ADC_Mode 设置ADC 工作在独立或者双ADC 模式。
ADC_Mode 描述
1.ADC_Mode_Independent ADC1 和ADC2 工作在独立模式
2.ADC_Mode_RegInjecSimult ADC1 和ADC2 工作在同步规则和同步注入模式
3.ADC_Mode_RegSimult_AlterTrig ADC1 和ADC2 工作在同步规则模式和交替触发模式
4.ADC_Mode_InjecSimult_FastInterl ADC1 和ADC2 工作在同步规则模式和快速交替模式
5.ADC_Mode_InjecSimult_SlowInterl ADC1 和ADC2 工作在同步注入模式和慢速交替模式
6.ADC_Mode_InjecSimult ADC1 和ADC2 工作在同步注入模式
7.ADC_Mode_RegSimult ADC1 和ADC2 工作在同步规则模式
8.ADC_Mode_FastInterl ADC1 和ADC2 工作在快速交替模式
9.ADC_Mode_SlowInterl ADC1 和ADC2 工作在慢速交替模式
10.ADC_Mode_AlterTrig ADC1 和ADC2 工作在交替触发模式
具体的ADC配置可以参考下面大佬
https://blog.csdn.net/qwq1503/article/details/96108617
ADC初始化配置函数
void ADC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //蓝桥杯扩展板因为都是ADC1采集,所以配置独立通道即可
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2; //双路AD采集通道
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
ADC采集的数值的获取
u16 Get_ADCs(u8 channel)
{
u16 ADC_Val = 0;
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
ADC_Val = ADC_GetConversionValue(ADC1);//返回最近一次ADCx 规则组的转换结果
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
return ADC_Val;
}
如果想要采集ADC的值更加的稳定,精度更高,可以写一个算法提高采集的精度,但是如果没有其实影响也不大,主要是比赛时候敲下面的代码也需要花费一些时间,平时练习即可帮组了解这些算法的用途。
冒泡排序法如下
//采用冒泡排序法,提高采集的精度
u16 Get_Filter(u8 channel)
{
u16 tmp;
u8 i = 0,j = 0;
for(i=0; i<ADC_BUFF_LEN; i++)
{
adc_buff[i] = Get_ADCs(channel);
}
for(i=0; i<=ADC_BUFF_LEN-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
{
for(j=0; j< ADC_BUFF_LEN-i-1; j++)/* 内循环为每趟比较的次数,第i趟比较len-i次 */
{
if(adc_buff[j+1] < adc_buff[j])/* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
{
tmp = adc_buff[j+1];
adc_buff[j+1] = adc_buff[j];
adc_buff[j] = tmp;
}
}
}
//判断循环的次数的奇偶次数
if(ADC_BUFF_LEN % 2 == 0)
{
return(adc_buff[ADC_BUFF_LEN/2-1] + adc_buff[ADC_BUFF_LEN/2])/2;//循环偶数次就保留中间俩个数字
}
else
{
return(adc_buff[ADC_BUFF_LEN/2]);//奇数次就返回中间一个数
}
}
主函数
ADC_Config();//ADC配置的初始化
while(1)
{
x = Get_ADCs(ADC_Channel_4);
y = Get_ADCs(ADC_Channel_5);
snprintf((char *)str, sizeof(str), " VRp5:%3.2fV", x/4095.*3.3);
LCD_DisplayStringLine(Line6, str);
snprintf((char *)str, sizeof(str), " VRp6:%3.2fV", y/4095.*3.3);
LCD_DisplayStringLine(Line7, str);
Delay_Ms(200);
}
总结:
1.扩展板上的俩路ADC配置和单独的ADC的初始化配置没有太大的区别,注意的一点就是ADC_InitStructure.ADC_NbrOfChannel = 2俩个通道
2.如果采集不要太精准和稳定,则冒泡排序的算法可以不用使用