[资料分享] msp430fr2311单片机adc序列通道采样

火辣西米秀   2020-8-9 22:18 楼主

使用P1.2、P1.3、P1.4、P1.5为采样通道,以demo的msp430fr231x_adc10_10.c文件为例。

1、将上述4个管脚配置为ADC模式:

P1SEL0 |= BIT2 + BIT3 + BIT4 + BIT5;

P1SEL1 |= BIT2 + BIT3 + BIT4 + BIT5;

2、查看资料可知,有4种adc采样模式,单通道单次,序列通道单次,单通道多次,序列通道多次;

本例选择序列通道单次,将ADCCT寄存器设为L1ADCCONSEQ_1;430读取通道数据时是由最高通道开始,直至A0,因此将ADCMCTL0设置为ADCINCH_5(通道5),

ADCMCTL0 |= ADCINCH_5; //参考电压为ADCC。

adc采样值保存在ADCMEM0寄存器中,类似串口接收区。当配置为序列通道时,循环读取ADCMEM的值,即为采样的数据。

注意:序列通道时,需要从最高通道一直读到通道0,总共6个通道。因此定义数组u16 ADC_Result[6],在ADC的中断处理函数中,进行赋值:

//初始化函数
void adc_init()
{
       // Configure ADC A0~2 pins
    P1SEL0 |= BIT2 + BIT3 + BIT4 + BIT5;
    P1SEL1 |= BIT2 + BIT3 + BIT4 + BIT5;

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

   // Configure ADC 
    ADCCTL0 |= ADCSHT_2 | ADCMSC | ADCON; // 16ADCclks, MSC, ADC ON
    ADCCTL1 |= ADCSHP | ADCCONSEQ_1 | ADCSSEL_1;   // ADC clock ACLK, sampling timer, s/w trig.,single sequence
    ADCCTL2 = ADCRES;   // 10-bit conversion results
    ADCMCTL0 |= ADCINCH_5;   // A5~2(EoS); Vref=avcc=3.3v
    ADCIE |= ADCIE0;       // Enable ADC conv complete interrupt    

      // Configure reference
    PMMCTL0_H = PMMPW_H;         // Unlock the PMM registers
    PMMCTL2 |= INTREFEN;          // Enable internal reference
    __delay_cycles(400);           // Delay for reference settling
    __no_operation();    
}


// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
    {
        case ADCIV_NONE: 
            break;                              
        case ADCIV_ADCOVIFG: 
            break;             
        case ADCIV_ADCTOVIFG: 
            break;            
        case ADCIV_ADCHIIFG: 
            break;             
        case ADCIV_ADCLOIFG: 
            break;             
        case ADCIV_ADCINIFG: 
            break;             
        case ADCIV_ADCIFG:
            ADC_Result = ADCMEM0;
            if(i == 0)
            {
                __bic_SR_register_on_exit(LPM0_bits);   // Exist LPM0
            }
            else
            {
                i--;
            }
            break;                                             
        default: 
            break; 
    }  
}

此时,ADC_Result[0]为通道0,ADC_Result[1]为通道1,依次。

3、采样值的转换

2311的ADC是10位的,参考电压为3.3V,因此

image.png
ADC_Result[6]定义为u16,不要定义为 u8 噢。

4、注意事项

上述设置,ADC完成单次转换后需要退出低功耗重新开启。在定时器或者while(1)中循环开启,

  while(ADCCTL1 & ADCBUSY);     // Wait if ADC core is active  
  ADCCTL0 |= ADCENC | ADCSC;    // Sampling and conversion start
  i = 5;  //数组索引重新赋值

在调试过程中,开始将 i=5 放在重新开启之前,发现数组中通道的数据会发生错位的现象,如通道3的数据在ADC_Result[2]中,本应在ADC_Result[3]中。放在此处更好!

5 后续
因选用的芯片fram太小了,没有对adc的采样数据进行平均化处理。
若需平均化,将采样模式配置为序列多次采样通道,ADCCONSEQ_3.
重复的次数在通过数据的大小来限制,定义 u16 ADC_Result[30], 执行ADC_Result = ADCMEM0, 当i=30时,跳出低功耗即可。
数组中存放的数据依次为[A5,A4,A3,A2,A1,A0,A5,A4,A3,A2,A1,A0,… ], 读者自己进行数据处理即可。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复