[Lanqiao Cup Embedded Expansion Board]—Detailed explanation of dual-channel ADC acquisition (program source code attached)

1. Preparation

[PA4->AO1], [PA5->AO2] Rotate RP5 and RP6 to observe the changes in the measured AD value
Insert picture description here

Two, schematic diagram

Insert picture description hereInsert picture description here

For detailed explanation of ADC acquisition, refer to "Detailed STM32-ADC Configuration and Application. Examples: "Interrupt Single Channel Reading ADC", "DMA Multi-channel Reading ADC""

Link: https://blog.csdn.net/qq_45689790/article/details/113862143

3. Procedure

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;  //CMA可以多通道,实现数据寄存器对其,建议直接单通道读取
	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通道,这里即使你填 1 也不会出问题
	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);

	}
}

Welcome to exchange and discuss

Guess you like

Origin blog.csdn.net/qq_45689790/article/details/114153609