[STM32] ADC program example

00. Table of Contents

01. Introduction to ADC

STM32F4xx series generally have 3 ADCs. These ADCs can be used independently or in dual/triple mode (increased sampling rate). The ADC of STM32F4 is a 12-bit successive approximation analog-to-digital converter. It has 19 channels and can measure signals from 16 external sources, 2 internal sources and Vbat channels. The A/D conversion of these channels can be performed in single, continuous, sweep or discontinuous mode. The ADC result can be stored in the 16-bit data register in a left-justified or right-justified manner. The analog watchdog feature allows the application to detect whether the input voltage exceeds a user-defined high/low threshold.

STM32F407ZGT6 contains 3 ADCs. The maximum conversion rate of STM32F4 ADC is 2.4Mhz, that is, the conversion time is 0.41us (obtained under ADCCLK=36M, sampling period is 3 ADC clocks). Do not let the ADC clock exceed 36M, otherwise the accuracy of the result will decrease. .

STM32F4 divides ADC conversion into 2 channel groups: regular channel group and injection channel group. The regular channel is equivalent to your normal running program, and the injection channel is equivalent to interruption. When your program is executing normally, interrupts can interrupt your execution. Similar to this, the conversion of the injection channel can interrupt the conversion of the regular channel. After the injection channel is converted, the regular channel can continue to convert.

02. Hardware resources

The hardware resources used are:
1) Indicator light DS0
2) TFTLCD module
3) ADC
4) Dupont line

03. Programming ideas

①Turn on the PA port clock and ADC1 clock, and set PA1 as analog input.

RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

GPIO_Init ();

② Reset ADC1 and set ADC1 frequency division factor at the same time.

ADC_DeInit (ADC1);

③ Initialize the ADC_CCR register.

ADC_CommonInit();

④Initialize ADC1 parameters, set the working mode of ADC1 and related information of the rule sequence.

void ADC_Init(ADC_TypeDefADCx,ADC_InitTypeDef* ADC_InitStruct);*

⑤ Enable ADC.

ADC_Cmd(ADC1, ENABLE);

⑥Configure rule channel parameters:

ADC_RegularChannelConfig();

⑦Start software conversion: ADC_SoftwareStartConvCmd(ADC1);

⑧ Wait for the conversion to be completed and read the ADC value.

ADC_GetConversionValue(ADC1);

04. Program example

adc.h

#ifndef __ADC_H__
#define __ADC_H__

#include "sys.h"

//ADC通道初始化
void ADC1_Init(void);

//获取某个通道的值
u16 Get_Adc(u8 ch);

//获取某个通道给定次数采样平均值
u16 Get_Adc_Average(u8 ch, u8 times);

#endif/*__ADC_H__*/


adc.c


#include "adc.h"
#include "delay.h"


//ADC通道初始化
void ADC1_Init(void)
{
    
    
	GPIO_InitTypeDef gpio_InitTypeDef;
	
	ADC_InitTypeDef ADC_InitStruct;
	
	ADC_CommonInitTypeDef ADC_CommonInitStruct;
	
	//开启ADC1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	
	//开启GPIO时钟 PA5
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
	
	
	//GPIO初始化 初始化为模拟功能
	gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_5;
	gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_AN;
	gpio_InitTypeDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &gpio_InitTypeDef);
	
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);	  //ADC1复位
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);	//复位结束	
	
	
	//初始化ADC_CCR寄存器
	ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4;
	ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
	ADC_CommonInit(&ADC_CommonInitStruct);
	
	//初始化ADC1
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
	ADC_InitStruct.ADC_NbrOfConversion = 1;
	ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStruct.ADC_ScanConvMode = DISABLE;
	ADC_Init(ADC1, &ADC_InitStruct);
	
	//使能ADC
	ADC_Cmd(ADC1, ENABLE);
	
}

//获取某个通道的值
u16 Get_Adc(u8 ch)
{
    
    

	//设置ADC规则组通道 一个序列 采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles);
	
	//开启软件转换
	ADC_SoftwareStartConv(ADC1);
	
	//等待转换结束
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
		;

	//读取ADC的值
	return  ADC_GetConversionValue(ADC1);
}

//获取某个通道给定次数采样平均值
u16 Get_Adc_Average(u8 ch, u8 times)
{
    
    
	u32 tmp_val = 0;
	
	u8 i = 0;
	
	for (i = 0; i < times; i++)
	{
    
    
		tmp_val += Get_Adc(ch);
		delay_ms(5);
	}

	return tmp_val / times;
}

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "usmart.h"
#include "lcd.h"
#include "rtc.h"
#include "rng.h"
#include "key.h"
#include "wkup.h"
#include "adc.h"

int main(void)
{
    
     
	u16 value = 0;
	
	float temp = 0;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	
	delay_init(168);
	
	uart_init(115200);
	
	usmart_dev.init(84);

	
	LED_Init();
	
	
	LCD_Init();

	ADC1_Init();
	
		
	POINT_COLOR = RED;
	
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"ADC TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@tom");
	LCD_ShowString(30,110,200,16,16,"2020/09/10");	 
	
	//设置字体为蓝色
	POINT_COLOR = BLUE;
	LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");	 
	LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");	 
		
	while(1)
	{
    
    
		value = Get_Adc_Average(ADC_Channel_5, 20);
		
		//显示采样之后的原始值
		LCD_ShowxNum(134, 130, value, 4, 16, 0);
		
		temp = (float)value * (3.3 / 4096);
		value = temp;
		LCD_ShowxNum(134, 150, value, 1, 16, 0);
		
		//小数部分
		temp = temp - value;
		temp *= 1000;
		LCD_ShowxNum(150, 150, temp, 3, 16, 0x80);		
		
		LED1 = !LED1;
		
		delay_ms(250);
	}
}


05. Reserved

06. Appendix

6.1 [STM32] STM32 series tutorial summary

Website: [STM32] STM32 series tutorial summary

07. Statement

This tutorial refers to the "STM32 F4 Development Guide" of Punctual Atom

Guess you like

Origin blog.csdn.net/dengjin20104042056/article/details/108559310