题外话
好久没更了,今晚继续。
虽然Stellaris Cotex-M3系列芯片大部分已经停产,但是仍然阻止不了很多公司对它的喜爱。个人感觉从开发者
的角度来说选择这个系列有两个原因:
- TI官方提供驱动库指南,里面包含了大量的API供开发者调用,大大缩短项目开发时间,个人感觉TI的
这份驱动库指南比STM32的驱动库要更贴近开发者,STM32库只是简单的把所有API放到一起,没有分类,
有时候要调试一个模块,看到如此多的API有一种不知从何下手的感觉。 - 更重要的一个原因:性价比高,单块CPU售价低至$1.0,对Cotex-M3内核芯片来说,那可是相当的诱人。
正文
相信使用过单片机的开发者都知道定时器,定时器可以说是是单片机必不可少的一块资源,具体功能就不
多说。由于项目需要,LM3SXXX的4个32位定时器资源不够用,无奈之下,不得不将32定时器拆分位为16位
定时器,在调试过程中遇到了小小的问题。先看一段代码,功能是将两个16位合并为32位定时器。
void Timer0_A_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/1000);//定时 1000 us
IntMasterEnable();
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
IntEnable(INT_TIMER0A);
}
上面一段程序的功能室将定时器0配置为一个32位定时器,定时时间是1 ms,程序中配置的是定时器0 A模块一
个16位定时器,但实际上是一个32位而非16位定时器,当然中断向量还是定时器0_A,如果我要将定时器0配置
为16位定时器该怎么配置呢,之前我是这样配置:
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);
TimerLoadSet(TIMER1_BASE, TIMER_A, 64000);
TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
IntEnable(INT_TIMER1A);
结果是可行的,于是我想到了把定时器B也利用起来,SO,我配置为如下:
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC);
TimerLoadSet(TIMER1_BASE, TIMER_B, 81536);
TimerIntEnable(TIMER1_BASE, TIMER_TIMB_TIMEOUT);
IntEnable(INT_TIMER1B);
但是结果并非我预料的那样,时钟只有一个定时器工作,我仔细检查了好几遍程序,逻辑没有错。
调试时看寄存器发现了问题的所在,当调用
TimerConfigure(TIMER1_BASE,TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC);
时会将上一次的配置覆盖掉,也就是覆盖掉对定时器A的配置,对应的寄存器是GOTMCFG,所以,要同时使用
两个寄存器得同时配置A和B,代码如下:
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_PERIODIC);
TimerLoadSet(TIMER1_BASE, TIMER_A, 64000);
TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
IntEnable(INT_TIMER1A);
TimerLoadSet(TIMER1_BASE, TIMER_B, 81536);
TimerIntEnable(TIMER1_BASE, TIMER_TIMB_TIMEOUT);
IntEnable(INT_TIMER1B);
当再次测试的时候,定时器A 、B都能正常工作。
约是800us左右。如果要实现更长时间的定时,得使用其他方法。
完结。^_^