ADC单通道与多通道

一.ADC基本信息

ADC就是将模拟数值转化成数字
ADC时钟分频2/4/6/8对应就是72M/2 72M/4  72M/6  72M/8即36M 18M 12M 9M
ADC_Mode_ALN模拟输入模式是ADC专属模式

二.ADC流程

开启时钟

RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1,ENABLE);//ADC选择APB2时钟
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);//GPIOA选择APB2时钟

设置ADC时钟

RCC_ADCCLKConfig (RCC_PCLK2_Div6);

这里可以选择2,4,6,8分频我用的6分频就是72MHz/6=12MHz

初始化GPIO

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_Mode_AIN数字模拟输入,引脚选择,速度配置

ADC规则通道配置

ADC_RegularChannelConfig (ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);

这里我使用通道0,一个通道数,55.5采样时间

初始化ADC

ADC_InitTypeDef ADC_InitStructure;

对齐模式,连续模式选择,扫描模式选择,通道选择,外部触发沿选择,通道数配置

这里主要是连续模式与单次模式区分;扫描与非扫描模式区分

连续模式就是一个通道完成直接到下一个通道

单次就是一个通道一个通道完成

非扫描模式就是一个通道里面完成一个数据

扫描模式就是一个通道可以完成多个数据

ADC使能
ADC校准

 ADC_ResetCalibration (ADC1);//复位校准
 while (ADC_GetResetCalibrationStatus (ADC1) == SET);//获取复位校准状态
 ADC_StartCalibration (ADC1);//开始校准
 while(ADC_GetCalibrationStatus (ADC1) == SET);//获取校准状态

三.代码实现

1.AD单通道

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t ADValue;
float Voltage;

int main(void)
{
	OLED_Init ();
	AD_Init ();
	
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(2,1,"Voltage:0.00V");
	
	while(1)
	{
		ADValue = AD_GetValue();//AD获取值:将AD获取值赋值给ADValue,AD最大值为4095
		Voltage = (float)ADValue / 4095 * 3.3;//电压值:将获取值ADValue/(AD最大值*3.3V)就能得到电压变化值
		
		OLED_ShowNum(1,9,ADValue,4);//OLED显示AD值
		OLED_ShowNum(2,9,Voltage,1);//OLED显示小数点前的值
		OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100, 2);//算出小数点后面值
		
		Delay_ms(100);
    }
}

AD.c

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	//开启时钟
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1,ENABLE);//ADC选择APB2时钟
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);//GPIOA选择APB2时钟
	
	//设置ADC时钟
	RCC_ADCCLKConfig (RCC_PCLK2_Div6);//选择6分频也就是72MHz/6=12MHz
	
	//初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN ;//ADC选择模拟输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//引脚PA0
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;//速度50
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//配置ADC规则通道
	ADC_RegularChannelConfig (ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//使用通道0, 使用一个,采样时间55.5
	
	//初始化ADC
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode =ADC_Mode_Independent;//独立模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//不使用连续转换(单次转换)
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不开启外部触发(软件触发)
	ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数量1
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;//不扫描
	ADC_Init(ADC1,&ADC_InitStructure);
	
	//ADC使能
	ADC_Cmd(ADC1,ENABLE);
	
	//ADC校准(固定使用)
	ADC_ResetCalibration (ADC1);//复位校准
	while (ADC_GetResetCalibrationStatus (ADC1) == SET);//获取复位校准状态
	ADC_StartCalibration (ADC1);//开始校准
	while(ADC_GetCalibrationStatus (ADC1) == SET);//获取校准状态
}

//获取ADC转换函数
uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd (ADC1,ENABLE);//AD开始转换
	while(ADC_GetFlagStatus (ADC1,ADC_FLAG_EOC) == RESET);//获取EOC标志位值,完成AD转换
	return ADC_GetConversionValue (ADC1);//获取ADC1转换值
}

AD.h

#ifndef _AD_H
#define _AD_H

void AD_Init(void);
uint16_t AD_GetValue(void);

#endif

2.AD多通道

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t AD0,AD1,AD2,AD3;//定义AD变量


int main(void)
{
	OLED_Init ();
	AD_Init();
	
	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD1:");
	OLED_ShowString(4,1,"AD1:");
	
	while(1)
	{
        AD0 = AD_GetValue(ADC_Channel_0);
		AD1 = AD_GetValue(ADC_Channel_1);
		AD2 = AD_GetValue(ADC_Channel_2);
		AD3 = AD_GetValue(ADC_Channel_3);
		
		OLED_ShowNum(1,5,AD0,4);
		OLED_ShowNum(2,5,AD1,4);
		OLED_ShowNum(3,5,AD2,4);
		OLED_ShowNum(4,5,AD3,4);
		
		Delay_ms(100);
    }
}

AD.c

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{ 
	//开启时钟
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1,ENABLE);//开启ADC时钟
    RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO时钟
	
	//设置ADC时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟分频,6分频
	
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;//引脚PA0-3
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	//ADC初始化
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//没有外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续转换失能
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描模式失能
	ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数为1
	ADC_Init(ADC1, &ADC_InitStructure);
	
	//ADC使能
	ADC_Cmd(ADC1,ENABLE);//开启ADC
	
	//ADC校准
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
	
}
//定义AD获取值
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1,ADC_Channel, 1 ,ADC_SampleTime_55Cycles5);//将所有的规则通道放在这里
	//ADC规则通道以及采样时间55.5
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发AD转换
	while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//等待EOC获取,AD转换结束
	return ADC_GetConversionValue(ADC1);//读取AD转换值
}
//转换-获取-读取

AD.h

#ifndef _AD_H
#define _AD_H

void AD_Init(void);
uint16_t AD_GetValue(uint8_t ADC_Channel);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值