#include
#define PART_LM3S1138 #include
// 在PF6/CCP1管脚产生32786.885Hz方波,为Timer2的RTC功能提供时钟源 void pulseInit(void) {
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); // 使能TIMER0模块
SysCtlPeriEnable(CCP1_PERIPH); // 使能CCP1所在的GPIO端口 GPIOPinTypeTimer(CCP1_PORT, CCP1_PIN); // 配置相关管脚为Timer功能
TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | // 配置TimerB为16位PWM
TimerLoadSet(TIMER0_BASE, TIMER_B, 183); // 设置TimerB初值 TimerMatchSet(TIMER0_BASE, TIMER_B, 92); // 设置TimerB匹配值 TimerEnable(TIMER0_BASE, TIMER_B); }
// 定时器RTC功能初始化
void timerInitRTC(unsigned long ulVal) {
SysCtlPeriEnable(CCP4_PERIPH); // 使能CCP4所在的GPIO端口 GPIOPinTypeTimer(CCP4_PORT, CCP4_PIN); // 配置CCP4管脚为RTC时钟输入
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER2); // 使能Timer模块
TimerConfigure(TIMER2_BASE, TIMER_CFG_32_RTC); // 配置Timer为32位RTC模式 TimerLoadSet(TIMER2_BASE, TIMER_A, ulVal); // 设置RTC计数器初值 TimerMatchSet(TIMER2_BASE, TIMER_A, 1 + ulVal); // 设置RTC匹配值
TimerIntEnable(TIMER2_BASE, TIMER_RTC_MATCH); // 使能RTC匹配中断
TimerRTCEnable(TIMER2_BASE); // 使能RTC计数 TimerEnable(TIMER2_BASE, TIMER_A); // 使能Timer计数 }
// 计算并显示RTC时钟
void timerDispRTC(unsigned long ulVal) {
char s[40];
IntEnable(INT_TIMER2A); IntMasterEnable( );
// 使能Timer中断 // 使能处理器中断
TIMER_CFG_B_PWM);
15
// 计算并显示小时
// 计算并显示分钟
// 显示秒钟,并回车换行 }
// 主函数(程序入口) int main(void) {
ulVal = TimerValueGet(TIMER2_BASE, TIMER_A); // 读取当前RTC计时器值
for (;;) { } }
timerDispRTC(ulVal);
// 显示初始时间
uartPuts(\(hh:mm:ss)\\r\\n\ // 提示输入时、分、秒 sscanf(s, \&ulM, &ulS); // 扫描输入时、分、秒 ulVal = 3600 * ulH + 60 * ulM + ulS; timerInitRTC(ulVal); pulseInit( );
// 时分秒转换为1个整数 // RTC初始化
// 开始提供RTC时钟源
uartGets(s, sizeof(s)); // 从UART读取RTC初始时间
jtagWait( ); clockInit( ); uartInit( );
// 防止JTAG失效,重要! // 时钟初始化:晶振,6MHz // UART初始化
unsigned long ulH, ulM, ulS; unsigned long ulVal; if (ulVal < 10) uartPutc('0'); sprintf(s, \if (ulVal / 60 < 10) uartPutc('0'); sprintf(s, %ulVal %= 60;
if (ulVal / 3600 < 10) uartPutc('0'); sprintf(s, %ulVal %= 3600;
uartPuts(s);
uartPuts(s);
uartPuts(s);
char s[40];
ulVal =% 24 * 60 * 60; // 去掉“天”
16
// Timer2的中断服务函数 void Timer2A_ISR(void) {
if (ulStatus & TIMER_RTC_MATCH) {
ulVal = TimerValueGet(TIMER2_BASE, TIMER_A); // 读取当前RTC计时器值
if (ulVal => 24 * 60 * 60) // 若超过一天,则从0开始
{
ulVal = 0;
TimerLoadSet(TIMER2_BASE, TIMER_A, 0); // 重新设置RTC计数器初值
TimerMatchSet(TIMER2_BASE, TIMER_A, 1 + ulVal); // 重新设置RTC匹配值 }
timerDispRTC(ulVal);
// 显示当前时间
}
}
ulStatus = TimerIntStatus(TIMER2_BASE, true); TimerIntClear(TIMER2_BASE, ulStatus);
unsigned long ulStatus; unsigned long ulVal;
4. 16位单次触发定时
程序清单1.4是Timer模块16位单次触发定时器模式的例子。该例程实现的功能与32位单次触发定时的例程(参见程序清单1.1)基本相同,只是多了一个8位预分频器的运用。
程序清单1.4 Timer例程:16位单次触发定时
#include \#include
// 定义LED
#define LED_PERIPH SYSCTL_PERIPH_GPIOG #define LED_PORT GPIO_PORTG_BASE #define LED_PIN GPIO_PIN_2
// 定义KEY
#define KEY_PERIPH
SYSCTL_PERIPH_GPIOD
#define KEY_PORT GPIO_PORTD_BASE #define KEY_PIN GPIO_PIN_1
17
// 主函数(程序入口) int main(void) {
SysCtlPeriEnable(LED_PERIPH); // 使能LED所在的GPIO端口 GPIOPinTypeOut(LED_PORT, LED_PIN); // 设置LED所在的管脚为输出 GPIOPinWrite(LED_PORT, LED_PIN, 1 << 2); // 熄灭LED
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); // 使能Timer模块
TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | // 配置Timer为16位单次触发 TIMER_CFG_A_ONE_SHOT);
TimerPrescaleSet(TIMER0_BASE, TIMER_A, 199); // 预先进行200分频 TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
for (;;) {
SysCtlDelay(10 * (TheSysClock / 3000)); // 延时,消除松键抖动
TimerLoadSet(TIMER0_BASE, TIMER_A, 45000); // 设置Timer初值,定时1.5s TimerEnable(TIMER0_BASE, TIMER_A); // 使能Timer计数 GPIOPinWrite(LED_PORT, LED_PIN, 0x00); // 点亮LED,定时开始 }
// TimerA的中断服务函数 void Timer0A_ISR(void) {
unsigned char ucVal; unsigned long ulStatus;
}
}
while (GPIOPinRead(KEY_PORT, KEY_PIN) == 0x00); // 等待按键抬起
if (GPIOPinRead(KEY_PORT, KEY_PIN) == 0x00) {
// 如果复位时按下KEY
IntEnable(INT_TIMER0A); IntMasterEnable( );
// 使能Timer超时中断 // 使能Timer中断 // 使能处理器中断
SysCtlPeriEnable(KEY_PERIPH);
// 使能KEY所在的GPIO端口
GPIOPinTypeIn(KEY_PORT, KEY_PIN); // 设置KEY所在管脚为输入
jtagWait( ); clockInit( );
// 防止JTAG失效,重要! // 时钟初始化:晶振,6MHz
SysCtlDelay(10 * (TheSysClock / 3000)); // 延时,消除按键抖动
18
ulStatus = TimerIntStatus(TIMER0_BASE, true); // 获取当前中断状态 TimerIntClear(TIMER0_BASE, ulStatus); // 清除中断状态,重要!
if (ulStatus & TIMER_TIMA_TIMEOUT) // 如果是超时中断 {
ucVal = GPIOPinRead(LED_PORT, LED_PIN); // 反转LED GPIOPinWrite(LED_PORT, LED_PIN, ~ucVal); } }
5. 16位周期定时
程序清单1.5是Timer模块16位周期定时器模式的例子。该例程实现的功能与32位周期定时的例程(参见程序清单1.2)基本相同,只是多了一个8位预分频器的运用。
程序清单1.5 Timer例程:16位周期定时
#include \#include
// 定义LED
#define LED_PERIPH SYSCTL_PERIPH_GPIOG #define LED_PORT GPIO_PORTG_BASE #define LED_PIN GPIO_PIN_2
// 主函数(程序入口) int main(void) {
SysCtlPeriEnable(LED_PERIPH); // 使能LED所在的GPIO端口 GPIOPinTypeOut(LED_PORT, LED_PIN); // 设置LED所在管脚为输出
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); // 使能Timer模块
TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | // 配置Timer为16位周期定时器 TIMER_CFG_A_PERIODIC);
TimerPrescaleSet(TIMER0_BASE, TIMER_A, 99);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
IntEnable(INT_TIMER0A);
// 使能Timer超时中断 // 使能Timer中断
// 预先进行100分频
TimerLoadSet(TIMER0_BASE, TIMER_A, 30000); // 设置Timer初值,定时500ms
jtagWait( ); clockInit( );
// 防止JTAG失效,重要! // 时钟初始化:晶振,6MHz
19