嵌入式系统内存映射I / O. [英] Embedded system memory mapped I/o
问题描述
步骤1:为所有寄存器定义单个结构adc_t
步骤2:在内存映射基址
步骤3:创建一个uint16_t pot_read(void),将adc样本除以4,将12位值放入0到1023的范围内
第4步:在主要电话上面打电话
我尝试过的事情:
这就是我所拥有的。
任何帮助将不胜感激
Step 1: define a single struct adc_t for all the registers
step 2: assign a pointer to the adc_t struct at the memory-mapped base address
step 3: create a uint16_t pot_read(void), dividing the adc sample by 4 to put 12-bit value into the range from 0 to 1023
step 4: call above function in main
What I have tried:
THIS IS WHAT I HAVE SO FAR.
any help would be appreciated
#include <stdint.h>
#include "led.h"
#include <assert.h>
/*!
* @brief Delay for some number of milliseconds, by wasting CPU cycles.
*
* @param[in] ms Number of milliseconds to busy-wait.
* @return void
*/
// a single struct for all the registers
typedef struct {
uint8_t AD_Control_Register ;
uint8_t unused1[3];
uint16_t AD_Channel_Select_Register_0;
uint16_t AD_Channel_Select_Register_1;
uint16_t AD_Converted_Value_Addition_Mode_Select_Register_0;
uint16_t AD_Converted_Value_Addition_Mode_Select_Register_1;
uint8_t AD_Converted_Value_Addition_Count_Select_Register;
uint16_t AD_Control_Extended_Register ;
uint8_t AD_Start_Trigger_Select_Register;
uint16_t AD_Converted_Extended_Input_Control_Register;
uint16_t AD_Temperature_Sensor_Data_Register;
uint16_t AD_Internal_Reference_Voltage_Data_Register;
uint16_t AD_Data_Register_y;
uint8_t unused2[11];
uint16_t AD_Sampling_State_Register_01 ;
uint8_t unused3[9];
uint16_t AD_Sampling_State_Register_23;
} adc_t;
// assign a pointer to the memory-mapped base address
adc_t* adc_regs = (adc_t *)adc_regs_base_address;
/* new function:
this function will divide the raw ADC sample by 4 to put the 12 bit value into the range
0 to 1023 ms
*/
uint16_t pot_read()
{
// adc_t *adc_regs = get mapped address here;
// create the 12-bit value if necessary (if the registers are 8-bit wide), and divide by four.
uint16_t adc_value = ((adc_regs -> value_lo) | ((adc_regs -> value_hi & 0x0f) << 8));
// unmap here if necessary
return adc_value / 4;
}
推荐答案
如果没有其他信息,这是无法解答的。
结构名称adc_t
表示它指的是某种ADC(模数转换器)寄存器。这些通常在嵌入式系统的数据表中指定。
分配指向此结构的指针需要知道地址。根据系统,仅使用强制转换分配地址可能就足够了:
This can't be answered without additional information.
The structure nameadc_t
indicates that it refers to some kind of ADC (Analogue to Digital Converter) registers. These are usually specified in the datasheet of the embedded system.
Assigning a pointer to this structure requires to know the address. Depending on the system it might be sufficient to just assign the address using casting:
adc_t* adc_regs = (adc_t *)adc_regs_base_address;
其中 adc_regs_base_address
是定义为常量的硬编码地址(例如,通过 define
语句或作为十六进制地址)。
如果不可能,可能有一个系统函数来映射地址(例如 mmap(2):将文件/设备映射/取消映射到内存 - Linux手册页 [ ^ ] with Linux)。
第三步需要知道ADC寄存器。对于典型系统,使用上面映射的存储器读取相应的寄存器,必要时创建12位值(如果寄存器为8位宽),并除以4。
一个典型的代码示例可能是:
where adc_regs_base_address
is the hard coded address defined as constant (e.g. by a define
statement or as hex address).
If this is not possible there might be a system function to map the address (e.g. mmap(2): map/unmap files/devices into memory - Linux man page[^] with Linux).
The third step requires knowing the ADC registers. With a typical system, use the above mapped memory to read the corresponding register(s), create the 12-bit value if necessary (if the registers are 8-bit wide), and divide by four.
A typical code example might be:
uint16_t pot_read()
{
//adc_t *adc_regs = get mapped address here;
uint16_t adc_value = adc_regs->value_lo |
((adc_regs->value_hi & 0x0f) << 8);
// unmap here if necessary
return adc_value / 4;
}
这篇关于嵌入式系统内存映射I / O.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!