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.

[参考译文] MSP430FR2355:MSP430FR2355多通道 ADC 采样、无需使用通道序列

Guru**** 2516840 points
Other Parts Discussed in Thread: MSP430FR2355

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/923534/msp430fr2355-msp430fr2355-multiple-channel-adc-sampling-without-using-sequence-of-channels

器件型号:MSP430FR2355

大家好、

我正在使用 MSP430FR2355 Launchpad。 我想对3个数据通道进行采样、但无法使用 A2、因为它用作 SAC 输入引脚(OA-)。

如何在不使用通道序列设置的情况下使用 A3、A1&A0?

IAM 使用 TimerB1.1以1000Hz 的采样率触发 ADC。

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

    您好、Sumit、谢谢您的问题!

    序列从 ADCINCHx 位选择的通道开始、递减到通道 A0。 因此、请勿采用通道序列模式。 您可以在 TimerB1.1 触发 ADC 期间分配 ADC 通道。

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

    您好,

    感谢您的回复。 在 TimerB1.1 触发 ADC 期间、我不理解分配 ADC 通道的含义。

    我没有为 TimerB1.1 中断编写任何 ISR。

    我已经使用 Timer1_B0_ISR 来切换 GPIO 以检查采样率、但尚未编写 TimerB1.1 ISR。

     我还使用了 ADC 转换中断、IAM 在其中读取我的结果。

    您能为我提供一个小示例吗?

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

    您好!

    我在定时器中断期间尝试使用以下代码分配 ADC 通道。

    
    

    在每1ms 计时器中断内、我正在编写此代码。 但我将在通道中获得相同的 ADC 值。 我存储了要检查的通道的 ADC 结果、发现它们是彼此的副本。

    我的 完整 ADC 代码、计时器初始化及其中断

    //配置 ADC
    ADCCTL0 |= ADCSHT_4|ADCON|ADCMSC; //ADCON | ADCMSC;
    ADCCTL1 |= ADCSHP|ADCSHS_2|ADCCONSEQ_0|ADCSSEL_0;//ADCSHS_2 | ADCCONSEQ_3|ADCSSEL_0;//重复单通道;TB1.1 TRIG 样本启动
    // ADCCTL1 |= ADCSHP|ADCSSEL_0;//温度变化
    ADCCTL2 &=~ADCRES; //清除 ADCCTL 中的 ADCRES
    ADCCTL2 |= ADCRES_2; // 12位转换结果
    ADCMCTL0 |= ADCSREF_1; // A1 ADC 输入选择;Vref=2.5V
    // ADCMCTL0 |= ADCSREF_1;//温度变化
    ADCIE |= ADCIE0; //启用 ADC 转换完成中断
    
    
    ADCCTL0 |= ADCENC| ADCSC; // ADC 使能
    
    
    
    // ADC 转换触发信号- TimerB0
    // TB1CCTL0 = CCIE; //启用 CCR0中断
    TB1CTL |= TBSSEL_ACLK | TBCLR; // ACLK、清除 TBR
    TB1CCTL1 |= OUTMOD_2;
    TB1CCTL0 |= CCIE;
    TB1CCR0 = 31;//采样率500
    TB1CCR1 = 10;
    TB1CTL |= MC_1;
    
    //计时器 B1中断服务例程
    #pragma vector=Timer1_B0_vector
    __interrupt void Timer1_B0_ISR (void)
    
    {
    
    //_delay_cycles (100);
    
    //while (ADCCTL1和 ADCBUSY);
    // ADCCTL0 |= ADCENC | ADCSC;
    
    if ((SAC1OA 和 SACEN)
    
    ){
    // P2OUT &=~BIT0;
    SAC1OA &=~SACEN;
    SAC1DAC &=~DACEN;
    P2OUT |= BIT2;
    SAC3OA |= SACEN;
    SAC3DAC |= DACEN;
    SAC3DAT = VS_LED_LEVEL;
    SAC2DAT = VS_dc_offset;
    //SAC0DAT = VS_SAMPLE;
    P2OUT &=~BIT0;
    
    
    IS _IR = 0;
    
    //__delay_cycles (100);
    ADCMCTL0 |= ADCINCH_3;
    
    // ADCCTL0 |= ADCENC | ADCSC;
    while (ADCCTL1和 ADCBUSY);
    
    ADCMCTL0 |= ADCINCH_1;
    
    // ADCCTL0 |= ADCENC | ADCSC;
    while (ADCCTL1和 ADCBUSY); //等待 ADC 内核处于活动状态
    
    ADCMCTL0 |= ADCINCH_0;
    
    // ADCCTL0 |= ADCENC | ADCSC;
    while (ADCCTL1和 ADCBUSY);
    
    IR_SAMPLE = ADC_RESULT[1];
    I = ADC_Result [0];
    采样= ADC_Result [2];
    newsample =1;
    
    ADCCTL0 &=~ADCENC;
    
    ADCCTL0 |= ADCENC;
    
    
    
    如果(接收='A')
    {
    if (i<4095){
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF ='I';
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF = I & 0x00FF; //将数据加载到缓冲区中
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF =(I & 0xFF00)>>8;//MSB //将数据加载到缓冲区中
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF = SAMPLE & 0x00FF; //将数据加载到缓冲区中
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF =(采样和0xFF00)>>8;//MSB //将数据加载到缓冲
    区}
    }
    
    
    
    
    
    
    否则
    {
    // P2OUT &=~BIT2;
    SAC3OA &=~SACEN;
    SAC3DAC &=~DACEN;
    P2OUT |= BIT0;
    SAC1OA |= SACEN;
    SAC1DAC |= DACEN;
    SAC1DAT = ir_LED_level;
    SAC2DAT = ir_dc_offset;
    // SAC0DAT = ir_sample;
    P2OUT &=~BIT2;
    
    
    IS _IR = 1;
    
    
    
    //__delay_cycles (100);
    ADCMCTL0 |= ADCINCH_3;
    
    while (ADCCTL1和 ADCBUSY);
    
    ADCMCTL0 |= ADCINCH_1;
    
    while (ADCCTL1和 ADCBUSY);
    
    ADCMCTL0 |= ADCINCH_0;
    
    while (ADCCTL1和 ADCBUSY); //等待 ADC 内核处于活动状态
    
    
    
    
    VS_SAMPLE = ADC_RESULT[1]; //读取可见的 LED 结果
    I = ADC_Result [0];
    采样= ADC_Result [2];
    newsample =1;
    //启用下一个转换序列。
    //序列由 TB1启动
    ADCCTL0 &=~ADCENC;
    // while (ADCCTL1 & ADCBUSY);
    ADCCTL0 |= ADCENC; //采样和转换开始
    
    如果(接收='A')
    {
    if (i<4095){
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF ='V'; //将数据加载到缓冲区中
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF = I & 0x00FF; //将数据加载到缓冲区中
    
    while (!(UCA1IFG & UCTXIFG));
    
    UCA1TXBUF =(I & 0xFF00)>>8;//MSB //将数据加载到缓冲区中
    
    // while (!(UCA1IFG & UCTXIFG));
    
    // UCA1TXBUF =采样& 0x00FF; //将数据加载到缓冲区中
    
    // while (!(UCA1IFG & UCTXIFG));
    
    // UCA1TXBUF =(采样& 0xFF00)>>8;//MSB //将数据加载到缓冲
    区}
    
    
    
    
    
    }
    
    TB0CCTL0 &=~CCIFG;
    }
    
    // ADC 中断服务例程
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=ADC_vector
    __interrupt void ADC_ISR (void)
    #Elif defined (__GNU_)__=
    void _ attribute _adc (void
    
    )(void)(void adc)(void)(void)(void)(void)!
    #endif
    {
    switch (__evo_in_range (ADCIV、ADCIV_ADCIFG))
    {
    案例 ADCIV_NONE:
    中断;
    ADCIV_ADCOVIFG 案例:
    中断;
    案例 ADCIV_ADCTOVIFG:
    中断;
    ADCIV_ADCHIIFG 案例:
    中断;
    ADCIV_ADCLOIFG 案例:
    中断;
    ADCIV_ADCINIFG 案例:
    中断;
    ADCIV_ADCIFG 案例:
    ADC_Result = ADCMEM0;
    
    如果(s = 0)
    {
    S=2;
    
    SAC1DAT = 0;//关闭两个 LED
    SAC3DAT = 0;//
    
    if (is _IR=1)//
    {
    P2OUT |= BIT2;
    P2OUT &=~BIT0;
    }
    其他
    {
    P2OUT |= BIT0;
    P2OUT &=~BIT2;// P2.0 = 1
    }
    __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits);
    
    
    }
    其他
    {
    S-;
    }
    
    
    
    // P6OUT ^= BIT3;
    
    ADCIFG = 0;
    
    中断; //将 CPUOFF 位从0 (SR)清零
    //将 CPUOFF 位从0 (SR)清零
    默认值:
    中断;
    }
    }
    
    

    如下所示

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

    >ADCMCTL0 |= ADCINCH_3;

    "|="只能设置位、而不能清除位。 之后、您将始终采样 INCH=3。 此外、当 ENC=0时、您只能更改 INCH。

    ADCSHS_2指定一个定时器触发器、并且您正在使用 ADCSC、因此请使用 ADCSHS_0。

    我建议如下。 重复3次、使用不同的"i"值(通道编号):

    I = 3; // inch_3和 ADC_Result 索引
    ADCCTL0 &=~ADCENC; //禁用
    ADCMCTL0 =(ADCMCTL0 &~ADCINCH)| I;//我们知道英寸是 LSB
    ADCCTL0 |= ADCENC | ADCSC; //重新启用并启动另一个
    while (ADCCTL1 & ADCBUSY)/* empty*/;//等待它完成
    ADC_RESULSE[i]= ADCMEM0; //保存离开结果
    

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

    太棒了!!! 绝对精彩的建议!  

    我根本不能弄清楚这个解决方案。 我希望您的回答也能帮助他人!!

    再次感谢您。 继续保持良好的工作!