微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > LPC11XX.h头文件解析

LPC11XX.h头文件解析

时间:11-13 来源:互联网 点击:
从前面的第一个演示示例中可以看出,只实现一个LED的闪烁,其代码量似乎要比51单片的多很多。仔细观察后会发现,其实除了多了时钟配置以外,就数预定义部分的代码数量最多,而且这部分大多是以结构体的形式出现的。在正规的开发过程中,这部分预定义的内容被是放在一些头文件内并包含进来的,前面的代码只是为了编译方便,所以把全部代码都给出来,不太正规。下面就来讨论一下在ARM-MDK环境中开发LPC1114的头文件配置。

在前面的示例中,给出了预定义部分的内容,但没有进行解释。这里就先来讨论一下在第一个演示示例中预定义部分的内容。

先看第一个部分,代码如下:

#define__IOvolatile

#define__Ovolatile

#define__Ivolatile const

typedef unsignedchar uint8_t;

typedef unsigned shortint uint16_t;

typedef unsignedint uint32_t;

#pragma anon_unions

第一、二、三行是三个宏定义,通过define语句把__IO等效为volatile,把__O等效为volatile,把__I等效为volatile const。一般来说宏定义都是大写,但因为这里用的字母比较少(只有I或O或IO),所以再在其前面添加下划线来进行区分,这样做可以有效避免命名冲突问题。而volatile本身则是一个关键字,表示其后面定义的变量不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄存器中读取或者修改。比如在单片机开发中,经常会用到软件延时,但若要软件延时不被编译器优化掉,就必须在变量定义前加上关键字volatile,如“for(volatile unsigned int k=0;k<60000;k++);”。而volatile const则表示其后面定义的变量是只读的,比如用它来定义一个只读的状态寄存器,定义为volatile是因为它的值可能会被硬件意想不到地改变,而定义为const是因为程序不应该试图去修改它的值。通俗的说,就是它定义的是一个“只读变量”而不是常量,它的值是由硬件来改变的,不能通过程序写入来改变。总结一下:

__I:定义输入口。既然是输入,那么寄存器的值就随时会被外部修改,所以不能对它进行优化,每次都必须从寄存器中读取。也不能写(即只读),否则就不是输入而是输出了。
__O:定义输出口,也不能对它进行优化,不然端口连续两次输出相同的值,编译器就会认为没有变化,而忽略后那一次输出,假如外部在两次输出中间修改了值,那就会影响输出的正确性。可写,否则就不能称为输出了。
__IO:定义输入输出口,也不能对它进行优化,原因同上。可读可写。

第三至五行是类型的声明,把无符号的字符型、短整型、整型分别用uint8_t、uint16_t、uint32_t来表示,以突出它们所占用的字节数,方便查看。

在最后一行中,pragma是一个关键字,它的使用较为复杂,有兴趣的读者可自行上网查阅。这里只需要记住,在使用到带union的结构体定义时,在预定义部分一定要有“#pragma anon_unions”这样一句,否则编译通不过。在第一个演示示例中,由于在后面定义了一个带union的结构体,所以在这里必须要写这一句。

接下来看第二个部分,这部分全部使用结构体来对寄存器进行描述。先来看对SYSCON结构体的定义:

typedef struct
{
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 (R/W) System memory remap Register */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 (R/W) Peripheral reset control Register */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 (R/W) System PLL control Register */
__I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C (R/ ) System PLL status Register */
uint32_t RESERVED0[4];

__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 (R/W) System oscillator control Register */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 (R/W) Watchdog oscillator control Register */
__IO uint32_t IRCCTRL; /*!< Offset: 0x028 (R/W) IRC control Register */
uint32_t RESERVED1[1];
__I uint32_t SYSRSTSTAT; /*!< Offset: 0x030 (R/ ) System reset status Register */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 (R/W) System PLL clock source select Register */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 (R/W) System PLL clock source update enable Register */
uint32_t RESERVED3[10];

__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 (R/W) Main clock source select Register */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 (R/W) Main clock source update enable Register */
__IO uint32_t SYSAHBCLKdiv; /*!< Offset: 0x078 (R/W) System AHB clock divider Register */
uint32_t RESERVED4[1];

__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 (R/W) System AHB clock control Register */
uint32_t RESERVED5[4];
__IO uint32_t SSP0CLKdiv; /*!< Offset: 0x094 (R/W) SSP0 clock divider Register */
__IO uint32_t UARTCLKdiv; /*!< Offset: 0x098 (R/W) UART clock divider Register */
__IO uint32_t SSP1CLKdiv; /*!< Offset: 0x09C (R/W) SSP1 clock divider Register */
uint32_t RESERVED6[1];
uint32_t RESERVED7[11];

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top