本帖最后由 leaderpig 于 2017-1-17 00:20 编辑
本文为【用LPC824玩转51开发板】系列的入门实验——点亮LED,涉及的相关资源包括GPIO。由于本篇为第一个实验,因此有必要对启动过程做一次详细分析:
首先,从 keil_startup_LPC8xx.s 看到,执行main函数前,调用了 SystemInit()- ; Reset Handler
- Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, = SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
复制代码
1) 使能IOCON时钟 IOCON: I/O configuration,顾名思义,用来配置每个管脚的电气属性,包括推挽、开漏、迟滞、数字输入、模拟输入。另外,为节省功耗,一旦配置完管脚的电气属性,可将IOCON的时钟关闭。 因此,在配置I/O的电气属性前,需要先使能IOCON时钟(管脚的初始化在Main函数中进行,后述)。 sysinit_8xx.c - /* Set up and initialize hardware prior to call to main */
- /* 在main()函数之前调用此函数做基本的初始化工作 */
- void SystemInit(void)
- {
- Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON); //使能IOCON时钟
-
- /* Use 12MHz IRC as clock source */
- Chip_SetupIrcClocking(); //初始化系统时钟
- }
复制代码clock_8xx.h - STATIC INLINE void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
- {
- LPC_SYSCTL->SYSAHBCLKCTRL = (1 << clk) | (LPC_SYSCTL->SYSAHBCLKCTRL & ~SYSCTL_SYSAHBCLKCTRL_RESERVED);
- }
复制代码
2) 初始化系统时钟(main clk, system clk, AHB clk) 上面我们使能了APB时钟(IOCON),APB时钟源于AHB to APB Bridge,AHB即为system clk,那么system clk又是多少呢?接下来,就需要配置system clk。LPC824 Breakout采用的时钟源为IRC,依次经过中间环节的system pll、选择器、分频器,产生main clk = 60MHz,system clk = 30MHz,红色轨迹即为时钟路径。 sysinit_8xx.c - /* Set up and initialize hardware prior to call to main */
- void Chip_SetupIrcClocking(void)
- {
- Chip_IRC_SetFreq(CONFIG_MAIN_FREQ, CONFIG_SYS_FREQ);
- }
复制代码
3) 初始化GPIO时钟 board.c - /* Set up and initialize all required blocks and functions related to the
- board hardware */
- void Board_Init(void)
- {
- ...
- /* Initialize GPIO */
- Chip_GPIO_Init(LPC_GPIO_PORT);
- ...
- }
复制代码gpio_8xx.h - STATIC INLINE void Chip_GPIO_Init(LPC_GPIO_T *pGPIO) //注:参数在该函数无意义
- {
- LPC_SYSCTL->SYSAHBCLKCTRL = (1 << SYSCTL_CLOCK_GPIO) | (LPC_SYSCTL->SYSAHBCLKCTRL & ~SYSCTL_SYSAHBCLKCTRL_RESERVED);
- }
复制代码4) 设置管脚的电气属性 在第一节我们使能了IOCON时钟后,就可以对管脚的电气属性进行设置了。
以板载LED为例,硬件上低电平驱动LED灯亮。因此,对应管脚应初始化为上拉。查阅手册可知,P0.15(P0.16、P0.17)默认值为0x90,即为使能上拉电阻,因此该步骤可省略。
5) 设置管脚类型、初始状态 类型就是输入、输出。状态就是或高或低。 board.c - /* Initialize the LEDs on the NXP LPC824 LPCXpresso Board */
- static void Board_LED_Init(void)
- {
- int i;
- for (i = 0; i < BOARD_LED_CNT; i++) {
- Chip_GPIO_PinSetDIR(LPC_GPIO_PORT, 0, ledBits[i], 1);
- Chip_GPIO_PinSetState(LPC_GPIO_PORT, 0, ledBits[i], true);
- }
- }
复制代码6) 经典实验——点亮LED
main.c - #define LED1_PIN 15 //red led
- #define LED2_PIN 16 //green led
- #define LED3_PIN 17 //blue led
- static void delay(void)
- {
- uint32_t i, j;
- for(i=0; i<1000; i++)
- for(j=0; j<1000; j++);
- }
- int main(void)
- {
- uint32_t GPIOCONFIG = ( (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED3_PIN) );
- Board_Init();
- /* All work happens in while() loop */
- while (1)
- {
- Chip_GPIO_PortToggleState(LPC_GPIO_PORT, 0, GPIOCONFIG);
- delay();
- }
- }
复制代码
现象如下:
|