嵌入式系统内存映射I / O. [英] Embedded system memory mapped I/o

查看:104
本文介绍了嵌入式系统内存映射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 name adc_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