0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于RoboMasterC板的RT-Thread使用分享—ADC测量电压实验

冬至子 来源:goldengrandpa 作者:goldengrandpa 2023-10-13 15:15 次阅读

本次我们来讲一下ADCAnalog-to-Digital Converter)不是游戏里的AD Carry,我们将实现电池电压的读取。

ADC简介
ADC的全称为Analog-to-Digital Converter(模拟/数字转换器)。

单片机中传输的信号均为数字信号,通过离散的高低电平表示数字逻辑的 1 和 0,但是在现实的物理世界中只存在模拟信号,即连续变化的信号。将这些连续变化的信号——比如热,光,声音,速度通过各种传感器转化成连续的电信号,再通过 ADC 功能将连续的模拟信号转化成离散的数字信号给单片机进行处理。

常见的ADC类型有并联比较型、逐次逼近型。它们的特点如下

1.jpg

ADC有两个重要参数,分辨率和转换速率。

分辨率:每一个ADC模块都会明确他的分辨率,通过bit来表示,一般的是8bit,10bit,12bit,16bit,24bit.bit越大,说明分辨率越高。

采样率:采样率就是ADC 采样的速率。它是指在规定的时间内可以采集的次数,采样率越高,采集到的点数就越多,那么对原始信号的还原率就越高。采样率的单位是SPS(sample per sencond),每秒采样次数。这个值越大,采样速度越快。

下面简单的讲一下这两种ADC的工作原理

并联比较型
这个也是比较容易理解的一种。下图为并联比较型ADC的工作原理图。

1.jpg

它分为分压部分、比较部分、编码部分。

一开始的一排电阻均为等阻值的电阻,它们将VREF(参考电压)进行均分,也就代表这个该ADC的精度,电阻分压后的电压(Vr)我们将其接到比较器的。图中V1为我们的待测电压,当V1Vr时比较器输出1。比如我们这个假设VREF为15V,V1为1.2V。那么在最下面的比较器中Vr为1V,V1>Vr,比较器输出1,第二个比较器中Vr为3V,V1

之后我们在每个比较器后加上D触发器,当我们把C(控制端)至1后,我们给D输入1,则Q输入1,输入0,则Q输出0。这里我们先给C1,此时比较器输出的结果就被存储到锁存器中。然后再置0,那么无论我们的输入电压V1怎样变,Q输出的值都不变,也就保存了输出值。这里我们改变控制C的速度很大程度决定了最大采样率,当然最大采样率还受比较器等器件最大频率的限制。

但是这里输出的还不是二进制数,因此我们需要后面加一个编码器进行编码。上面就是并联比较型原理的简单描述。

这里我们也可以看出,并联比较型的缺点就是精度想要提升就必须增加相应的电阻、比较器、触发器。这样会增加物料成本与体积。但是优点就是速度很快。

逐级比较型
下图为逐级比较型ADC的工作示意图,我们使用的STM32F4也是使用的这种ADC。

1.jpg

它可以分为控制电路数码寄存器、D/A转换器、电压比较器四个部分

首先第一步在数码寄存器进行编码,将高位D2编码置1,其他位置0,之后进入D/A转换器,将编码出来的数字量转变为模拟量V0。之后V0和输入电压Vx到比较器进行比较。如果Vx大于V0,比较器输出1,那么控制电路就会将高位D2锁定不变,之后将D1置1进行第二轮比较。如果此时Vx还是大于V0我们也就说明了我们V0的值更加接近Vx。我们将D0置1继续进行第三轮比较,比如Vx还是比V0大那么说明Vx大于了ADC的量程,如果Vx

这里给出另一个图方便大家理解

与 1/2Vref 进行比较,Vin 大于 1/2Vref,则将第一位标记为 1
与 3/4Vref 进行比较,Vin 小于 3/4Vref,则将第二位标记为 0
与 5/8Vref 进行比较,Vin 小于 5/8Vref,则将第三位标记为 0。
图中的 Vin 通过这个三位的 ADC 后输出的结果为 100,转换的结果为 1/2Vref。

1.jpg

这里我们看出由于它需要逐次逼近因此它的转换速度是比较慢的。而且它的分辨率和采样速度相互矛盾,分辨率越高,采样速率就越低。

CubeMX配置
虽然这里bsp文件已经将我们需要的ADC1,ADC3开启了,但是这里还是带着大家学习一遍,便于大家使用其他STM32板子时快速配置。

首先还是看原理图

1.jpg

这里可以看到电源ADC引脚为PF10,使用ADC3的通道8。

我们需要开启ADC1和ADC3,ADC1在此处作用为读取STM32内部的1.2V校准电压Vrefint,这个操作在芯片内部实现没有对应引脚。

1.jpg

ADC1的具体配置如下

1.jpg

下表简单描述一下CuebMX中ADC设置中的功能。

1.jpg

