This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR2433:ADC 卡在线路上

Guru**** 657500 points
Other Parts Discussed in Thread: MSP430FR2433
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1166833/msp430fr2433-adc-stuck-at-the-line

器件型号:MSP430FR2433

您好!

我在 msp430fr2433上配置 ADC 模块已经有几天的时间了、但是 程序只停留在第35行的特定行。我无法处理它。 可以检查一下吗?

#include <msp430.h>

/**
 * main.c
 */
int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	

	P1DIR &= ~BIT5;
	P1DIR |= BIT0 + BIT1;
	P1OUT |= BIT0 + BIT1;
	P1OUT &= ~(BIT0 + BIT1);

	PM5CTL0 &= ~LOCKLPM5;


	ADCCTL0 |= ADCON + ADCSHT_2;//采样保持时钟源默认即ADC时钟,ADC时钟源默认MODCLK=5MHz,采样保持16个ADC时钟周期
	ADCCTL1 |= ADCCONSEQ_2;
	ADCMCTL0 |= ADCINCH_13 + ADCSREF_1;//15通道,使用内部1.5V参考电压
	SYSCFG2 |= ADCPCTL5;           //A5口输入
	ADCIE |= ADCIE0;            //使能ADC中断
	PMMCTL2 |= INTREFEN;//使能内部参考电压




	for(;;)
	{
	   __delay_cycles(50);
	   ADCCTL0 |= ADCENC + ADCSC;

	   //ADCIFG |= ADCIFG0;
	 __bis_SR_register(CPUOFF + GIE);
	 __no_operation();
	 if(ADCMEM0 > 512)
	     {
	         P1OUT |= BIT0;
	         __delay_cycles(1000000);
	     }
	     else
	     {
	         P1OUT &= ~BIT0;
	         __delay_cycles(1000000);
	     }
	 }

}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(ADC_VECTOR)))
#endif
void ADCLED(void)
{

    switch(__even_in_range(ADCIV,12))
    {

        case  0: break; //No interrupt
        case  2: break; //conversion result overflow
        case  4: break; //conversion time overflow
        case  6: break; //ADC10HI
        case  8: break; //ADC10LO
        case 10: break; //ADC10IN
        case 12:        //ADC10IFG0
            __bic_SR_register_on_exit(CPUOFF);
                P1OUT |= BIT1;
                __delay_cycles(1000000);
                P1OUT &= ~BIT1;
                break;
        default:break;
    }
    //ADCIFG &= ~ADCIFG0;
}

