原子操作

2019-07-21 20:37发布

用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;
   
  }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
liliang9554
1楼-- · 2019-07-22 20:15
需要把每一步C分解成汇编来考虑这个问题,思维乱了。
午夜粪车
2楼-- · 2019-07-22 21:39
恩恩,这个东西只能看汇编,才能清楚
jiajs
3楼-- · 2019-07-23 00:11
测脉宽用“捕足”不行吗?
liliang9554
4楼-- · 2019-07-23 05:03
 精彩回答 2  元偷偷看……
dengdc
5楼-- · 2019-07-23 07:43
测脉宽可以用外部中断捕获上下沿的时间点来计算出来
liliang9554
6楼-- · 2019-07-23 09:10
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;

一周热门 更多>