用TIME0循环读四路风扇转速,是直接用time0来计算脉宽,我是循环开中断来做的,
(TA0CCTL1&= ~CCIE; TA0CCTL2|= CCIE;)-->(TA0CCTL2&= ~CCIE; TA0CCTL3|= CCIE;)......
(TA0CCTL4&= ~CCIE; TA0CCTL1|= CCIE;)
在中断里面关掉自己中断的使能和 TA0CTL|=TACLR;有没有潜在的危险?
char fan_times_tmp = 0; //用来记录次数的中间变量
char fan_flag = 0; //进入中断标志位
#pragma vector=TIMER0_A1_VECTOR
//__interrupt void TIMER0_A1_ISR(void)
__interrupt void TIMER0_A(void)
{
switch(TA0IV)
{
case 0: break; // No interrupt
case 2:
if((TA0CCTL1&CM_2)&&(fan_flag == 0))
{ //清计数器
TA0CTL|=TACLR;
fan_flag = 1;
P3OUT ^= BIT2;
}
else if((TA0CCTL1&CM_2)&&(fan_flag == 1))
{
speed_tmp[fan_times_tmp++] = TA0CCR1;
fan_flag = 0;
if(fan_times_tmp == fan_data_time)
{
fan_a = 0;
for(fan_i=0;fan_i<fan_data_time;fan_i++)
fan_a +=speed_tmp[fan_i];
fan_a >>= 5; //除以4求平均值,以免数据不停跳变
fan_speed[0] = fan_a;
fan_i = 0;
// TA0CCTL1&= ~CCIE;
// TA0CCTL2|= CCIE;
fan_times_tmp = 0;
}
}
TA0CCTL1 &= ~CCIFG; break;
break; // CCR1 not used
case 4:
if((TA0CCTL2&CM_2)&&(fan_flag == 0))
{ //清计数器
TA0CTL|=TACLR;
fan_flag = 1;
}
else if((TA0CCTL2&CM_2)&&(fan_flag == 1))
{
speed_tmp[fan_times_tmp++] = TA0CCR2;
fan_flag = 0;
if(fan_times_tmp == fan_data_time)
{
fan_a = 0;
for(fan_i=0;fan_i<fan_data_time;fan_i++)
fan_a +=speed_tmp[fan_i];
fan_a >>= 5; //除以4求平均值,以免数据不停跳变
fan_speed[0] = fan_a;
fan_i = 0;
TA0CCTL2&= ~CCIE;
TA0CCTL3|= CCIE;
fan_times_tmp = 0;
}
}
TA0CCTL2 &= ~CCIFG;
break;
break; // CCR2 not used
case 6:
if((TA0CCTL3&CM_2)&&(fan_flag == 0))
{ //清计数器
TA0CTL|=TACLR;
fan_flag = 1;
}
else if((TA0CCTL3&CM_2)&&(fan_flag == 1))
{
speed_tmp[fan_times_tmp++] = TA0CCR3;
fan_flag = 0;
if(fan_times_tmp == fan_data_time)
{
fan_a = 0;
for(fan_i=0;fan_i<fan_data_time;fan_i++)
fan_a +=speed_tmp[fan_i];
fan_a >>= 5; //除以4求平均值,以免数据不停跳变
fan_speed[0] = fan_a;
fan_i = 0;
TA0CCTL3&= ~CCIE;
TA0CCTL1|= CCIE;
fan_times_tmp = 0;
}
}
TA0CCTL3 &= ~CCIFG;
break; // reserved
case 8:
if((TA0CCTL4&CM_2)&&(fan_flag == 0))
{ //清计数器
TA0CTL|=TACLR;
fan_flag = 1;
}
else if((TA0CCTL4&CM_2)&&(fan_flag == 1))
{
speed_tmp[fan_times_tmp++] = TA0CCR4;
fan_flag = 0;
if(fan_times_tmp == fan_data_time)
{
fan_a = 0;
for(fan_i=0;fan_i<fan_data_time;fan_i++)
fan_a +=speed_tmp[fan_i];
fan_a >>= 5; //除以4求平均值,以免数据不停跳变
fan_speed[0] = fan_a;
fan_i = 0;
TA0CCTL4&= ~CCIE;
TA0CCTL1|= CCIE;
fan_times_tmp = 0;
}
}
TA0CCTL4 &= ~CCIFG;
break; // reserved
case 10: // reserved
case 12: // reserved
case 14: //TA1CCTL1 &= ~COV; // overflow
break;
default:break;
}
}
另外我程序用也开了time1做轮询中断,因为mian函数中和轮询中断中存在这共同的全局变量,所以mian函数中在读写这个全局变量的时候要先关掉轮询中断,现在不清楚TA2CCTL1 &= ~CCIE; 存在不存在原子操作的说法,会不会在执行TA2CCTL1 &= ~CCIE;被中断硬件修改CCIFG位造成不可预知的情况?
while(1)
{
while(1) //关机
{
// while (!(UCA0IFG&UCTXIFG));
// UCA0TXBUF = 1;
PWM_CTRL(1,1);
TA2CCTL1 &= ~CCIE; //关轮询中断(避免 cpu_stat ***FLAG
//在轮询中断中发生改变 )
if( cpu_stat == CPU_POWER_DOWN )
{
if(1 == power_down_flag)
power_down_flag = 0;
power_on_flag = 1;
}
TA2CCTL1 |= CCIE; //开轮询中断
}
else
{
TA2CCTL1 |= CCIE;
break;
}
}
#pragma vector=TIMER2_A1_VECTOR
__interrupt void TIMER2_A1_ISR(void)
{
switch( __even_in_range(TA2IV,14))
{
case 0: break;
case 2:
P3OUT ^=0X01;
TA2CCR1 += 0X4E2; //按键检测 每5ms检测一次
|