附整个工程。
原理,做高频信号测量。ACLK=32768HZ,MCLK=SMCLK=4MHZ
首先利用TB0产生一个1S闸门,闸门关闭的时候OneSecondFlag置位。
TA0的时钟为TA0CLK(即待测信号),10分频,增计数模式,TA0CCR0=100;在闸门期间,TA0第一次中断的时候,打开TA2标准计数,并把TA0CCR0=10000。闸门关闭后,TA0在紧接着的一次中断中关闭自己。并将HighFrequenceWaitFlag清零。
实际发现,好像TA0没有按照计划在应有的时刻关掉。
还有,请教TI在多中断中怎样处理来防止中断竞争之类的事情发生。有没有相关的例程
主要程序部分如下:
void TAInit1() //高频预测量定时器设置
{
/*TB0设定1S间隔*/
TB0CTL|=MC_0; //关闭定时器
TB0CTL|=TBCLR; //计数器TA2清零
TB0CCR0=32767; //比较模式对比数值
TB0CCTL0|=CCIE; //CCRO比较中断使能
TB0CTL|=TBSSEL_1+ID_0;//选择ACLK时钟32.768KHZ,初级1分频,关闭TA2IFG中断
TB0EX0=TBIDEX_0;//二级1分频
/*TA0设定待测信号计数*/
TA0CTL|=MC_0; //关闭定时器
TA0CTL|=TACLR; //计数器TA0清零
TA0CCR0=100; //比较模式对比数值
TA0CCTL0|=CCIE; //CCRO比较中断使能
TA0CTL|=TASSEL_0+ID_1;//选择TA0CLK,即待测信号,初级2分频,关闭TA0IFG中断
TA0EX0=TAIDEX_4;//二级5分频,总共为10分频
/*TA1标准信号计数*/
TA1CTL|=MC_0; //关闭定时器
TA1CTL|=TACLR; //计数器TA1清零
TA1CTL|=TASSEL_2+ID_0+TAIE;//选择SMCLK4MHZ,初级1分频,开启TA1IFG中断
TA1EX0=TAIDEX_0;//二级1分频
}
/*TA2-CCR0中断服务函数*/
#pragma vector=TIMER0_B0_VECTOR //CCR0中断标志
__interrupt void TA2Interrupt0()
{
OneSecondFlag=1; //1S标志位置位
TB0CTL=MC_0; //关闭定时器2
TB0CTL&=~TBIE;
/*测试用*/
P1OUT^=BIT2;
if(HInputOverflowTime==0)//溢出次数为0,表示实际信号为低频
{
TA0CTL|=MC_0; //TA0直接关闭
TA0CTL&=~TAIE;
IsHighFrequenceFlag=0;//判断为低频
HighFrequenceWaitFlag=0;//高频测量等待结束
/*测试用*/
P1OUT^=BIT3;
}
}
/*TA0-CCR0中断服务函数*/
#pragma vector=TIMER0_A0_VECTOR //CCR0中断标志
__interrupt void TA0Interrupt0()
{
//__enable_interrupt();
if(OneSecondFlag==0) //表示还在1S的大闸门内
{
if(HInputWorkFlag==0) //待测信号第一个闸门沿到来
{
TA0CCR0=10000; //比较模式对比数值
TA1CTL|=MC_2; //标准信号开始同时进入连续技计数模式
HInputWorkFlag=1; //进入闸门内
}
else //处于待测信号闸门内
{
HInputOverflowTime++;
P1OUT^=BIT4;
}
}
/*就是这里好像不能按照设想关掉相应的定时器,实际好像会一直进入中断,或者好一点的话也会比预计多中断几次*/
if(OneSecondFlag==1) //表示1S的大闸门已经关闭
{
TA0CTL|=MC_0; //关闭待测信号计数
TA0CTL&=~TAIE;
HInputOverflowTime++;
TA1CTL&=~TAIE;
TA1CTL|=MC_0; //关闭标准信号计数
HReferenceNum=TA1R;//暂时记录标准信号计数终值
HighFrequenceWaitFlag=0;//高频测量等待结束
P1OUT^=BIT5;
}
}
/*TA1IFG中断服务函数*/
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TA1Interrupt1()
{
switch(__even_in_range(TA0IV,14))
{
case 14:HROverflowTime++;break;
default:break;
}
}
/*高频测量主函数*/
void HFMeasure()
{
OneSecondFlag=0; //定时1S标志
TB0CTL|=MC_1;//定时器2增模式
TA0CTL|=MC_1;//定时器0增模式
DelayMs(1500);
//while(HighFrequenceWaitFlag);//高频测量等待
//P1DIR|=BIT3;
//P1OUT|=BIT3;
TB0CTL|=MC_0; //关闭定时器TB
TA0CTL|=MC_0; //关闭定时器
TA1CTL|=MC_0; //关闭定时器
HInputNum=100*HInputOverflowTime;
DelayMs(1);
//HReferenceNum++;
HReferenceNum+=HROverflowTime*65537;
DelayMs(2);
}
Triton Zhang:
没来及看你的代码,先普及下MSP430的中断系统:
1. 和大多数的MCU一样,MSP430的中断系统也分优先级,不同的中断源有不同的优先级。同一时间发生的N个中断时会优先触发中断级别较高的中断。
2. 和很多MCU不一样的是,一旦进入了中断处理函数,任何中断都可能被其他中断给打断而不管新中断的优先级是否比当前的中断优先级高还是低。可以这样理解,进入中断之后本次中断的优先级就变成最低的了,任何其他中断都可以打断本中断。
3. 所以在实际编程过程中,为了防止本次中断被其他中断打断,进入中断就需要关闭全局中断使能标志。
4. 如果在有的应用中允许某个中断类型打断本中断,就要人为得打开全局中断标志,并屏蔽掉其他不允许中断的标志类型。这样操作很复杂,所以推荐在应用中尽量减少中断处理的程序,而是用状态机或标志位来实现中断指示,放在主函数去处理需要较多时间处理的事件。
ZhaoF:
回复 Triton Zhang:
因为之前看到一些资料,和你说的刚好相反,所以想要再次确认一下,430的中断机制到底是怎样的,有没有这方面的官方资料:
附我之前看到的一下说法:
1)430默认的是关闭中断嵌套的,除非你在一个中断程序中再次开总中断EINT;
2)当进入中断程序时,只要不在中断中再次开中断,则总中断是关闭的,此时来中断不管是比当前中断的优先级高还是低都不执行;
3)若在中断A中开了总中断,则可以响应后来的中断B(不管B的优先级比A高还是低),B执行完再继续执行A。注意:进入中断B后总中断同样也会关闭,如果B中断程序执行时需响应中断C,则此时也要开总中断,若不需响应中断,则不用开中断,B执行完后跳出中断程序进入A程序时,总中断会自动打开;
4)若在中断中开了总中断,后来的中断同时有多个,则会按优先级来执行,即中断优先级只有在多个中断同时到来时才起做用!中断服务不执行抢先原则。
5)对于单源中断,只要响应中断,系统硬件自动清中断标志位,对于TA/TB定时器的比较/捕获中断,只要访问TAIV/TBIV,标志位倍被自动清除;
麻烦,对这5点的正确性予以辨别和确认。这对我很重要。谢谢!!!!!!