嵌入式C:寄存器访问 [英] Embedded C: Registers Access

查看:377
本文介绍了嵌入式C:寄存器访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们要在地址写 0xc000 ,我们可以在C中定义一个宏:

  #define LCDCW1_ADDR 0xc000 
#define READ_LCDCW1()(*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val)((*(volatile uint32_t *)LCDCW1_ADDR我的问题是,当使用任何微控制器时,考虑一个例子MSP430(C) ,P1OUT寄存器地址为0x0021。



但是当我们使用P1OUT = 0xFFFF; //它分配P1OUT一个值0xFFFF。



我的问题是它如何写到该地址。在这种情况下为0x0021。
IDE是IAR。我在标题msp430g2553.h中找到了以下定义:

  #define P1OUT_(0x0021u)/ * Port 1 Output * / 
DEFC(P1OUT,P1OUT_)



我假设它正在定义地址,



任何人都可以解释P1OUT在特定地址位置写入的流程吗?也请让我知道在0x0021u是什么意思?



感谢





$ b b

到目前为止,我发现的细节是:

in msp430g2553.h

  #ifdef __IAR_SYSTEMS_ICC__ 
#includein430.h
#pragma language = extended

#define DEFC(name,address)__no_init volatile unsigned char name @ 地址;
#define DEFW(name,address)__no_init volatile unsigned short name @ address;
#define DEFXC volatile unsigned char
#define DEFXW volatile unsigned short

#endif / * __IAR_SYSTEMS_ICC__ * /


#ifdef __IAR_SYSTEMS_ASM__
#define DEFC(name,address)sfrb name = address;
#define DEFW(name,address)sfrw name = address;

#endif / * __IAR_SYSTEMS_ASM __ * /



#define P1OUT_(0x0021u)/ * Port 1 Output * /
DEFC P1OUT,P1OUT_)

io430g2553.h说

  __ no_init volatile union 
{
unsigned char P1OUT; / * Port 1 Output * /

struct
{
unsigned char P0:1; / * * /
unsigned char P1:1; / * * /
unsigned char P2:1; / * * /
unsigned char P3:1; / * * /
unsigned char P4:1; / * * /
unsigned char P5:1; / * * /
unsigned char P6:1; / * * /
unsigned char P7:1; / * * /
} P1OUT_bit;
} @ 0x0021;

有人可以解释一下上面的定义吗?我在MSP430中发现的详细信息IAR C / C ++编译器:

 使用__write和__read 
的示例以下示例使用内存映射I / O写入LCD
显示:
__no_init volatile unsigned char LCD_IO @ address;
size_t __write(int Handle,const unsigned char * Buf,
size_t Bufsize)
{
size_t nChars = 0;
/ *检查stdout和stderr
(仅当文件描述符被启用时才需要)* /
if(Handle!= 1&& Handle!= 2)
{
return -1;
}
for(/ * Empty * /; Bufsize> 0; --Bufsize)
{
LCD_IO = * Buf ++;
++ nChars;
}
return nChars;
}
以下示例中的代码使用内存映射I / O从键盘读取:
__no_init volatile unsigned char KB_IO @ 0xD2;
size_t __read(int Handle,unsigned char * Buf,size_t BufSize)
{
size_t nChars = 0;
/ *检查stdin
(只有在FILE描述符被启用时才需要)* /
if(Handle!= 0)
{
return -1;
}
for(/ * Empty * /; BufSize> 0; --BufSize)
{
unsigned char c = KB_IO;
if(c == 0)
break;
* Buf ++ = c;
++ nChars;
}
return nChars;
}

有没有人知道?

解决方案

这是编译器如何从我编写的代码生成,只有编译器的作者才能够为你回答。



很明显,在__no_init上面的代码中有几个非标准的C组件,使用@等等。在我阅读的时候,它告诉编译器this是一个HW端口,提供一个unsigned char,它的地址是0xd2。编译器将产生正确的指令类型来读写这样的端口 - 具体如何工作取决于编译器,编译器生成代码的处理器等。



