使用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,因此
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,… ], 读者自己进行数据处理即可。