结构体定义寄存器方法(很流行哦)



ARM寄存器数量之多,叹为观止!幸运的是,它都是以模块分布,再依托C语言的模块化编程,用户就没有必要记忆那么多的寄存器名称了!

拿LPC1114来说,单片机内部模块有“模数转换器ADC模块”,“看门狗WDG模块”,“中断模块NVIC”,“串口UART模块”等等。

每个模块都有一些寄存器。

在51单片机中,用串口发送数据,会这样写:SBUF=0x88,如何正确的把0x88写到名称为SBUF的寄存器中,在51的寄存器地址定义文件里面,SCON的地址这样定义:sfr SCON = 0x98。

同样,LPC1114里面也需要定义地址,由于LPC1114用纯C语言编写程序,所以不能用“伪C语言”sfr来定义地址了。
涉及到地址,肯定会用到指针,因为指针可以指向地址。
拿看门狗模块来举例,结构体定义如下:
  1. typedef struct
  2. {
  3.     RW_en MOD;              /*看门狗模式寄存器,  地址偏移: 0x000 (R/W) */
  4.     RW_en TC;               /*看门狗常量寄存器,  地址偏移: 0x004 (R/W) */
  5.     W_en  FEED;             /*看门狗喂狗寄存器,  地址偏移: 0x008 (W)   */
  6.     R_en  TV;               /*看门狗当前值寄存器,地址偏移: 0x00C (R/ ) */
  7. }WDT_TypeDef
复制代码
结构体定义了看门狗里面一共有四个寄存器
基址定义如下:
  1. #define WDT_BASE          (APB0_BASE + 0x04000)
  1. #define APB0_BASE         (0x40000000UL)
  1. #define WDT         ((WDT_TypeDef    *) WDT_BASE   )
在官网用户手册中指出:看门狗模块的四个寄存器地址分别为0x40004000,0x40004004,0x40004008,0x4000400C,如何正确的把寄存器地址放到这个地方,上面的语句就是实现方法。

看懂上面的语句,并不是十分困难,因为都是些C语言的基础知识。(所以说,不管任何行业,高手并不是掌握了高深的技能,而是掌握了扎实的基础!)

#define 在C语言中表示 :用define后面的词代替这个词后面的语句。

写程序赋值的时候,我们会这样写:
  1. WDT->TC = 80000;
那么WDT就是:(WDT_TypeDef *) (0x40000000UL + 0x04000) 即把上面的结构体地址定义为0x40004000,那么里面的4个寄存器地址就分别是:
MOD = 0X40004000
TC= 0x40004004
FEED=0X40004008
TV=0X4000400C
地址为什么会递增4?
请看前面的RW_en,R_en,W_en,分别是:
  1. #define R_en   volatile uint32
  2. #define W_en   volatile uint32
  3. #define RW_en volatile uint32
uint32即四个字节,所以地址会增加4。

“->”运算符用于指向结构体变量指针,当然也可以用“.”,如果用“.”,对于结构体指针,要这样用:
  1. (*WDT).TC = 80000;
用"->"和"."都可以,书写正确就可以,都可以正常使用!

为了书写方便,我们一般用“->”,而不用“.”

你可能感兴趣的:(c,C++,c,模块化)