C语言访问MCU寄存器的方式有哪些?.doc

C语言访问MCU寄存器的方式有哪些?.doc

ID:27486895

大小:221.00 KB

页数:4页

时间:2018-12-04

C语言访问MCU寄存器的方式有哪些?.doc_第1页
C语言访问MCU寄存器的方式有哪些?.doc_第2页
C语言访问MCU寄存器的方式有哪些?.doc_第3页
C语言访问MCU寄存器的方式有哪些?.doc_第4页
资源描述:

《C语言访问MCU寄存器的方式有哪些?.doc》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、C语言访问MCU寄存器的方式有哪些?  1.对C编译器进行语法扩充  对C编译器进行语法扩充。例如MCS51系列单片机的C-51语法中扩充了sfr关键字,举例如下:  sfrP0=0x80;  这样操作0x80单元直接写P0即可。    又如Atmel的AVR系列单片机,其ICCAVR和GCCAVR编译器都没有定义新的数据类型,只能采用标准C的强制类型转换和指针来实现访问MCU的寄存器。而IAR和CodeVisionAVR编译器对ANSIC进行了扩充,定义了新的数据类型,使C语言可以直接访问MCU的有关寄存器,例如在IAR中可以使用:  SFR_B(DDRB,

2、0x28);  CodeVisionAVR中可以使用:  sfrbDDRB=0x28;  2.使用标准C的强制类型转换和指针来实现  采用标准C的强制转换和指针的概念来实现访问MCU的寄存器,例如:  #defineDDRB(*(volatileunsignedchar*)0x25)  分析如下:  1.(unsignedchar*)0x25中的0x25只是个值,前面加(unsignedchar*)表示把这个值强制类型转换为unsignedchar型的指针。再在前面加”*”,即*(volatileunsignedchar*)0x25表示对这个指针解引用,相当于

3、(unsignedchar*)0x25是一个指针p,而这个宏定义为#defineDDRB*p。  这样当读/写以0x25为地址的寄存器时,直接书写DDRB即可,即写:DDRB=0xff;  相当于:  unsignedchar*p,i;p=0x25;i=*p;  //把地址为0x25单元中的数据读出送入i变量*p=0xff;//向地址为0x25的单元中写入0xff  这样经过一层宏定义的封装就变得直观和方便的多了。  2.关键字volatile确保本指令不会以为C编译器的优化而被省略,且要求每次直接读值。例如使用while(*(unsignedchar*)0x

4、25)时,有时系统可能不能真正去读0x25的值,而是用第一次读出的值,如果这样,这个循环可能就是个死循环。用了volatile则要求每次都去读0x25的实际值。  GCCAVR工具链中就使用了这样的方式,例如在iomx8.h文件中一个定义如下:#definePORTB_SFR_IO8(0x25)  而在sfr_defs.h中可以找到如下两个宏定义:  #define_SFR_IO8(io_addr)_MMIO_BYTE((io_addr)+0x20)#define_MMIO_BYTE(mem_addr)(*(volatileunit8_t*)(mem_addr

5、))  实质上与直接的强制类型转换和指针定义是一样的。  3.使用结构体实现  使用指针的方式来访问特殊功能寄存器的优势在于完全符合标准的ANSI-C,而无需扩展语法,形成“方言”,拥有更好的兼容性和可移植性。  这种方式适合简单的应用程序,而当系统用到多个同种外设时,就需要为每一个这种外设定义寄存器,这样就会使程序的维护变得非常困难。而且,由于每次寄存器操作都会有对应的常量存储在程序Flash里,为每个寄存器定义单独的指针还会增加程序代码。  为了简化程序代码,可以将寄存器组定义为结构体,而将外设当做指向这个结构体的指针。例如:  typedefstruct

6、{volatileunsignedlongDATA;//0x00volatileunsignedlongRSR;//0x04unsignedlongRESERVED0[4];//0x08-0x14volatileunsignedlongFLAG;//0x18...}UART_TypeDef;#defineUart0((UART_Type*)0x40003000)#defineUart1((UART_Type*)0x40004000)#defineUart2((UART_Type*)0x40005000)intgetkey(UART_TypeDef*uartpt

7、r){while((uartptr->FLAG&0x40)==0);//无数据,等待returnuartptr->DATA;  //读取字符}intmain(void){unsignedlongdata;data=getkey(Uart0);}  在这种设定下,同一个外设寄存器的结构体可以被多个外设实体共用,这样也使得程序维护变得容易。另外,由于立即数存储的减少,编译出的程序代码也会变小。

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。