STM32:ADC单通道(内含:1.实物图/接线图+2.代码部分如下+3.AD用到的库函数总结)

简介: STM32:ADC单通道(内含:1.实物图/接线图+2.代码部分如下+3.AD用到的库函数总结)

1.接线图:


6bf474caa4834766854041c1a9bae66a.png


电位器中间的扭头往左拧,电阻器向左;往右拧,电阻器向右。输出电压即为可调电压。接在PA0(引脚定义图可知,PA0~PB1的十个引脚是ADC的十个通道,可任选接哪个)。


实物图如下:


83dd0c168cc24616a962e101a1e83fe6.png


注:蓝色的电位器要把三个引脚的插在面包板上侧。


2.代码部分如下:


主函数部分:(main.c)


35cddd8d91514adbb2c38d254e4f7687.png


#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");//显示AD值(0~4095)
    OLED_ShowString(2,1,"Voltage");//显示电压值(0~3.3V)
    while(1)
    {
        ADValue=AD_GETValue();//启动等待读取
        Voltage=(float)ADValue/4095*3.3;//将ADValue的0~4095变为0~3.3V
        OLED_ShowNum(1,9,ADValue,4);
        OLED_ShowNum(2,9,Voltage,1);//只会显示整数的部分,因为该OLED没小数点,需要自行计算小数点部分
    OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//浮点数不能取余,需要强制类型转换
        Delay_ms(100);//刷新/持续时间
    }
}

//现象:OLED上有AD值,并且左拧数据减小,右拧数据增大。

//注:AD的个位可能会持续跳动,属于正常现象,如果在固定场合规定不能跳动,如AD高于某一值就亮灯,低于就灭灯,

//就会导致频繁的亮灭,因此,可以:1.设置阈值,超过某一值灯就亮,低于某一值灯就灭。2.滤波。3.裁剪分辨率


AD.c部分如下:


f2cb0d5316b74432a4094d8feb881fba.png

c6cb8f23bd21454db1e79d7ea92addb5.png


#include "stm32f10x.h"                  // Device header
//思路如下:(参照ADC基本结构图)
//1.开启RCC时钟,包括ADC和GPIO的时钟,配置ADCCLOCK的分频器
//2.配置GPIO为模拟输入模式
//3.配置多路开关通道,把左边的通道(如GPIO)接到右边的规则组里
//4.配置ADC转换器,用结构体(中断和模拟看门狗,此处用不到,就不写,用到的话可以写)
//(参数决定ADC是单次转换还是连续转换,扫描还是非扫描,有几个通道,触发源是什么,数据对齐是左对齐还是右对齐)
//5.调用ADC_Cmd进行开关控制
//6.校准4函数
void AD_Init(void)
{
    //1.开启RCC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//对APB2进行6分频
    //2.配置GPIO为模拟输入模式(可复制LED.c初始化部分代码)
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//AIN是ADC专属模式(模拟输入模式下,GPIO无效,防止对ADC产生干扰)
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//PA0口初始化为模拟输入的引脚
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //3.选择输入通道
    ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1,ADC_SampleTime_55Cycles5);//在规则组列表的第一个位置写入通道0
    //参数二:选择通道0,   参数三:序列1~16之间的一个数    参数四:指定通道的采样时间(转换快选择参数,稳定选大参数)
    //4.用结构体初始化ADC(单次转换非扫描)
    ADC_InitTypeDef ADC_InitStructure;
    ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//选择连续转换(ENABLE)还是单次转换(DISABLE)
    ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐(右对齐:ADC_DataAlign_Right)
    ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
                            //外部触发源选择(不使用外部触发,使用软件触发:ADC_ExternalTrigConv_None)
    ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式,选择是单ADC模式(ADC_Mode_Independent)or双ADC模式
    ADC_InitStructure.ADC_NbrOfChannel=1;//写几就几个通道起作用
    ADC_InitStructure.ADC_ScanConvMode=DISABLE;//选择扫描模式(ENABLE)还是非扫描模式(DISABLE)
    ADC_Init(ADC1,&ADC_InitStructure);
    //5.调用ADC_Cmd进行开关控制
    ADC_Cmd(ADC1,ENABLE);
    //6.校准4函数
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1)==SET);//是SET就循环,不是就跳出了
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1)==SET);
}
//启动转换获取结果函数
//思路:软件触发转换+ 等待转换完成,即等待EOC等于一  +读取ADC数据寄存器(参照转换模式图)
uint16_t AD_GETValue(void)
{
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);//放在这里表示是单次转换,需要反复触发
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//获取标志位状态函数,此处第二个参数选择规则转换完成标志位
    //第二个参数可填:ADC_FLAG_AWD(模拟看门狗),ADC_FLAG_EOC(规则转换完成标志位),ADC_FLAG_JEOC(注入组转换完成标志位)
    //ADC_FLAG_JSTRT(注入组开始转换标志位),ADC_FLAG_STRT(规则组开始转换标志位)
    return ADC_GetConversionValue(ADC1);//ADC获取转换值
}

