本帖最后由 dan158185 于 2015-11-24 13:34 编辑
我写的tinyos底层部分,虚拟定时器基础驱动两个部分:
1,定时器溢出初始化 只开启溢出中断
static error_t HplCC2530Timer1AlarmCounterP__0__Init__init(void )
{
T1CTL = 0x00;
T1CCTL0 = 0;
T1CCTL1 = 0;
T1CCTL2 = 0;
T1CNTL = 0;
T1CNTH = 0;
T1CTL = (T1CTL & ~CC2530_T1CTL_DIV_MASK) | CC2530_TIMER1_DIV_128;
T1IE = 1;
TIMIF |= 1 << CC2530_TIMIF_OVFIM;
T1CTL = (T1CTL & ~CC2530_T1CTL_MODE_MASK) | CC2530_TIMER1_MODE_FREE;
return SUCCESS;
}
2,不关心比较跳过;设定比较起通道1,你不用去关心的是那些中间的赋值计算,那是我的系统计算出来的时间剩余值
static void HplCC2530Timer1AlarmCounterP__0__Alarm0__startAt(uint16_t t0, uint16_t dt)
{
uint16_t set;
uint16_t now;
uint16_t elapsed;
/* atomic removed: atomic calls only */
{
((uint8_t *)&now)[0] = T1CNTL;
(
(uint8_t *)&now)[1] = T1CNTH;
elapsed = now - t0;
if (elapsed >= dt) {
set = now + 5;
}
else
{
uint16_t remaining = dt - elapsed;
if (remaining <= 5) {
set = now + 5;
}
else
{
set = remaining + now;
}
}
T1CC1L = (uint8_t )((uint8_t *)&set)[0];
T1CC1H = (uint8_t )((uint8_t *)&set)[1];
T1CCTL1 |= 1 << CC2530_T1CCTLx_MODE;
T1CCTL1 |= 1 << CC2530_T1CCTLx_IM;
}
return;
}
3,中断函数:
//# 265 "/opt/tinyos-2.x/tos/chips/cc2530/timer_hpl/HplCC2530Timer1AlarmCounterP.nc"
#pragma vector = 75
__interrupt void T__vector_75(void)
{
{ __nesc_atomic_t __nesc_atomic = __nesc_atomic_start();
{
if (* (uint8_t __xdata *)0x62A3 & (1 << CC2530_T1CCTLx_IM) && T1STAT & (1 << CC2530_T1CTL_CH3IF)) {
//比较器通道3中断
* (uint8_t __xdata *)0x62A3 = 0X0;
T1STAT &= ~(1 << CC2530_T1CTL_CH3IF);
HplCC2530Timer1AlarmCounterP__0__Alarm2__fired();
}
if (T1CCTL2 & (1 << CC2530_T1CCTLx_IM) && T1STAT & (1 << CC2530_T1CTL_CH2IF)) {
//比较器通道2中断
T1CCTL2 = 0X0;
T1STAT &= ~(1 << CC2530_T1CTL_CH2IF);
HplCC2530Timer1AlarmCounterP__0__Alarm1__fired();
}
if (T1CCTL1 & (1 << CC2530_T1CCTLx_IM) && T1STAT & (1 << CC2530_T1CTL_CH1IF)) {
//比较器通道1中断
T1CCTL1 = 0X0;
T1STAT &= ~(1 << CC2530_T1CTL_CH1IF);
HplCC2530Timer1AlarmCounterP__0__Alarm0__fired();
}
if (T1STAT & (1 << CC2530_T1CTL_OVFIF)) { //溢出中断
T1STAT &= ~(1 << CC2530_T1CTL_OVFIF);
HplCC2530Timer1AlarmCounterP__0__Counter__overflow();
}
}
__nesc_atomic_end(__nesc_atomic); }
}
对于* (uint8_t __xdata *)0x62A3这种也是操作寄存器,这个是tinyos转成c文件后的代码,也是肯定能用的驱动,
对于比较起通道 上面已经说过注意芯片 上电初始化默认是开启的,再者就算不开启中断,屏蔽中断发生了该中断事件标志仍然会 置位;
添加中断服务函数标志判断,断点打开看看你进去的是那个中断,反过去查找手册了
T1CNTH:T1CNTL freemode的寄存器计数
通过看函数2已经能看出来假设我要在freemode中断 不影响T1CNTH:T1CNTL计数那就是读取当前T1CNTH:T1CNTL的值加上我要比较起通道定时的值设置
T1CCxH:T1CCxL
然后开启比较起通道
T1CCTLx |= 1 << CC2530_T1CCTLx_MODE;
T1CCTLx |= 1 << CC2530_T1CCTLx_IM;
看不看得懂将不再多说
|