蓝桥杯嵌入式学习之双路AD采集

硬件电路
蓝桥杯嵌入式学习之双路AD采集_第1张图片
排针帽
蓝桥杯嵌入式学习之双路AD采集_第2张图片
程序

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.如果采集不要太精准和稳定,则冒泡排序的算法可以不用使用

你可能感兴趣的:(蓝桥杯嵌入式)