各位请进。。。
最近做东本用到了8962的TIMER模块。。。。
仔细研究了一下。下面是总结的。请评估一下。
同时纠正一下ZLG所翻译的timer数据手册上面有一个小小的错误,就是在运行控制块描述TimerRTCDisable()这个函数的时候,是写错了,写成了TimerRTCEnable()了。。大家可以验证一下。。。。
8962有4个TIMER模块,但是能用的CCP引脚却只有2个,分别对应着TIMER0_A的CCP0(PD4)和TIMER0_B的CCP1(PA6),所以我们如果将定时模块用作ONESHOT/PERIODIC触发的定时器时,是没有问题的,因为不会涉及到CCP引脚的用法。但是如果想用成32位的RTC模式,此时我们就只能引入时钟源才能用。这样就未免有些麻烦 。比如本人,就是从信号发生器上引入的32768.885HZ的方波信号的。
如果要用到16位的输入边沿计数/定时,PWM模式。都会用到CCP引脚的。
许多片子上面,如1138,都是利用其它的TIMER模块产生的PWM信号,作为RTC的时钟源,输入的边沿脉冲等。
下面我建立了一个小的模块工程,希望对大家有用:
本人偷了偷懒,没有接入新的时钟源,而是利用timer模块产生的时钟信号。
从8962移植到615上面的工程:(注意:我是在615的CCP1上面产生的10KHZ的方波的,所以CCP1必须作为CCP4的输入,要将这两个引脚短接)
//----------------------HEADER FILE 头文件-------------------------// #include "systemInit.h" #include "uartgetput.h" #define PART_LM3S615 #include <pin_map.h> #define CCP1_PERIPH SYSCTL_PERIPH_GPIOE #define CCP4_PERIPH SYSCTL_PERIPH_GPIOE //--------------------MAVRO DEFINITION 宏定义----------------------// /******************************************************************** 函数名称:void pulseInit(void) 函数入口:务 函数出口:无 函数说明:在CCP1管脚产生10KHz方波,为Timer2的16位输入边沿计数捕获功能提供时钟源 ********************************************************************/ 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 TIMER_CFG_B_PWM);
TimerLoadSet(TIMER0_BASE, TIMER_B, 600); // 设置TimerB初值 TimerMatchSet(TIMER0_BASE, TIMER_B, 300); // 设置TimerB匹配值 TimerEnable(TIMER0_BASE, TIMER_B); }
/******************************************************************** 函数名称:void timerInitCapCount(void) 函数入口:务 函数出口:无 函数说明:定时器16位输入边沿计数捕获功能初始化 ********************************************************************/ void timerInitCapCount(void) { SysCtlPeriEnable(SYSCTL_PERIPH_TIMER2); // 使能Timer模块 SysCtlPeriEnable(CCP4_PERIPH); // 使能CCP4所在的GPIO端口 GPIOPinTypeTimer(CCP4_PORT, CCP4_PIN); // 配置CCP4管脚为脉冲输入
TimerConfigure(TIMER2_BASE, TIMER_CFG_16_BIT_PAIR | // 配置Timer为16位事件计数器 TIMER_CFG_A_CAP_COUNT);
TimerControlEvent(TIMER2_BASE, // 控制TimerA捕获CCP负边沿 TIMER_A, TIMER_EVENT_NEG_EDGE);
TimerLoadSet(TIMER2_BASE, TIMER_A, 40000); // 设置计数器初值 TimerMatchSet(TIMER2_BASE, TIMER_A, 35000); // 设置事件计数匹配值
TimerIntEnable(TIMER2_BASE, TIMER_CAPA_MATCH); // 使能TimerA捕获匹配中断 IntEnable(INT_TIMER2A); // 使能Timer中断 IntMasterEnable(); // 使能处理器中断
TimerEnable(TIMER2_BASE, TIMER_A); // 使能Timer计数 } /******************************************************************** 函数名称:main() 函数入口:务 函数出口:无 函数说明:系统主函数 ********************************************************************/ int main(void) { //add initialization code in here jtagWait(); clockInit(); //for debugging uartInit(); uartPuts("\t 史莱克---timer-32bit perodic 测试\r\n"); SysCtlPeriEnable(LED_PERIPH); GPIOPinTypeOut(LED_PORT,LED_PIN); GPIOPinWrite(LED_PORT,LED_PIN,0X00);
pulseInit(); timerInitCapCount(); // Timer初始化:16位计数捕获
while(1) { ; } }
/******************************************************************** 函数名称:Timer0_Base_ISR(void) 函数入口:NO 函数出口:NO 函数说明:TIMER0 INTERRUPT FUNCTION ********************************************************************/ void Timer2_Base_ISR(void) { u8 ulValue; u32 ulStatus; ulStatus=TimerIntStatus(TIMER2_BASE,true); TimerIntClear(TIMER2_BASE,ulStatus);
if(ulStatus& TIMER_CAPA_MATCH) { TimerLoadSet(TIMER2_BASE, TIMER_A, 40000); // 重新设置计数器初值 TimerEnable(TIMER2_BASE, TIMER_A); // TimerA已停止,重新使能 ulValue=GPIOPinRead(LED_PORT,LED_PIN);
GPIOPinWrite(LED_PORT,LED_PIN,~ulValue); } }
|