stm32-ADC实际应用

MCU ADC采样值转换成电压值详解

ADC外设相关的一些基础知识:

1、读取ADC模块采样值时将会读取到什么值?

2、读取到的采样值怎么换算成实际的电压值?

3、ADC模块参考电压是什么?

4、ADC模块的输入电压范围是多大?

如何利用单片机的ADC模块(或者独立的ADC芯片)得到接入ADC管脚上的实际电压值?
  这个问题,是第一次接触ADC时候,大家都会遇到的问题。
一、Q:会读到什么值?(满量程:能读到最高分辨率
  单片机会读到什么值?需要看一个特性,就是几位的ADC,在手册上就会给出,例如,STM32的ADC是12位的。另外,还有8位,10位,16位,24位等。
  我先告诉你答案:STM32读到的ADC值,是从0到4095,当你把ADC引脚接了GND,读到的就是0,当你把ADC引脚接了VDD,读到的就是4095。
  接下来告诉你为什么:前面提到,STM32的ADC是12位的,我们知道,8位的值是从0-255;16位的值,是从0~65535。这两个位的最大值,是我们最为熟悉的。
(怎么算出来的?这问题就又降低到另一个层面了,这里我们说的几位的值,每个位只能是0或者1,比如2位的值,可以表示为00 01 10 11四种不同的值,这是以2进制表示的,转换成十进制就是0 1 2 3,所以得出结论,2位的值可以表示从0-3。同理,3位的值,可以表示十进制的0-9,你可以展开计算一下。4位的值,可以表示0-16,5位的值,可以表示从0~31,同理,你可以得出任意位的值可以表示的范围。)
  所以,12位的值,可以表示从0~4095,这就是先在感性上,认识了为什么12位的ADC的值,是从0-4095.

二、Q:读到的值怎么换算成实际的电压值
  前面提到了,我们输入GND,读到的值是0,输入VDD,得到的值是4095,那么,当你读到2035的时候,你知道输入电压多少V吗?这个问题,归根结底,就到了数学XY坐标,已知两点坐标值(0,0)(3.3,4095),给出任意X坐标值,求Y值的问题了吧?简单不简单?
ADC测电压2-2

三、Q:参考电压是什么(注意最高电压,别误烧了目前用的IC)
  讨论这个问题之前,你先拿万用表量一下你的VDDA的实际电压是多大?是不是标准的3.300V?应该不是吧?或许是2.296V,或许是3.312V。然后你把VDD连接到ADC引脚之后,得到的是4095,也就是,实际上,当你读出4095这个数据的时候,实际的电压值不是你想象中的3.300V。有些初学者,觉得几毫伏的电压差无所谓,但实际应用中,几毫伏就可能代表很大的实际工况,例如,在一个量程为50克的电子称上。
  所以,这时候,芯片厂商就想了一个办法,给ADC模块中引入参考电压,由非常标准的参考电压芯片来接入参考电压引脚。标准的电压芯片,我们一般叫做参考电压芯片,或者叫做基准电压芯片。例如REF3133(输出3.300V) REF3025(输出2.500V)等等。
注意:STM32 的100脚以上(含100脚)有参考电压引脚。在没有参考电压引脚的单片机上,可以把基准电压芯片接入VDDA,但是VDDA和VDD的电压差不能超过0.3V,例如,VDD是3.3V的话,可以给VDDA接入一个3.3V的参考电压芯片或者3.0V的参考电压芯片,但是不能接入2.5V的参考电压芯片,后果就是芯片不能工作。

四、Q:ADC引脚的输入电压范围是多大
  一般情况下,ADC引脚的输入电压,是从0VDD,如果有REF引脚,一般是0Vref,也有0~2Vref的情况。
  如果被测的电压大于ADC的输入电压,例如,要用STM32测量0~5V的电压的话,可以在输入ADC引脚之前,加入电阻分压和放大器电路。

五,比如你ADC值为0x80,那么实际值就是0x80/(0xFF+1)*3.3V = 1.65V。

Vadc=R2/(R1+R2)*Vinput

以下资料整理于网上
电阻分压采样电路图汇总(三款电阻分压采样电路设计原理图详解)

电阻分压采样电路图(一)
  音量控制的实质是由电阻构成的分压电路,其原理就是电阻串联分压的知识,其典型的电路如图1-1。

电阻分压采样电路图汇总(三款电阻分压采样电路设计原理图详解)
请添加图片描述

输入电路由信号源Ui、电阻R1和电阻R2构成。分压电路输出电压U0算公式为
 请添加图片描述
从公式可以看出,由于分母R1+R2大于R2,所以输出电压小于入电压。也就是说分压电路是一个对输入信号进行衰减的电路。我们可以通过改变R1或R2的大小来改变输入电压U0的大小。

下分压电阻R2大小对输出电压变化的影响:

输入电压Ui和R1不变时,如果R2增大,输出电压将增大;R2减小,输出电压也将减少。

上分压电阻R1大小对输出电压变化的影响:

输入电压Ui和R2不变时,如果R1增大,输出电压将减小;R1减小,输出电压将增大。

带负载的电阻分压电路
  图1-2是带有负载的电阻分压电路,电路中的RL是负载电路,他可以是一个电阻也可以是一个电路。
请添加图片描述
其工作原理和上面介绍的一样,只不过是现在分析电路时要将R2和RL并联后的阻抗作为下分压电阻。此时,负载电阻的值越小,负载越重。负载越重,分压电路的输出电压下降的量就越大。

音量电位器阻值变化的原理

音量电位器在电路中相当于电阻的一个分压电路,图1-3为音量电位器与电阻分压电路之间的等效电路图,其中RP1为音量电位器。

请添加图片描述
  转动电位器的转柄时,动片再电阻体上滑动,动片到两个定片的阻值大小也随之变化。电位器在电路中相当于两个电阻构成的串联电路,动片将电位器的阻体分为两个电阻R1和R2,组成电阻分压电路,在音量控制电路中常用到此器件。

单声道音量控制器

单声道音量控制器是各种音量控制器的基础,图1-4是单联电位器构成的的单声道音量控制电路,它实际上是一个电阻分压电路,电位器RP1相当于两个分压电阻。请添加图片描述
图中的电位器RP1用于音量控制电路,所以又叫音量电位器。BL1是扬声器,它的作用是把电信号转化成声音。功率放大器的作用是把对RP1动片的输出信号进行放大,再推动扬声器BL1工作。

电阻分压采样电路图(二)
  AD通过分压电阻采样
  请添加图片描述

电阻分压采样电路图(三)
  对于异步电机调速系统来说,环球电机速度检测的正确和精度将是调速系统稳定性和控制精度的关键。为了使系统具有良好的稳定性和较宽的调速范围,本系统采用增里式光电编码器来检测异步电机的速度,事件管理器中,集成有正交编码脉冲电路能够接受光电编码器发出的正交编码脉冲信号,通过检测正交编码脉冲信号便可测出电机的速度和运动方向。系统选用定时器作为的时基,定时器工作模式设为增减计数模式,正交编码脉冲作为的时钟源。
请添加图片描述
辅助电源是控制系统必不可少的一部分,小编为了确保能为控制系统提供可靠稳定的电源,辅助电源设计选用线性电源。其工作原理是工频交流电经降压变压器降压后再经整流滤波电路,得到直流电压再经三端稳压芯片得到所需的电源电压。

请添加图片描述
两相交流电机变频调速控制系统的硬件总体框图,包括以三菱作为功率模块的主电路、以为控制核心的外围基本电路,小编详细介绍了直流母线欠过压保护电路、电流采样电路、速度采样电路以及按键显示电路的设计过程。软件和硬件是异步电机变频调速系统的两大组成部分,硬件是调速系统的基础,软件是调速系统的核心。系统控制能力的优劣主要取决于软件的可靠性和通用性,两相交流电机变频调速系统的软件需要满足实时性、可靠性和通用性。为了提高软件效率,系统软件使用汇编语言来编写。

  • 5
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在STM32上使用ADC模块采集模拟量,你可以按照以下步骤进行配置和编程: 1. 打开STM32CubeMX并创建一个新项目。 2. 选择适当的MCU型号,并启用所需的ADC功能。 3. 在"Pinout & Configuration"选项卡中,为ADC选择适当的引脚。 4. 在"Configuration"选项卡中,配置ADC采样精度、采样周期等参数。 5. 在"Project"选项卡中,选择生成代码的目标IDE和语言。 6. 点击"Project Settings"按钮,设置生成代码的存储路径和其他选项。 7. 点击"Code Generator"选项卡,选择生成代码的类型(HAL库或LL库)。 8. 点击"Generate Code"按钮,生成代码并打开所选的IDE。 在生成的代码中,你可以使用适当的API函数来配置和使用ADC模块。如果你选择了HAL库,以下是一个简单的示例代码: ```c #include "stm32f4xx.h" #include "stm32f4xx_hal.h" ADC_HandleTypeDef hadc1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); int main(void) { // STM32初始化代码 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); // 启动ADC转换 HAL_ADC_Start(&hadc1); while (1) { // 等待ADC转换完成 HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // 读取ADC转换结果 uint32_t adcValue = HAL_ADC_GetValue(&hadc1); // 处理ADC转换结果 // ... } } void SystemClock_Config(void) { // 系统时钟配置 // ... } static void MX_GPIO_Init(void) { // GPIO初始化 // ... } static void MX_ADC1_Init(void) { // ADC初始化 hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.NbrOfDiscConversion = 0; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; HAL_ADC_Init(&hadc1); // 配置ADC通道 ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig); } ``` 上述代码中,我们使用了ADC1模块进行模拟量的采集。在`MX_ADC1_Init()`函数中,我们对ADC进行了初始化,并配置了ADC的参数,如时钟预分频、分辨率、转换模式等。然后,我们配置了ADC通道,选择了要采集的模拟量输入通道(例如ADC_CHANNEL_0)和采样时间。 在主循环中,我们使用`HAL_ADC_Start()`函数启动ADC转换,并使用`HAL_ADC_PollForConversion()`函数等待转换完成。一旦转换完成,我们使用`HAL_ADC_GetValue()`函数读取转换结果。 请注意,以上代码只是一个示例,实际情况下你需要根据你的具体需求进行修改和适配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值