打印

最近用了430f5510单片机写程序,用,关于一些原子操作

[复制链接]
3008|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
430_NEW_MAN|  楼主 | 2013-10-19 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用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检测一次

相关帖子

沙发
430_NEW_MAN|  楼主 | 2013-10-19 10:55 | 只看该作者
求430汇编高手解答。

使用特权

评论回复
板凳
dirtwillfly| | 2013-10-19 11:06 | 只看该作者
430_NEW_MAN 发表于 2013-10-19 10:55
求430汇编高手解答。

:L这和汇编有啥关系?

使用特权

评论回复
地板
430_NEW_MAN|  楼主 | 2013-10-19 11:18 | 只看该作者
最近公司一个做C++的同事看了,mian函数+中断类似多线程,并且存在着共同的全局变量,需要对全局变量("加锁")保护,现在思维乱了,分不清关CCIE存在不存在原子操作的说法,
需要把每一步C分解成汇编来考虑这个问题,思维乱了。

使用特权

评论回复
5
dirtwillfly| | 2013-10-19 12:23 | 只看该作者
430_NEW_MAN 发表于 2013-10-19 11:18
最近公司一个做C++的同事看了,mian函数+中断类似多线程,并且存在着共同的全局变量,需要对全局变量("加 ...

恩恩,这个东西只能看汇编,才能清楚

使用特权

评论回复
6
李冬发| | 2013-10-19 13:41 | 只看该作者
测脉宽用“捕足”不行吗?

使用特权

评论回复
7
430_NEW_MAN|  楼主 | 2013-10-19 13:50 | 只看该作者
李冬发 发表于 2013-10-19 13:41
测脉宽用“捕足”不行吗?

捕足?不理解 请简单说一下吧,谢谢

使用特权

评论回复
8
dirtwillfly| | 2013-10-19 16:00 | 只看该作者
测脉宽可以用外部中断捕获上下沿的时间点来计算出来

使用特权

评论回复
9
430_NEW_MAN|  楼主 | 2013-10-19 16:20 | 只看该作者
dirtwillfly 发表于 2013-10-19 16:00
测脉宽可以用外部中断捕获上下沿的时间点来计算出来

你说的也是一种方法,我用的也是一种方法,现在我更关心的是我的这样方法中,在中断中关闭这个中断的使能会不会有什么风险?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;

使用特权

评论回复
10
dirtwillfly| | 2013-10-19 17:21 | 只看该作者
430_NEW_MAN 发表于 2013-10-19 16:20
你说的也是一种方法,我用的也是一种方法,现在我更关心的是我的这样方法中,在中断中关闭这个中断的使能 ...

考虑了一下午。一直没敢草率的回答楼主的这个问题。
刚刚有了点思路。
楼主的这个问题其实是中断的优先级问题以及中断嵌套问题。
msp430默认的是关闭中断嵌套的,除非你在一个中断程序中再次开总中断EINT。
所以楼主在中断中关闭这个中断的使能,是不会被打断的,所以不会有风险。

使用特权

评论回复
11
430_NEW_MAN|  楼主 | 2013-10-19 21:43 | 只看该作者
dirtwillfly 发表于 2013-10-19 17:21
考虑了一下午。一直没敢草率的回答楼主的这个问题。
刚刚有了点思路。
楼主的这个问题其实是中断的优先级 ...

多谢版主的回复,我帖子实际两个问题,第一个问题是开中断后在main函数中关这个中断,假如关闭这个中断(TA2CCTL1 &= ~CCIE;)这步C语句在执行一半的时候(汇编中的某一部),然后被中断打断,然后返回没有执行完的汇编,这个过程会不会有什么危险?像_EINT()应该属于原子操作吧?然后TA2CCTL1 &= ~CCIE;呢? 现在我对这些感念很模糊,我得学习圧栈出栈的过程了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

19

帖子

1

粉丝