一.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