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
    +关注

    关注

    98

    文章

    6458

    浏览量

    544217
  • 比较器
    +关注

    关注

    14

    文章

    1640

    浏览量

    107134
  • D触发器
    +关注

    关注

    3

    文章

    164

    浏览量

    47872
  • STM32F4
    +关注

    关注

    3

    文章

    194

    浏览量

    28013
  • ADC采样
    +关注

    关注

    0

    文章

    134

    浏览量

    12834
  • RT-Thread
    +关注

    关注

    31

    文章

    1277

    浏览量

    39972
收藏 人收藏

    评论

    相关推荐

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

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

    基于RoboMasterCRT-Thread使用分享—PWM扩展实验

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

    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的开发
    的头像 发表于 09-25 09:55 3.5w次阅读
    <b class='flag-5'>RT-Thread</b>开发,如何有效学习<b class='flag-5'>RT-Thread</b>的五个步骤

    RT-Thread Studio驱动SD卡

    总结前言硬件平台:RT-Thread ART-Pi STM32H750XBH6开发 H750开发开发软件:RT-Thread Studio参考博客:
    发表于 12-27 19:13 20次下载
    <b class='flag-5'>RT-Thread</b> Studio驱动SD卡

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

    RT-Thread全球技术大会:RT-Thread测试用例集合案例           审核编辑:彭静
    的头像 发表于 05-27 16:34 2072次阅读
    <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 4492次阅读
    <b class='flag-5'>RT-Thread</b>学习笔记 <b class='flag-5'>RT-Thread</b>的架构概述

    基于RoboMasterC型开发RT-Thread使用分享(一)

    假期期间打算开一个坑,和大家分享下基于RoboMaster开发C型上RT-Thread使用,本系列文章计划是给刚接触STM32和RT-Thread的同学看的,讲的会稍微基础一点。 硬件与开发环境
    的头像 发表于 01-05 12:10 2326次阅读

    基于RoboMasterC型开发RT-Thread使用分享(二)

    的通过Kconfig+CubeMX配置出可以驱动整个开发所有外设的工程的。在社区前辈的提醒后才知道通过基于芯片创建工程是没有办法Kconfig配置的。因此我在之后的教程中我会基于RT-Thread提供
    的头像 发表于 01-06 03:05 760次阅读

    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 9次下载
    <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 9次下载
    <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 3847次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio学习

    基于rt-thread的socket通信设计

    最近再研究 rt-thread 的通信 ,想设计出 eps8266(多个) rt-thread(作为中控) 服务器的通信框架,使用的开发是 潘多拉
    的头像 发表于 10-13 15:02 1334次阅读
    基于<b class='flag-5'>rt-thread</b>的socket通信设计