ADC3开启通道8,具体配置如ADC1一样。

1.jpg

这里我们为什么需要使用ADC1的VREFINT呢?

VREFINT是ADC的内部参照电压1.2V,一般来说在STM32我们会使用Vcc作为Vref,但是实际情况中Vcc可能存在较大波动导致Vref不稳定最终使得ADC采样值不准确,因此我们使用已有的1.2V内部参考电压先行进行多次采样,计算平均值。将其与ADC采样得出的值进行对比,计算出偏移的比例,得到单位数字电压对应的模拟电压值。

程序编写
首先在RT-Thread Settings组件中打开ADC设备驱动程序

1.jpg

之后在硬件中打开ADC1与ADC3

1.jpg

新建一个app_adc.c文件

在使能设备之后有几点需要我们注意

我们需要采样内部参考电压1.2V200次,取平均值并计算单位数字电压对应的模拟电压值

/* 采样内部参考电压200次 /
for(int i=0;i<200;i++)
{
totalvalue+=rt_adc_read(adc_ref,ADC_REF_CHANNEL);
}
/
计算单位数字电压对应的模拟电压值 /
voltage_vrefint_proportion=200
1.2f/totalvalue;
之后我们对ADC3通道8进行采样,这里有两个点需要注意

/* 读取采样值 */
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is :%d n", value);
/* 转换为对应电压值 */
vol=(double)value*voltage_vrefint_proportion*1009.0909090909090909090909090909f;
rt_kprintf("the voltage is :%d.%02d n", vol / 100, vol % 100);

我们重新看一下原理图,我们这里采样的是分压电路分压之后的值,因此我们需要计算出分压之前的值才为我们所需的电池电压。通过如下计算我们需要乘以10.09

1.jpg

并且RT-Thread中rt_kprintf是不能打印出浮点数的,如果是浮点数的话就不会打印出来,这个我之前也踩过坑,有两个办法,一是修改rt_kprintf函数实现,但是printf作为一个可重入的函数,打印浮点数是不安全的。因此我这里选择方法二,我们想要保留小数点后两位,那么我们就将值*100,之后在打印时再将值/100作为整数部分,值%100作为小数部分,如下所示。

rt_kprintf("the voltage is :%d.%02d n", vol / 100, vol % 100);
完整代码如下,实现功能为输入adc_vol_sample,输出实际读取到的转换的原始数据和经过计算后的实际电压值。

