CC2540的Timer1寄存器问题
目前有个项目用到CC2540使用OSAL蓝牙栈,项目应用中使用Timer1作为PWM输出的计数器,使用center-aglin,同时开启Timer1中断,使用中断对PWM输出的个数进行计算;发现中断计数的个数与实际不符,理论上计数个数应该为实际输出个数的2倍;断点后查看,发现中断中T1STAT的中断源无法清除,且中断源的mask bit对T1STAT的中断源没有控制;项目实际应用ch1和ch2,已经屏蔽ch0.2.3.4和T1的overflow的mask bit;中断查看是还是T1STAT的ch2还是被置位。代码如下,请达人或TI的员工能给一个答复。谢谢!
/*
* 函数名:ini_pwm
* 函数功能: 初始化并启动pwm 输出
* 参数: aa 要产生的2微秒延时个数
*/
void ini_pwm() //初始化PWM相关寄存器
{
CC_TYPE unTicks; //装载到T1CC0寄存器中的数据
uint8 u8TickSpdDiv; //取得时钟的前期分频CLKCONSTA.TICKSPD的值
//disable interrupt mask bit
T1CCTL0 &= ~0xC0; //disable RF and channel 0 interrupt mask bit
T1CCTL1 &= ~0x80; //disable RF interrupt mask bit
T1CCTL2 &= ~0xC0; //disable RF and channel 2 interrupt mask bit
T1CCTL3 &= ~0xC0; //disable RF and channel 3 interrupt mask bit
T1CCTL4 &= ~0xC0; //disable RF and channel 4 interrupt mask bit
TIMIF &= ~0x40; //disable Timer1 overflow interrupt mask bit
CLKCONSTA = 0;
u8TickSpdDiv = (CLKCONSTA & 0x38) >> 3; //获取当前定时器时钟源的预分频
unTicks.u16Counters = ((MAIN_CLOCK / SEND_FRE) >> u8TickSpdDiv) / 2; //
//由于我们的主时钟为32Mhz,要得到的频率为125Khz,并且定时器T1CTL.div=0,即预分频为0
//因此就算是u8TickSpdDiv为0.我们得到的u16Ticks的最大值为32000000/125000=256
T1CC0L = unTicks.u8Counters[0]; //PWM波周期设定
T1CC0H = unTicks.u8Counters[1];
unTicks.u16Counters = ((unTicks.u16Counters) * 55)/100;
T1CC1L = unTicks.u8Counters[0]; //占空比设置,设定为50%占空比
T1CC1H = unTicks.u8Counters[1];
unTicks.u16Counters = ((MAIN_CLOCK / SEND_FRE) >> u8TickSpdDiv) / 2;
unTicks.u16Counters = ((unTicks.u16Counters) * 45)/100;
T1CC2L = unTicks.u8Counters[0]; //占空比设置,设定为50%占空比
T1CC2H = unTicks.u8Counters[1];
T1CCTL1 |= 0x04; // 通道1设定为比较模式
T1CCTL1 |= 0x18; // 向上比较设置输出,在0清零
T1CCTL2 |= 0x04; // 通道1设定为比较模式
T1CCTL2 |= 0x20; //向上比较清除输出,在0设置
//设置pwm输出模式,T1CCTL1和T1CCTL2的输出模式使得
//两路PWM波是对称输出的
PERCFG |= 0x40; // 将timer1的端口移动到备用端口2
P1SEL |= 0x03; // P1_0 为pwm2口,P1_1为pwm1口
P1DIR |= 0x03; //p1_0,p1_0口为输出
T1IE = 1;//使能T1IE
T1CTL |= UP_AND_DOWN_MODE; //开启pwm工作使用从0到T1CC0反复计数
}
#pragma vector = T1_VECTOR
__interrupt void T1_ISR(void)
{
if(T1STAT & 0x02)
{
T1STAT &= ~0x06; // clear interrupt sourse bit
if(m_Cap.Sendpwm_Num > 0)
{
m_Cap.Sendpwm_Num--;
P0_4 = !P0_4;
}
else
{
T1CTL &= 0xFC;
}
}
}
//*********************************************
//函数名称:sendPWM
//
//输入参数:void
//
//输出参数:void
//
//功能描述:产生125Khz占空比为50%的PWM波
//修改历史:
//*********************************************
void sendPWM(void)
{
ini_pwm(); //timer 1配置初始化
#if 1
while(m_Cap.Sendpwm_Num !=0)
{};
STOP_PWM();
#else
{
delay(196);delay(196);delay(196);delay(196);delay(196);delay(196);
delay(196);delay(196);delay(196);delay(196);delay(196);delay(196);
}
STOP_PWM(); //关闭pwm工作
#endif
}
//*********************************************
//函数名称:stopPWM
//
//输入参数:void
//
//输出参数:void
//
//功能描述:停止产生PWM波且输出为低
//修改历史:
//*********************************************
void STOP_PWM(void)
{
PERCFG |= 0x40; // 将timer1的端口移动到备用端口2
P1SEL &= ~0x03; // P1_0 为pwm2口,P1_1为pwm1口
P1DIR |= 0x03; //p1_0,p1_0口为输出
P1 &= ~0x03; //low
}
补充说明一下,IDE为IAR for 8051版本8.10
Jet Shaw,
不知道你的问题是否已经解决了没有?
如果没有,建议你先用单独的main函数干净地试一下你的程序,看看是否有其他程序在影响timer1。