/******************************************************************* 内容:ADC配置,AIN0~AIN3 作者:Justice_Gao 日期:2017年7月15日 问题说明: 源代码程序的ADC采样使用的参考电压为内部参考电压1.2V,可测量的电压值范围为0~0.6V(参考电压/2), 这里我将提供ADC初始化设置,提供多种可测量电压值范围: a.0~0.6V,适用于AIN0~AIN3 b.0~1.2V,适用于AIN0~AIN3 c.0~3V,适用于AIN0和AIN1 d.0~6V,适用于AIN0和AIN1,需要注意的是,这两个ADC接口最大容忍电压为5V *******************************************************************/ /************************************************************************ ADC的初始化程序和转换程序在adc.c文件中,我们只需要修改ADC_StartConvert函数中几条语句就可以实现,程序如下 void ADC_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass) { uint32_t ctrl_tmp; /* Clear the ADC done flag */ ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF); /* Insert channel selection */ ctrl_tmp = MXC_ADC->ctrl; ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_CHSEL); ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (0x00000004UL<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));//只需要改0x00000004UL,这里选择模式4,AIN0/5 /* Clear channel configuration */ ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_REFSCL | MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_BUF_BYPASS); /* ADC reference scaling must be set for all channels but two*/ if ((channel != ADC_CH_VDD18) && (channel != ADC_CH_VDD12)) { //ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL; //如果不注释,则内部参考电压为0.6V,注释掉,内部参考电压为1.2V } /* Finalize user-requested channel configuration */ if (adc_scale || channel > ADC_CH_3) { ctrl_tmp |= MXC_F_ADC_CTRL_ADC_SCALE; } if (bypass) { ctrl_tmp |= MXC_F_ADC_CTRL_BUF_BYPASS; } /* Write this configuration */ MXC_ADC->ctrl = ctrl_tmp; /* Start conversion */ MXC_ADC->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START; }
以上程序是0~6V测量范围的配置,下面总结一下常用到的配置
(1)0~0.6V测量范围,x=0x00000000UL/0x00000001UL/0x00000002UL/0x00000003UL
ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (x<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
(2)0~3V测量范围,x=0x00000004UL/x=0x00000005UL
ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (x<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
(3)0~1.2V,x=0x00000000UL/0x00000001UL/0x00000002UL/0x00000003UL
ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (x<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
//ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
(4)0~6V测量范围,x=0x00000004UL/x=0x00000005UL
ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (x<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
//ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
如果同时使用两个ADC的话,上面的1个函数就不适用了,所以我们将函数改一下,将x作为形参输入,优化后的函数如下: void ADC_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass, uint32_t mode) { uint32_t ctrl_tmp; /* Clear the ADC done flag */ ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF); /* Insert channel selection */ ctrl_tmp = MXC_ADC->ctrl; ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_CHSEL); ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (mode<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));//只需要改0x00000004UL,这里选择模式4,AIN0/5 /* Clear channel configuration */ ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_REFSCL | MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_BUF_BYPASS); /* ADC reference scaling must be set for all channels but two*/ if ((channel != ADC_CH_VDD18) && (channel != ADC_CH_VDD12)) { //ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL; //如果不注释,则内部参考电压为0.6V,注释掉,内部参考电压为1.2V } /* Finalize user-requested channel configuration */ if (adc_scale || channel > ADC_CH_3) { ctrl_tmp |= MXC_F_ADC_CTRL_ADC_SCALE; } if (bypass) { ctrl_tmp |= MXC_F_ADC_CTRL_BUF_BYPASS; } /* Write this configuration */ MXC_ADC->ctrl = ctrl_tmp; /* Start conversion */ MXC_ADC->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START; }
弄清楚这些之后,写主函数程序就很简单了,只要几条语句,如下:
int main(void) { uint16_t adc_val[1]; /* Initialize ADC */ ADC_Init(); while(1) { ADC_StartConvert(ADC_CH_0, 0, 1, 4);//调用优化后的ADC启动函数 overflow[0] = (ADC_GetData(&adc_val[0]) == E_OVERFLOW ? 1 : 0); } } [color=#ff0000]需要注意的是,不同于STM32F4的ADC转换,这里采集一次数据,就要重新调用ADC_StartConvert,所以这里在while(1)一直循环[/color] *************************************************************************************/