第一个演示示例
由于LPC824较为复杂,为了能够快速地进入学习过程,减少学习的挫折感,现在先通过一个较容易实现的小例子,让大家体会MDK-ARM环境下LPC824开发的整个过程,并以此例子为基础,对程序开发中遇到的问题进行深入讨论。
示例的电路如下图所示,有8个LED通过限流电阻分别接到LPC824的8个PIO0端口,采取共阳接法,为了让实例具有普遍意义,这里的PIO0并没有选取全部相邻的端口。接下来编写程序,让这8个LED交替闪烁,闪烁的时间间隔为1秒。

由于LED采取共阳极接法,当对应的PIO0端口引脚输出低电平(值为0)时,对应的LED被点亮,输出高电平(值为1)时熄灭。因此,根据上面的电路图,LED1~LED8分别接在了PIO0端口的第7、13、16、17、19、27、28及18号引脚上(注:并非芯片引脚号),而全部端口号都对应到一个32位的二进制数(实际只用了29位),给这个32位的二进制数赋值就可以控制8个LED的亮灭了。所以,要让这些LED交替闪烁,只需要给这个32位的二进制数轮流赋值为XXX10XXXXXXX1001XX0XXXXX1XXXXXXX和XXX01XXXXXXX0110XX1XXXXX0XXXXXXX即可。注意,二进制数的最左边对应端口号的高位(即PIO0_31),最右边对应低位(即PIO0_0),其余位置依次对应到相应的二进制位。前面二进制数中的X表示无关的位,也就是没有接LED的端口引脚,在实际程序中可取这些端口号的默认值(本来是不应该改动这些X位的值的,这将在以后再作讨论)。在LPC824中,这个二进制数将按需要赋值给端口寄存器PIN0,只要在程序中写这个寄存器即可实际上述功能。
本程序仍然使用不包含头文件的形式书写,完整代码如下:
#define __I volatile const #define __O volatile #define __IO volatile typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef struct { __IO uint32_t SYSMEMREMAP; __IO uint32_t PRESETCTRL; __IO uint32_t SYSPLLCTRL; __I uint32_t SYSPLLSTAT; __I uint32_t RESERVED0[4]; __IO uint32_t SYSOSCCTRL; __IO uint32_t WDTOSCCTRL; __IO uint32_t IRCCTRL; __I uint32_t RESERVED1; __IO uint32_t SYSRSTSTAT; __I uint32_t RESERVED2[3]; __IO uint32_t SYSPLLCLKSEL; __IO uint32_t SYSPLLCLKUEN; __I uint32_t RESERVED3[10]; __IO uint32_t MAINCLKSEL; __IO uint32_t MAINCLKUEN; __IO uint32_t SYSAHBCLKDIV; __I uint32_t RESERVED4; __IO uint32_t SYSAHBCLKCTRL; __I uint32_t RESERVED5[4]; __IO uint32_t UARTCLKDIV; __I uint32_t RESERVED6[18]; __IO uint32_t CLKOUTSEL; __IO uint32_t CLKOUTUEN; __IO uint32_t CLKOUTDIV; __I uint32_t RESERVED7; __IO uint32_t UARTFRGDIV; __IO uint32_t UARTFRGMULT; __I uint32_t RESERVED8; __IO uint32_t EXTTRACECMD; __I uint32_t PIOPORCAP0; __I uint32_t RESERVED9[12]; __IO uint32_t IOCONCLKDIV6; __I uint32_t RESERVED10[6]; __IO uint32_t BODCTRL; __IO uint32_t SYSTCKCAL; __I uint32_t RESERVED11[6]; __IO uint32_t IRQLATENCY; __IO uint32_t NMISRC; __IO uint32_t PINTSEL0; __IO uint32_t PINTSEL1; __IO uint32_t PINTSEL2; __IO uint32_t PINTSEL3; __IO uint32_t PINTSEL4; __IO uint32_t PINTSEL5; __IO uint32_t PINTSEL6; __IO uint32_t PINTSEL7; __I uint32_t RESERVED12[27]; __IO uint32_t STARTERP0; __I uint32_t RESERVED13[3]; __IO uint32_t STARTERP1; __I uint32_t RESERVED14[6]; __IO uint32_t PDSLEEPCFG; __IO uint32_t PDAWAKECFG; __IO uint32_t PDRUNCFG; __I uint32_t RESERVED15[111]; __I uint32_t DEVICE_ID; } LPC_SYSCON_Type; typedef struct { __IO uint32_t PIO0_17; __IO uint32_t PIO0_13; __IO uint32_t PIO0_12; __IO uint32_t PIO0_5; __IO uint32_t PIO0_4; __IO uint32_t PIO0_3; __IO uint32_t PIO0_2; __IO uint32_t PIO0_11; __IO uint32_t PIO0_10; __IO uint32_t PIO0_16; __IO uint32_t PIO0_15; __IO uint32_t PIO0_1; __I uint32_t RESERVED0; __IO uint32_t PIO0_9; __IO uint32_t PIO0_8; __IO uint32_t PIO0_7; __IO uint32_t PIO0_6; __IO uint32_t PIO0_0; __IO uint32_t PIO0_14; __I uint32_t RESERVED1; __IO uint32_t PIO0_28; __IO uint32_t PIO0_27; __IO uint32_t PIO0_26; __IO uint32_t PIO0_25; __IO uint32_t PIO0_24; __IO uint32_t PIO0_23; __IO uint32_t PIO0_22; __IO uint32_t PIO0_21; __IO uint32_t PIO0_20; __IO uint32_t PIO0_19; __IO uint32_t PIO0_18; } LPC_IOCON_Type; typedef struct { __IO uint32_t PINASSIGN0; __IO uint32_t PINASSIGN1; __IO uint32_t PINASSIGN2; __IO uint32_t PINASSIGN3; __IO uint32_t PINASSIGN4; __IO uint32_t PINASSIGN5; __IO uint32_t PINASSIGN6; __IO uint32_t PINASSIGN7; __IO uint32_t PINASSIGN8; __IO uint32_t PINASSIGN9; __IO uint32_t PINASSIGN10; __IO uint32_t PINASSIGN11; __I uint32_t RESERVED0[100]; __IO uint32_t PINENABLE0; } LPC_SWM_Type; typedef struct { __IO uint8_t B0; __IO uint8_t B1; __IO uint8_t B2; __IO uint8_t B3; __IO uint8_t B4; __IO uint8_t B5; __IO uint8_t B6; __IO uint8_t B7; __IO uint8_t B8; __IO uint8_t B9; __IO uint8_t B10; __IO uint8_t B11; __IO uint8_t B12; __IO uint8_t B13; __IO uint8_t B14; __IO uint8_t B15; __IO uint8_t B16; __IO uint8_t B17; __IO uint8_t B18; __IO uint8_t B19; __IO uint8_t B20; __IO uint8_t B21; __IO uint8_t B22; __IO uint8_t B23; __IO uint8_t B24; __IO uint8_t B25; __IO uint8_t B26; __IO uint8_t B27; __IO uint8_t B28; __I uint8_t RESERVED0[4067]; __IO uint32_t W0; __IO uint32_t W1; __IO uint32_t W2; __IO uint32_t W3; __IO uint32_t W4; __IO uint32_t W5; __IO uint32_t W6; __IO uint32_t W7; __IO uint32_t W8; __IO uint32_t W9; __IO uint32_t W10; __IO uint32_t W11; __IO uint32_t W12; __IO uint32_t W13; __IO uint32_t W14; __IO uint32_t W15; __IO uint32_t W16; __IO uint32_t W17; __IO uint32_t W18; __IO uint32_t W19; __IO uint32_t W20; __IO uint32_t W21; __IO uint32_t W22; __IO uint32_t W23; __IO uint32_t W24; __IO uint32_t W25; __IO uint32_t W26; __IO uint32_t W27; __IO uint32_t W28; __I uint32_t RESERVED1[995]; __IO uint32_t DIR0; __I uint32_t RESERVED2[31]; __IO uint32_t MASK0; __I uint32_t RESERVED3[31]; __IO uint32_t PIN0; __I uint32_t RESERVED4[31]; __IO uint32_t MPIN0; __I uint32_t RESERVED5[31]; __IO uint32_t SET0; __I uint32_t RESERVED6[31]; __O uint32_t CLR0; __I uint32_t RESERVED7[31]; __O uint32_t NOT0; __I uint32_t RESERVED8[31]; __O uint32_t DIRSET0; __I uint32_t RESERVED9[31]; __O uint32_t DIRCLR0; __I uint32_t RESERVED10[31]; __O uint32_t DIRNOT0; } LPC_GPIO_PORT_Type; typedef struct { __IO uint32_t CTRL; __IO uint32_t LOAD; __IO uint32_t VAL; __I uint32_t CALIB; } SysTick_Type; #define SCS_BASE (0xE000E000UL) #define LPC_SYSCON_BASE 0x40048000UL #define LPC_IOCON_BASE 0x40044000UL #define LPC_SWM_BASE 0x4000C000UL #define LPC_GPIO_PORT_BASE 0xA0000000UL #define SysTick_BASE (SCS_BASE + 0x0010UL) #define LPC_SYSCON ((LPC_SYSCON_Type *) LPC_SYSCON_BASE) #define LPC_IOCON ((LPC_IOCON_Type *) LPC_IOCON_BASE) #define LPC_SWM ((LPC_SWM_Type *) LPC_SWM_BASE) #define LPC_GPIO_PORT ((LPC_GPIO_PORT_Type *) LPC_GPIO_PORT_BASE) #define SysTick ((SysTick_Type *) SysTick_BASE ) //************************使用外部晶振********************************** void Ext_osc(void) { LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 18); //使能IOCON时钟 LPC_IOCON->PIO0_8 &= ~(3 << 3); //把P0_8引脚配置为无上下拉电阻方式 LPC_IOCON->PIO0_9 &= ~(3 << 3); //把P0_9引脚配置为无上下拉电阻方式 LPC_SWM->PINENABLE0 &= ~(3 << 6); //把P0_8、P0_9引脚配置为XTALIN、XTALOUT引脚 LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 18); //禁止IOCON时钟 } //************************时钟初始化*********************************** void SysCLK_config(void) { uint8_t i; LPC_SYSCON->PDRUNCFG &= ~(1 << 5); //给系统振荡器上电 LPC_SYSCON->SYSOSCCTRL = 0x00000000; //系统振荡器未旁路,1~12MHz输入 for (i = 0; i < 200; i++) __asm__("nop"); //延时等待振荡器稳定 LPC_SYSCON->SYSPLLCLKSEL = 0x00000001; //PLL输入选择外部晶体振荡 LPC_SYSCON->SYSPLLCLKUEN = 0x00; LPC_SYSCON->SYSPLLCLKUEN = 0x01; //先写0后写1更新时钟源 while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); //等待更新完成 LPC_SYSCON->SYSPLLCTRL = 0x00000041; //M=2、P=4,倍频后的时钟为24MHz LPC_SYSCON->PDRUNCFG &= ~(1 << 7); //给PLL上电 while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); //等待PLL锁定 LPC_SYSCON->MAINCLKSEL = 0x00000003; //主时钟选择PLL倍频后的时钟 LPC_SYSCON->MAINCLKUEN = 0x00; LPC_SYSCON->MAINCLKUEN = 0x01; //先写0后写1更新时钟源 while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); //等待更新完成 LPC_SYSCON->SYSAHBCLKDIV = 0x00000001; //AHB为1分频,AHB时钟为24MHz } //************************系统初始化*********************************** void SystemInit(void) { Ext_osc(); //调用使用外部晶振 SysCLK_config(); //调用时钟配置函数 } //************************端口初始化*********************************** void Port_init(void) { LPC_GPIO_PORT->DIR0 = 0x1FFFFFFF; //设置端口为输出方向 LPC_GPIO_PORT->PIN0 = 0x10090080; //输出相应电平交替点亮LED } //************************定时器初始化********************************* void SysTick_init(void) { SysTick->LOAD = (((12000)*1000)-1); SysTick->VAL = 0; SysTick->CTRL |= ((1<<1)|(1<<0)); } //***************************主函数************************************ int main(void) { Port_init(); //调用端口初始化 SysTick_init(); //调用定时器初始化 while(1) { ; } } //************************定时器中断*********************************** void SysTick_Handler(void) { LPC_GPIO_PORT->PIN0 = ~LPC_GPIO_PORT->PIN0; //取反赋值 }
把以上程序代码在MDK开发环境中进行编译(可能会出现很多未定义头文件的警告,不用管它),然后下载到LPC824中,按前面的电路接好8个LED,给系统上电,应该就可以看到LED在交替闪烁了。
上述程序中用到的端口及定时器的相关函数功能在后面再进行详细讨论。

浙公网安备 33010602011771号