TA的每日心情 | 奋斗 2013-2-28 11:51 |
---|
签到天数: 49 天 连续签到: 1 天 [LV.5]常住居民I
|
上海最近一直在下雨,天气也越来越冷,晚上睡觉会被冻醒;
事情也是非常多,做完了一些,又会来一堆,不知不觉有很长时间没有前来更新。
为了延续本教程的生命力,我觉得再忙也要抽时间来写心得,和大家分享。
今天我们的主题是定时器,查询LM4F120H5QR的手册可以得知该芯片一共有12个定时器,
其中6个是32/64bit的,另外六个是16/32bit的,可谓非常强大。
我们参考官方的例程来看看定时器究竟该如何使用,首先我们创建主函数:- //*****************************************************************************
- //
- // This example application demonstrates the use of the timers to generate
- // periodic interrupts.
- //
- //*****************************************************************************
- int
- main(void)
- {
- //
- // Enable lazy stacking for interrupt handlers. This allows floating-point
- // instructions to be used within interrupt handlers, but at the expense of
- // extra stack usage.
- //
- ROM_FPULazyStackingEnable();
- //
- // Set the clocking to run directly from the crystal.
- //
- ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
- SYSCTL_XTAL_16MHZ);
- //
- // Initialize the UART and write status.
- //
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
- GPIOPinConfigure(GPIO_PA0_U0RX);
- GPIOPinConfigure(GPIO_PA1_U0TX);
- ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
- UARTStdioInit(0);
- UARTprintf("\033[2JTimers example\n");
- UARTprintf("T1: 0 T2: 0");
- //
- // Enable the GPIO port that is used for the on-board LED.
- //
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
- //
- // Enable the GPIO pins for the LED (PF1 & PF2).
- //
- ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_1);
- //
- // Enable the peripherals used by this example.
- //
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
- //
- // Enable processor interrupts.
- //
- ROM_IntMasterEnable();
- //
- // Configure the two 32-bit periodic timers.
- //
- ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
- ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
- ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet());
- ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet() / 2);
- //
- // Setup the interrupts for the timer timeouts.
- //
- ROM_IntEnable(INT_TIMER0A);
- ROM_IntEnable(INT_TIMER1A);
- ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
- ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
- //
- // Enable the timers.
- //
- ROM_TimerEnable(TIMER0_BASE, TIMER_A);
- ROM_TimerEnable(TIMER1_BASE, TIMER_A);
- //
- // Loop forever while the timers run.
- //
- while(1)
- {
- }
- }
复制代码 我们来分析一下上述代码,其中与串口有关的我们直接忽略,有兴趣的可以参考
另外一篇与串口有关的文章。
- //
- // Enable the peripherals used by this example.
- //
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
- ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
复制代码 首先对定时器0和定时器1进行初始化,然后对定时器进行配置:- //
- // Configure the two 32-bit periodic timers.
- //
- ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
- ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
- ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet());
- ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet() / 2);
复制代码 由上述代码可知,配置成周期性模式,定时器0的频率采用系统频率,换句话说就是1s触发一次中断,
定时器1采用系统频率的一半,即半秒触发一次定时器中断。
而后配置定时器中断,并初始化时钟,这里采用TIMER_TIMA_TIMEOUT将时钟配置成溢出产生中断,程序如下:- //
- // Setup the interrupts for the timer timeouts.
- //
- ROM_IntEnable(INT_TIMER0A);
- ROM_IntEnable(INT_TIMER1A);
- ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
- ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
复制代码 与中断有关,必定需要联系到中断处理函数,我们先来看下定时器0中断的函数:- //*****************************************************************************
- //
- // The interrupt handler for the first timer interrupt.
- //
- //*****************************************************************************
- void
- Timer0IntHandler(void)
- {
- //
- // Clear the timer interrupt.
- //
- ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
- //
- // Toggle the flag for the first timer.
- //
- HWREGBITW(&g_ulFlags, 0) ^= 1;
- //
- // Use the flags to Toggle the LED for this timer
- //
- GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, g_ulFlags << 1);
-
- //
- // Update the interrupt status on the display.
- //
- ROM_IntMasterDisable();
- UARTprintf("\rT1: %d T2: %d", HWREGBITW(&g_ulFlags, 0) ? 1 : 0,
- HWREGBITW(&g_ulFlags, 1) ? 1 : 0);
- ROM_IntMasterEnable();
- }
复制代码 这里主要是每次定时器中断时,对LED灯状态进行异或,同时向串口输入,定时器1中断处理程序类似:- //*****************************************************************************
- //
- // The interrupt handler for the second timer interrupt.
- //
- //*****************************************************************************
- void
- Timer1IntHandler(void)
- {
- //
- // Clear the timer interrupt.
- //
- ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
- //
- // Toggle the flag for the second timer.
- //
- HWREGBITW(&g_ulFlags, 1) ^= 1;
-
- //
- // Use the flags to Toggle the LED for this timer
- //
- GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, g_ulFlags << 1);
-
- //
- // Update the interrupt status on the display.
- //
- ROM_IntMasterDisable();
- UARTprintf("\rT1: %d T2: %d", HWREGBITW(&g_ulFlags, 0) ? 1 : 0,
- HWREGBITW(&g_ulFlags, 1) ? 1 : 0);
- ROM_IntMasterEnable();
- }
复制代码 定时器使用初步就介绍到这里,有兴趣的话可以自己建立工程,做一下试验,别忘了修改startup文件,
连接上串口的话会看到以下结果,结果可自行结合代码进行分析。
|
|