P10out结构定义位字段,它是C标准的一部分。 Google是您的朋友。


Suppose we want to write at address say 0xc000, we can define a macro in C as:

#define LCDCW1_ADDR       0xc000
#define READ_LCDCW1()     (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))

My question is that when using any micro-controller, consider an example MSP430, P1OUT register address is 0x0021.

But when we use P1OUT=0xFFFF; // it assigns P1OUT a value 0xFFFF.

My question is how does it write to that address e.g. in this case 0x0021. The IDE is IAR. I found in header msp430g2553.h below definition:

#define P1OUT_              (0x0021u)  /* Port 1 Output */
DEFC(   P1OUT             , P1OUT_)

I suppose it is defining the address, but where are the other macros to write or read.

Could anyone please explain the flow that how P1OUT writes at that particular address location? Also do let me know what does u mean in 0x0021u ?

Thanks


So far the details I have found are :

in msp430g2553.h

#ifdef __IAR_SYSTEMS_ICC__
#include "in430.h"
#pragma language=extended

#define DEFC(name, address) __no_init volatile unsigned char name @ address;
#define DEFW(name, address) __no_init volatile unsigned short name @ address;
#define DEFXC  volatile unsigned char
#define DEFXW  volatile unsigned short

#endif  /* __IAR_SYSTEMS_ICC__  */


#ifdef __IAR_SYSTEMS_ASM__
#define DEFC(name, address) sfrb name = address;
#define DEFW(name, address) sfrw name = address;

#endif /* __IAR_SYSTEMS_ASM__*/



#define P1OUT_              (0x0021u)  /* Port 1 Output */
DEFC(   P1OUT             , P1OUT_)

The io430g2553.h says

__no_init volatile union
{
  unsigned char P1OUT;   /* Port 1 Output */

  struct
  {
    unsigned char P0              : 1; /*  */
    unsigned char P1              : 1; /*  */
    unsigned char P2              : 1; /*  */
    unsigned char P3              : 1; /*  */
    unsigned char P4              : 1; /*  */
    unsigned char P5              : 1; /*  */
    unsigned char P6              : 1; /*  */
    unsigned char P7              : 1; /*  */
  }P1OUT_bit;
} @0x0021;

Can some one explain what the above definition does? The details I found in MSP430 IAR C/C++ Compiler:

Example of using __write and __read
The code in the following examples use memory-mapped I/O to write to an LCD
display:
__no_init volatile unsigned char LCD_IO @ address;
size_t __write(int Handle, const unsigned char * Buf,
size_t Bufsize)
{
size_t nChars = 0;
/* Check for stdout and stderr
(only necessary if file descriptors are enabled.) */
if (Handle != 1 && Handle != 2)
{
return -1;
}
for (/*Empty */; Bufsize > 0; --Bufsize)
{
LCD_IO = * Buf++;
++nChars;
}
return nChars;
}
The code in the following example uses memory-mapped I/O to read from a keyboard:
__no_init volatile unsigned char KB_IO @ 0xD2;
size_t __read(int Handle, unsigned char *Buf, size_t BufSize)
{
size_t nChars = 0;
/* Check for stdin
(only necessary if FILE descriptors are enabled) */
if (Handle != 0)
{
return -1;
}
for (/*Empty*/; BufSize > 0; --BufSize)
{
unsigned char c = KB_IO;
if (c == 0)
break;
*Buf++ = c;
++nChars;
}
return nChars;
}

Does any one know?

解决方案

This is "how does the compiler generate the code from what I've written", and only the compiler writers will actually be able to answer that for you.

Clearly, there are several non standard C components in the code above __no_init, the use of @, etc. In my reading of this, it tells the compiler that "this is a HW port, that provides an unsigned char, and it's address is 0xd2". The compiler will produce the right kind of instructions to read and write such a port - exactly how that works depends on the compiler, the processor that the compiler is producing code for, etc.

The P10out structure defines bitfields, which is part of the C standard. Google is your friend here.

这篇关于嵌入式C:寄存器访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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