AD.h代码如下:


22f0a4d11f504865a5eac8d44583bcc8.png


#ifndef  __AD_H
#define  __AD_H
void AD_Init(void);
uint16_t AD_GETValue(void);
#endif

3.AD用到的库函数总结


//ADCCLK相关配置函数(在rcc.h里):

//void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);//配置ADCCLK分频器,对APB2的72MHz时钟选择2,4,6,8分频,输入到ADCCLK

//ADC相关库函数(在adc.h里):

//void ADC_DeInit(ADC_TypeDef* ADCx);//恢复出厂配置

//void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//初始化

//void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);//配置结构体

//void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//给ADC上电,即最后一步的开关控制

//void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//开启DMA输出信号

//void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断输出控制


//以下为控制校准相关函数:

//void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准

//FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准状态,等待校准完成

//void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始校准

//FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取开始校准状态,等待校准完成


//void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC软件开始转换控制--触发控制的软件触发

//FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);//获取标志位状态,转换结束EOC置1


//以下为配置间断模式相关函数:

//void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);//每个几个通道间断一次

//void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//是否启用间断模式


//void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

//ADC规则组通道配置,给序列的每个位置填写指定通道(重点)

//参数二:ADC_Channel为指定的通道;   参数三:ADC_Channel序列几;   参数四:ADC_SampleTime指定通道的采样时间


//void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//判断是否允许ADC外部触发转换


//uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换值,读取结果时使用该函数。(重点)

//uint32_t ADC_GetDualModeConversionValue(void);//获取双模式转换结果


//FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获取标志位状态

//void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//清楚标志位

//ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);//获取中断状态

//void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);//清除中断挂起位


相关文章
|
6月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
478 2
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
800 0
|
5月前
|
芯片
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
305 0
|
5月前
|
传感器 编解码 IDE
STM32CubeMX ADC采集光照和电压
STM32CubeMX ADC采集光照和电压
266 3
|
6月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
539 4
|
6月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
802 2
|
6月前
|
存储 数据采集 数据安全/隐私保护
使用STM32F103读取TF卡并模拟U盘:使用标准库实现
通过以上步骤,你可以实现用STM32F103将TF卡内容变成U盘进行读取。这种功能在数据采集、便携式存储设备等应用中非常有用。如果你有更多的需求,可以进一步扩展此项目,例如添加文件管理功能、加密存储等。希望这篇博客能帮到你,如果有任何问题,欢迎在评论区留言讨论!
272 1
|
6月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
651 1
|
5月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
208 0
|
6月前
|
存储 数据安全/隐私保护 芯片
【STM32】详解嵌入式中FLASH闪存的特性和代码示例
【STM32】详解嵌入式中FLASH闪存的特性和代码示例