此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、

    我发现您没有清除 ADCIFG 位、该代码应该只进入 LPM0模式:

    _bis_SR_register (CPUOFF + GIE);

    请参考以下示例:

    https://dev.ti.com/tirex/explore/node?node=A__AGc79yyzsPu1J.t4h.Nu.Q__msp430ware__IOGqZri__LATEST

    谢谢!

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Johnson:

    我不清除 ADCIFG 是因为它将在 ADCMEM0被读取时复位、并且我应该已经进入 LPM0模式。

    我看到了该示例、发现我没有解锁 PMM 寄存器。 我应该再试一次。

    谢谢、此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Johnson:

    我将代码更改为以下内容:

    #include <msp430.h>
    
    unsigned int ADC_Result;
    
    /**
     * main.c
     */
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
    
    
    	P1DIR |= BIT0 + BIT1;
    	P1OUT |= BIT0 + BIT1;
    	P1OUT &= ~(BIT0 + BIT1);
    
    	SYSCFG2 |= ADCPCTL1;        //A5口输入
    
    	PM5CTL0 &= ~LOCKLPM5;
    
    
    	ADCCTL0 |= ADCON + ADCSHT_2;//采样保持时钟源默认即ADC时钟,ADC时钟源默认MODCLK=5MHz,采样保持16个ADC时钟周期
    	ADCCTL1 |= ADCSHP;
    	ADCMCTL0 |= ADCINCH_5 + ADCSREF_1;//15通道,使用内部1.5V参考电压
    
    	ADCIE |= ADCIE0;            //使能ADC中断
    
    	PMMCTL0_H = PMMPW_H;
    	PMMCTL2 |= INTREFEN;//使能内部参考电压
        __delay_cycles(400);
    
    
    
    	while(1)
    	{
    
    	   ADCCTL0 |= ADCENC + ADCSC;
    
    	   //ADCIFG |= ADCIFG0;
    	 __bis_SR_register(CPUOFF + GIE);
    	 __no_operation();
    	 if(ADC_Result > 512)
    	     {
    	         P1OUT |= BIT0;
    	         //__delay_cycles(1000000);
    	     }
    	     else
    	     {
    	         P1OUT &= ~BIT0;
    	         //__delay_cycles(1000000);
    	     }
    	 }
    
    }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(ADC_VECTOR)))
    #endif
    void ADCLED(void)
    {
    
        switch(__even_in_range(ADCIV,12))
        {
    
            case  0: break; //No interrupt
            case  2: break; //conversion result overflow
            case  4: break; //conversion time overflow
            case  6: break; //ADC10HI
            case  8: break; //ADC10LO
            case 10: break; //ADC10IN
            case 12:        //ADC10IFG0
                __bic_SR_register_on_exit(CPUOFF);
                ADC_Result = ADCMEM0;
                    break;
            default:break;
        }
        //ADCIFG &= ~ADCIFG0;
    }
    

    但 在调试中经过2or3个周期后、它将停留在第41行。 我不‘s 发生了什么情况。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    > ADCCTL0 |= ADCENC + ADCSC;

    >_bis_SR_register (CPUOFF + GIE);

    如果您使用调试器步进、ADC 很可能会在这两行之间完成、并且 ISR 唤醒将丢失。 即使你不步进、也可能会发生这场比赛、因为时间非常接近。

    尝试在第一行之前插入(即在设置 ADCSC 之前):

    >_disable_interrupt ();//关闭窗口以避免竞争

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、

    我同意 Bruce 的观点、您可以尝试以下方法:

    代码:  

    _disable_interrupt ();

    ADCCTL0 |= ADCENC + ADCSC;

    _bis_SR_register (CPUOFF + GIE);

    谢谢!

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Johnson:

    感谢 Bruce 和 Johnson。 我尝试了您的代码、它运行良好。 但现在出现了一个问题、即 ADCMEM0可以在没有模拟输入的情况下读取除0以外的数字。 我真的很困惑。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、

    如果您未连接任何模拟输入、则该引脚保持悬空、因此我们具有值。

    您可以尝试将此引脚接地、然后该值将保持在0左右。

    谢谢!

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    >SYSCFG2 |= ADCPCTL1;// A5口输入

    >ADCMCTL0 |= ADCINCH_5 + ADCSREF_1;// 15通道,使用内部1.5V参考电压

    您正在使用哪种 ADC 输入? 如果需要 A1 (P1.1)、请使用 ADCINCH_1。 如果需要 A5 (P1.5)、请使用 ADCPCTL5 [参考数据表(SLASE59D)表6-17]。

    如果您使用的是 Launchpad、P1.1已跳线至 LED2、P1.5 (A5)已跳线至反向通道 UART、因此 P1.6 (A6:ADCPCTL6/ADCINCH_6)可能 是更好的选择。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="47378" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1166833/msp430fr2433-adc-stuck-at-the-line/4393084 #4393084"]如果需要 A1 (P1.1)、请使用 ADCINCH_1。 如果需要 A5 (P1.5)、请使用 ADCPCTL5 [参考数据表(SLASE59D)表6-17]。[/引用]

    您是说输入引脚和 ADCINCH 应该匹配吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ben、

    如果您使用 lanuchpad,则还有其他一些电路,如 LED、UART……

    因此、为了在没有任何其他连接的情况下使用 ADC 通道、P1.6是一个不错的选择。

    谢谢!

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、ADCPCTL5和 ADCINCH_5中的"5"都是指引脚 A5。