CC2530上共有T1~T4,4个定时器,另外还有诸如系统定时器、睡眠定时器、看门狗定时器等等。在不同的电源模式下可以使用不同速率的振荡器。晶振的精度高、能耗高、启动慢;RC振荡器的精度更低一些,能耗低,启动快。需要注意的是在射频传输时必须使用32M的晶振,而在要求低功耗又对精度要求不高的场景下可以使用RC振荡器。默认情况下,使用Active / Idel模式,32M晶振,振荡器速率为16M。
功耗模式 | 高速振荡器 | 低速振荡器 | 稳压器 |
---|---|---|---|
配置 | A. None B. 32MHz 晶振 C. 16MHz RC | A. None B. 32k 晶振 C. 16kHz RC | |
Active / Idle Mode | B和C可同时使用 | B或C任选其一 | ON |
PM1 | A | B或C任选其一 | ON |
PM2 | A | B或C任选其一 | OFF |
PM3 | A | A | OFF |
对于定时器,依然有轮询和中断两种方式,由于中断方式的优点,这里只讲中断方式。下面以T1计时器为例,配置并启动定时器,再用中断来处理定时器的中断请求有如下步骤:
- 选择晶振,待晶振稳定后设定速率。
CC2430与CC2530的数据手册在时钟、睡眠相关的寄存器上是有差别的,有的只是换了个名字,有的被挪到别的寄存器了。根据[1]的博文,CC2530的数据手册在这里是错误的。
cc2530数据手册上SLEEPCMD这个寄存器的第2位(从第0位开始计)说明是错误,该位的正确说明,应当看cc2430的数据手册SLEEP寄存器的第2位。当该位为0时,将两个高频晶振同时上电;该位为1时,将CLKCONCMD.OSC位没有选择的高频晶振关闭。同样的,cc2530数据手册SLEEPSTA这个寄存器的第6位和第5位说明是错误,这两位的正确说明,应当看cc2430的数据手册SLEEP寄存器的第6位和5位[1]。
根据数据手册,选择晶振或是RC,需要设置CLKCONCMD的第6位,1为使用RC,0为使用晶振。然后是等待振荡器报告其稳定,晶振和RC所检查的位各不同,当然按[1]的方式去确认稳定似乎也是可行的,但我发现下面这种方法也可以监测振荡器的稳定。
while(!(SLEEPSTA & 0x40)); // 对应使用晶振 while(!(SLEEPSTA & 0x20)); // 对应使用RC asm("NOP"); // 额外多等待一个安全时间,以确保其真的稳定了
当振荡器稳定后可以设定其速率,CC2530可以选择8档不同的速率,比CC2430多出好几种选择。数据手册也提到,选择的速率不能超过振荡器的最大振荡频率。在CC2530中,设置振荡器速率需要操作CLKCONCMD的低3位,从000~111,对应32M~250k的8档不同速率。对连续多位的写操作,移位操作是最方便的。预先定义好这些速率常量,设置时将CLKCONCMD先右移3位再左移3位,再把这个速率加上(3位二进制数)就完成了。
CLKCONCMD = (CLKCONCMD >> 3 << 3) + speed;
- 设置定时器的分频和工作模式
对于T1来说,分频和工作模式使用的是T1CTL的低4位,同样使用移位操作,这里不再赘述,表示不同分频和工作模式的二进制数可以参阅数据手册。
- 开启必要的中断
不使用T1提供的几个通道的情况下,一共需要开3个中断,分别是T1的中断、总中断、TIMIF.OVFIM(默认开启),所以实际上,只需要开2个即可。
EA = 1; //开启中断 TIMIF |= 0x40; IEN1 |= 0x02;
- 编写T1的中断请求代码
中断请求都有固定的格式,copy、改,就行了。
//定时器T1中断处理函数 #pragma vector = T1_VECTOR __interrupt void T1_Tick_IRQ(void){ flashAllLeds(speed); // 根据振荡器的速度来闪烁LED, // 当前速度可从CLKCONSTA的低三位读出, // 即speed = CLKCONSTA & 0x07 // 清除中断标志 T1STAT &= 0x20; //T1STAT.OVFIF=0 T1IF =0; }
我在实验中发现了一些令人沮丧的现象,比如,当断点加到那些移位操作的代码上,调试时会报IDataStack空间被占满,随后一定几率IDE崩溃;又比如用宏定义设定的一些常量在调试时发现它们居然还会变动!再比如,如果我声明一个变量并赋值为一个已经宏定义的常量,例如:int speed = OSC_SPEED_4M;,然后把这个speed作为入参,传进函数里,程序会罢工,断点一上,又是IDataStack耗尽,根本查不出原因。IAR的编辑和调试功能实在做得太糟糕了,一个2011年出的IDE,界面跟98年出的VC6相近,功能上还远不如VC6。但编译器和连接器至此一家,你也只能边骂边用了。
没有评论:
发表评论