初学者STM32—ADC(标准库)多通道使用
摘要:本课程讲解了STM32 ADC多通道的使用方法。通过连接光敏、热敏、红外传感器和电位器到PA1-PA3引脚,采用单次转换非扫描模式,逐个通道进行触发、等待和读取。实现关键是将通道配置移入AD_GetValue()函数,通过传入不同通道参数实现多通道转换。代码演示了初始化ADC、校准和四个通道的轮询读取,并将转换结果显示在OLED上。相比单通道模式,该方法通过修改通道参数实现了灵活的多通道数据
·
一、简述
上两节课学习ADC的基本原理以及ADC的基本结构、单通道的使用,本节课主要学习ADC多通道的使用,理解掌握多通道的基本使用方法。
二、基本步骤
1、连线

本次多通道的使用采用了光敏传感器、热敏传感器、反射式红外传感器,保留了上一节课的电位器。三个传感器的AO口分别接入PA1、PA2、PA3。
2、主要思路

采用单次转换,非扫描模式
转换思路:先将一个通道进行转换,假设是通道0,进行触发、等待、读值,然后,更改通道,通道1,继续经行触发、等待、读值。这样就完成了。
3、实现方法
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
//对一个通道进行转换
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
将主函数选择的通道传入 AD_GetValue()这个函数中,然后对这个通道进行转换。
而对比单通道,就是在配置通道这个函数放在了AD_GetValue()这个函数当中,给这个函数提供了填入通道的更能让单次转换变成了多次转换。
4、效果演示

三、完整代码
AD.c
#include "stm32f10x.h" // Device header
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //开启RCC时钟ADC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启GPIO时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72Mhz/6=12Mhz
GPIO_InitTypeDef GPIO_InitStructure; //通过结构体配置GPIO模式
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //配置为模拟输入模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
// ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //复位校准
while(ADC_GetCalibrationStatus(ADC1) == SET); //返回复位校准状态
ADC_StartCalibration(ADC1); //开始校准
while(ADC_GetCalibrationStatus(ADC1) == SET);
}
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
//对一个通道进行取值
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
AD.h
#ifndef __AD_H
#define __AD_H
void AD_Init(void);
uint16_t AD_GetValue(uint8_t ADC_Channel);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
uint16_t AD_Value0,AD_Value1,AD_Value2,AD_Value3;
float Voltage;
int main(void)
{
AD_Init(); //AD转换初始化函数
OLED_Init(); //初始化OLED
OLED_ShowString(1,1,"AD0:");
OLED_ShowString(2,1,"AD1:");
OLED_ShowString(3,1,"AD2:");
OLED_ShowString(4,1,"AD3:");
while(1)
{
AD_Value0=AD_GetValue(ADC_Channel_0);
AD_Value1=AD_GetValue(ADC_Channel_1);
AD_Value2=AD_GetValue(ADC_Channel_2);
AD_Value3=AD_GetValue(ADC_Channel_3);
OLED_ShowNum(1,5,AD_Value0,4);
OLED_ShowNum(2,5,AD_Value1,4);
OLED_ShowNum(3,5,AD_Value2,4);
OLED_ShowNum(4,5,AD_Value3,4);
Delay_ms(100);
}
}
转换出来的值实际上是0~4095,如果想要改变成电压的转换值可以加一套计算方式,具体计算方式的代码在上一节课的单通道的使用
更多推荐



所有评论(0)