TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430FR5969 ADC模块异常 重启不恢复

现在用定时器控制ADC以32K的频率采样,采用的是序列通道单次采样模式,可是有时候ADC模块出现异常,即当busy标志位为1时,当定时器再次开启ADC模块启动采样时,ADC不再产生中断,并且看门狗发挥作用,单片机整体重启后,ADC模块依然异常,只有当按单片机的复位按键后,busy标志位才清零,单片机才能恢复正常。

void ADC_Cfg(void)
{ P1SEL1 |= BIT2|BIT3|BIT4; // A2 A3 A4
P1SEL0 |= BIT3|BIT4;
P2SEL1 |= BIT3|BIT4; // A6 A7
P2SEL0 |= BIT3|BIT4; P3SEL1 |= BIT3; // A15
P3SEL0 |= BIT3; PM5CTL0 &= ~LOCKLPM5;
ADC12CTL0 &=~ ADC12ENC; //初始化在ENC = 0下修改

/*************************************************************************/
ADC12CTL0 = ADC12SHT0_0 | ADC12ON|ADC12MSC; // ADC
ADC12CTL1 = ADC12SHP|ADC12CONSEQ_1|ADC12SSEL_2; // 序列通道单次采集
ADC12CTL2 = ADC12RES_2; //12位的转换精度
ADC12MCTL0 |= ADC12INCH_2 | ADC12VRSEL_4; // 
ADC12MCTL1 |= ADC12INCH_3 | ADC12VRSEL_4; // 
ADC12MCTL2 |= ADC12INCH_4 | ADC12VRSEL_4; // 

ADC12MCTL3 |= ADC12INCH_6 | ADC12VRSEL_4; // 
ADC12MCTL4 |= ADC12INCH_7 | ADC12VRSEL_4; // 
ADC12MCTL5 |= ADC12INCH_15 | ADC12VRSEL_4|ADC12EOS; /
ADC12IER0 = ADC12IE5; // Enable ADC conv complete interrupt
ADC12CTL0 &=~ ADC12ON;
ADC12CTL0 |= ADC12ENC;}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{ uchar busy_i=0;
while(ADC12CTL1&ADC12BUSY) //启动ADC
{ busy_i++; if(busy_i>>3) break; }
ADC12CTL0 &=~ (ADC12ENC); ADC12CTL0 |= ADC12ON|ADC12SC|ADC12ENC;
}

灰小子:

建议先参考下官网的例程。

你的思路有点和常用的不一样

一般是先开始转换,然后判断是否转换完毕,再之后是获得采样数值

 ADC12CTL0 |= ADC12SC;// 开始转换while ((ADC12IFG & ADC12BUSY)==0);value=ADC12MEM0;

tingmeng yan:

回复 灰小子:

我使用的是ADC中断,即当ADC转换完成后,触发ADC中断,在中断里读取数据。

为了降低功耗,我采样一次完成后,把ADC模块关闭,使用时再在定时器里打开

*******************************************************************************/
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void)
#else
#error Compiler not supported!
#endif
{
//switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
//{
//case ADC12IV_ADC12HIIFG://
//{
//ADC12IFGR2 &= ~ADC12HIIFG;// Clear interrupt flag
//// Exit_ULPM();
//break;
//}// case ADC12IV_ADC12IFG5://ADC采样中断{
P2OUT ^= BIT5;//测试,检测程序是否正常运行ADC12CTL0 &=~ADC12ENC;ADC12CTL0 &=~ADC12ON;ADC12CTL0 |=ADC12ENC;//关闭ADCTwire_AD = ADC12MEM2;Vin_AD= ADC12MEM0;Vcap_AD= ADC12MEM3;Vbat_AD= ADC12MEM5;
。。。。

tingmeng yan:

回复 灰小子:

我还想知道的是,为什么内部看门狗将单片机复位后还不能恢复正常呢?怎样才能用软件控制使其恢复正常?

灰小子:

回复 tingmeng yan:

你的定时器的定时时间是多长?
建议只在定时器中断服务程序使能adc转换,然后使用adc的中断服务程序完成采样数据的转移

tingmeng yan:

回复 灰小子:

void Timer_Cfg(void){ TA0CTL = TASSEL__ACLK | MC__UP; // TA0CCTL0 = CCIE; // TACCR0 interrupt enabled TA0CCR0 = 7;}

定时器使用的是ACLK,外部32K的低频晶振,正常采样周期250us,运行期间会根据采样数据转换为1.25ms,采样周期的转换不小于5s

Hao Mengzhen:

回复 tingmeng yan:

看门狗不能将ADC复位很奇怪,软件清空ADC寄存器后再写入应该就能恢复正常

赞(0)
未经允许不得转载:TI中文支持网 » MSP430FR5969 ADC模块异常 重启不恢复
分享到: 更多 (0)