/*

Copyright (c) 2006-2021, RT-Thread Development Team

SPDX-License-Identifier: Apache-2.0

Change Logs:
Date Author Notes
2023-01-09 Goldengrandpa the first version
/
#include
#include
#define ADC_REF_NAME "adc1" /
ADC 内部参考电压设备名称 /
#define ADC_REF_CHANNEL 17
#define ADC_DEV_NAME "adc3" /
ADC 设备名称 /
#define ADC_DEV_CHANNEL 8 /
ADC 通道 /
static int adc_vol_sample(int argc, char argv[])
{
rt_adc_device_t adc_ref;
rt_adc_device_t adc_dev;
rt_uint32_t totalvalue;
rt_uint32_t value, vol;
double voltage_vrefint_proportion;
rt_err_t ret = RT_EOK;
/
查找设备 /
adc_ref = (rt_adc_device_t) rt_device_find(ADC_REF_NAME);
if (adc_ref == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!n", ADC_REF_NAME);
return RT_ERROR;
}
adc_dev = (rt_adc_device_t) rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!n", ADC_DEV_NAME);
return RT_ERROR;
}
/
使能设备 /
ret = rt_adc_enable(adc_ref, ADC_REF_CHANNEL);
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
/
采样内部参考电压200次 /
for(int i=0;i<200;i++)
{
totalvalue+=rt_adc_read(adc_ref,ADC_REF_CHANNEL);
}
/
计算单位数字电压对应的模拟电压值 /
voltage_vrefint_proportion=200
1.2f/totalvalue;
/
读取采样值 /
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is :%d n", value);
/
转换为对应电压值 /
vol=(double)value
voltage_vrefint_proportion1009.0909090909090909090909090909f;
rt_kprintf("the voltage is :%d.%02d n", vol / 100, vol % 100);
/
关闭通道 /
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
return ret;
}
/
导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);

硬件连接如下,这里使用的是大疆的6s电池,输出电压24V。

1.jpg

由于电池基本要没电了因此计算出来的电压为22.39V偏小属于正常现象。

1.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • adc
    adc
    +关注

    关注

    95

    文章

    5651

    浏览量

    539460
  • 比较器
    +关注

    关注

    14

    文章

    1526

    浏览量

    106481
  • D触发器
    +关注

    关注

    2

    文章

    147

    浏览量

    47378
  • STM32F4
    +关注

    关注

    3

    文章

    192

    浏览量

    27676
  • ADC采样
    +关注

    关注

    0

    文章

    125

    浏览量

    12708
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38869
收藏 人收藏

    评论

    相关推荐

    基于rt-thread studio的sdk开发adc的应用详解

    本文将介绍基于 rt-thread studio 的 sdk 开发 adc 的应用。本实验是在昨天的《中科蓝讯 AB32VG1 开发板OLED显示实验》项目基础上,增加
    的头像 发表于 11-06 09:41 5768次阅读
    基于<b class='flag-5'>rt-thread</b> studio的sdk开发<b class='flag-5'>adc</b>的应用详解

    RT-Thread记录(二、RT-Thread内核启动流程)

    在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程.
    的头像 发表于 06-20 00:30 4414次阅读
    <b class='flag-5'>RT-Thread</b>记录(二、<b class='flag-5'>RT-Thread</b>内核启动流程)

    基于RoboMasterC板的RT-Thread使用分享—PWM扩展实验

    这次因为没有新增功能所以新建功能部分我就先略过了,大家可以参考一下上篇文章,其中我修改Kconfig,开启PWM5 CH1/2/3的部分已经提交PR了,各位之后导入工程时可以先看一下RT-Thread Setting中是否已经显示。
    的头像 发表于 10-13 15:39 879次阅读
    基于<b class='flag-5'>RoboMasterC</b>板的<b class='flag-5'>RT-Thread</b>使用分享—PWM扩展<b class='flag-5'>实验</b>

    基于RT-Thread Studio的ADC外设使用方案介绍

    1、基于RT-Thread Stduio使用ART-Pi的ADC外设1. 打开 RT-Thread Stduio,左上角新建 RT-Thread 项目,选择基于开发
    发表于 03-28 16:57

    RT-Thread编程指南

    RT-Thread编程指南——RT-Thread开发组(2015-03-31)。RT-Thread做为国内有较大影响力的开源实时操作系统,本文是RT-Thread实时操作系统的编程指南
    发表于 11-26 16:06 0次下载

    RT-Thread开发,如何有效学习RT-Thread的五个步骤

    RT-Thread推出RT-Thread Inside战略开放RT-Thread开发平台授权合作,与硬件十万个为什么合作首次推出第一款RT-Inside的开发板——iBox物联网开发套
    的头像 发表于 09-25 09:55 3.4w次阅读
    <b class='flag-5'>RT-Thread</b>开发,如何有效学习<b class='flag-5'>RT-Thread</b>的五个步骤

    RT-Thread开源作品秀】基于RT-Thread的星务平台研究

    本作品为了验证星务软件在RT-Thread系统运行的可行性,底层是否能够驱动星务软件,同时扩展RT-Thread应用范围。ART-Pi作为卫星下位机,...
    发表于 01-25 18:26 5次下载
    【<b class='flag-5'>RT-Thread</b>开源作品秀】基于<b class='flag-5'>RT-Thread</b>的星务平台研究

    RT-Thread全球技术大会:Kconfig在RT-Thread中的工作机制

    RT-Thread全球技术大会:Kconfig在RT-Thread中的工作机制               审核编辑:彭静
    的头像 发表于 05-27 14:49 1239次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:Kconfig在<b class='flag-5'>RT-Thread</b>中的工作机制

    RT-Thread全球技术大会:RT-Thread测试用例集合案例

    RT-Thread全球技术大会:RT-Thread测试用例集合案例           审核编辑:彭静
    的头像 发表于 05-27 16:34 1782次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:<b class='flag-5'>RT-Thread</b>测试用例集合案例

    RT-Thread学习笔记 RT-Thread的架构概述

    RT-Thread 简介 作为一名 RTOS 的初学者,也许你对 RT-Thread 还比较陌生。然而,随着你的深入接触,你会逐渐发现 RT-Thread 的魅力和它相较于其他同类型 RTOS
    的头像 发表于 07-09 11:27 4000次阅读
    <b class='flag-5'>RT-Thread</b>学习笔记 <b class='flag-5'>RT-Thread</b>的架构概述

    RT-Thread文档_RT-Thread 简介

    RT-Thread文档_RT-Thread 简介
    发表于 02-22 18:22 5次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 简介

    RT-Thread文档_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文档_RT-Thread 潘多拉 STM32L475 上手指南
    发表于 02-22 18:23 7次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文档_RT-Thread SMP 介绍与移植

    RT-Thread文档_RT-Thread SMP 介绍与移植
    发表于 02-22 18:31 7次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> SMP 介绍与移植

    RT-Thread文档_ADC 设备

    RT-Thread文档_ADC 设备
    发表于 02-22 18:33 1次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>ADC</b> 设备

    基于RT-Thread Studio学习

    前期准备:从官网下载 RT-Thread Studio,弄个账号登陆,开启rt-thread学习之旅。
    的头像 发表于 05-15 11:00 2580次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio学习