【蓝桥杯嵌入式拓展板】—双通道ADC采集 详解(附程序源码)

一、准备工作

[PA4->AO1]、[PA5->AO2] 转动RP5RP6可观察到测得AD值变化
【蓝桥杯嵌入式拓展板】—双通道ADC采集  详解(附程序源码)

二、原理图

【蓝桥杯嵌入式拓展板】—双通道ADC采集  详解(附程序源码)【蓝桥杯嵌入式拓展板】—双通道ADC采集  详解(附程序源码)

关于ADC采集详解,参考“STM32-ADC配置详解及应用。实例:《中断单通道读取ADC》、《DMA多通道读取ADC》”

链接:https://blog.csdn.net/qq_45689790/article/details/113862143

三、程序

1、static void ADCx_GPIO_Config(void)

static void ADCx_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(ADC_GPIO_1_CLK|ADC_GPIO_2_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;  //模拟输入
	
	GPIO_InitStruct.GPIO_Pin = ADC_GPIO_1_PIN;
	GPIO_Init(ADC_GPIO_1_PORT,&GPIO_InitStruct);  //PA4
	
	GPIO_InitStruct.GPIO_Pin = ADC_GPIO_2_PIN;
	GPIO_Init(ADC_GPIO_2_PORT,&GPIO_InitStruct); //PA5
}

2、static void ADCx_Config(void)

static void ADCx_Config(void)
{
	ADC_InitTypeDef ADC_InitStruct;
	
	RCC_APB2PeriphClockCmd(ADC_CLK,ENABLE);
	
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStruct.ADC_NbrOfChannel = 2;
	ADC_InitStruct.ADC_ScanConvMode = DISABLE;
	ADC_Init(ADC_x,&ADC_InitStruct);
	
	//配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	//这里,转换顺序都是配置1,其实写入2 也无所谓
	//在写读取函数的时候,重新配置转换顺序和转换速度,
	//ADC读取函数,每次读一个通道,到时候,一定要配置1,否则会出错
	ADC_RegularChannelConfig(ADC_x,ADCx_Channel_1,1,ADC_SampleTime_13Cycles5);
	ADC_RegularChannelConfig(ADC_x,ADCx_Channel_2,1,ADC_SampleTime_13Cycles5);
	
	ADC_Cmd(ADC_x,ENABLE);
	
	//初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADC_x);
	//等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_x));
	//ADC开始校准
	ADC_StartCalibration(ADC_x);
	//等待校准完成
	while(ADC_GetCalibrationStatus(ADC_x));
	
}

3、void ADCx_Init(void)

void ADCx_Init(void)
{
	ADCx_GPIO_Config();
	ADCx_Config();
}

4、uint16_t ADCx_Read(uint8_t channel)

uint16_t ADCx_Read(uint8_t channel)
{
	uint16_t ADC_Value = 0;
	
	ADC_SoftwareStartConvCmd(ADC_x,ENABLE);//ADC开始转换
	
	if(channel == 1)
	{
		ADC_RegularChannelConfig(ADC_x,ADCx_Channel_1,1,ADC_SampleTime_13Cycles5);
	}
	else if(channel == 2)
	{
		ADC_RegularChannelConfig(ADC_x,ADCx_Channel_2,1,ADC_SampleTime_13Cycles5);
	}
	
	while(ADC_GetFlagStatus(ADC_x, ADC_FLAG_EOC) == RESET); //等待转换完成
	ADC_Value = ADC_GetConversionValue(ADC_x);
	ADC_ClearFlag(ADC_x, ADC_FLAG_EOC);		//清除转换完成标志位
	
	ADC_SoftwareStartConvCmd(ADC_x, DISABLE);  //关闭ADC转换

	return ADC_Value;
}

5、"bsp_adc.h"

#ifndef _BSP_ADC_H
#define _BSP_ADC_H
#include "stm32f10x.h"

#define ADC_GPIO_1_PORT				GPIOA
#define ADC_GPIO_1_PIN				GPIO_Pin_4
#define ADC_GPIO_1_CLK				RCC_APB2Periph_GPIOA

#define ADC_GPIO_2_PORT				GPIOA
#define ADC_GPIO_2_PIN				GPIO_Pin_5
#define ADC_GPIO_2_CLK				RCC_APB2Periph_GPIOA

#define ADC_x						ADC1
#define ADC_CLK						RCC_APB2Periph_ADC1

#define ADCx_Channel_1		ADC_Channel_4
#define ADCx_Channel_2		ADC_Channel_5

void ADCx_Init(void);
uint16_t ADCx_Read(uint8_t channel);

#endif /*_BSP_ADC_H*/

6、main

uint16_t AD_val_1 = 0;
uint16_t AD_val_2 = 0;
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);  //1ms一次中断
	
	STM3210B_LCD_Init();
	LCD_Clear(White);
	STM3210B_LCD_Init();
	
	SEG_GPIO_Config();
	ADCx_Init();

	LCD_SetTextColor(White);
	LCD_SetBackColor(Blue);

	LCD_Clear(Blue);
	LCD_DisplayStringLine(Line1,(u8*)"      ADC DEMO     ");
	
	LCD_SetTextColor(Blue);
	LCD_SetBackColor(White);
	
	LCD_ClearLine(Line3);
	LCD_ClearLine(Line4);
	LCD_ClearLine(Line5);
	LCD_ClearLine(Line6);
	LCD_ClearLine(Line7);
	LCD_ClearLine(Line8);
	LCD_ClearLine(Line9);
	
	while(1)
	{
		
		AD_val_2 = ADCx_Read(2);
		AD_val_1 = ADCx_Read(1);
		
		sprintf(txt, "    AD_1:%3.2f",(float)AD_val_1/4096*3.3);
		LCD_DisplayStringLine(Line6,(uint8_t*)txt);
		sprintf(txt, "    AD_2:%3.2f",(float)AD_val_2/4096*3.3);
		LCD_DisplayStringLine(Line7,(uint8_t*)txt);
		
		Delay_Ms(200);

	}
}

欢迎交流探讨

上一篇:【进阶之路】Java的类型擦除式泛型


下一篇:基于51单片机的智能孵化器恒温箱 原理图PCB程序设计