一、简述

        上两节课学习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,如果想要改变成电压的转换值可以加一套计算方式,具体计算方式的代码在上一节课的单通道的使用

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