一、准备工作
[PA4->AO1]、[PA5->AO2] 转动RP5、RP6可观察到测得AD值变化
二、原理图
关于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; //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);
}
}
欢迎交流探讨