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

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

3天内不再提示

实例讲解单片机模拟量采集: 从硬件到程序, 从滤波到实际值转换,有多少人懂了?

jf_pJlTbmA9 来源:今日头条 作者:今日头条 2023-10-17 14:28 次阅读

单片机系统里对模拟量的处理要比数字量稍显复杂,但是只要掌握了使用技巧,使用起来也很简单,很多朋友一开始比较纠结于单片机的底层语言,非要先弄个明白才罢休,其实大可不必,重要的是我们要先学会怎么应用。

现以铅酸电池电压检测及充电电流检测为例讲解模拟量的硬件和程序的设计。

如图1为28节铅酸电池的电压检测电路,1--14节组成电池组1,15--28节组成电池组2;第1节正极为BAT+,14与15节之间为BATM,第28节负极为BAT-。输入端的8个二极管的作用是钳位作用;电路计算如图所示。

wKgZomUD8BaAUcE4AAI0-d3PlZM858.png 图1:电池组电压检测电路

如图2为铅酸电池的充电电流检测电路,TA1为工频电流互感器,输入的4个二极管为整流二极管,电流流过R37(510Ω)形成压差△V。电路计算如图所示。

wKgZomUD8BmAJTJgAAD353Ydto0687.png 图2:电池组充电电流检测电路

如图3为单片机STM32F103CBT6,图1和图2的模拟信号输入至单片机的PA5、PA6、PA7。

wKgaomUD8ByAB5E9AAGYqnfdvZg450.png 图3:STM32F103CBT6单片机

由于代码较多,为便于浏览,我就把其中一部分以截图的形式展示

如图4为单片机adc.c文件的底层配置,把PA5、PA6、PA7端口配置成模拟输入模式。

wKgaomUD8B2AEBQPAAC0SxT2BCU483.png 图4:配置端口模式

如图5对以上三个模拟量进行模数转换并缓存入数组ADC_ConvertedValue[3],得到的AD值的范围是0~4096。

wKgZomUD8CCAXU2TAAHq5tP_8_M447.png 图5:模数转换并缓存

如图6把以上两个配置函数整合在一起,定义成模拟量的初始化函数void ADC1_Init(void)。

wKgaomUD8CGAS8SRAAA8KWp5Snw887.png 图6:初始化

如图7在adc.h文件里声明函数void ADC1_Init(void),另外几个函数也在adc的c文件里定义的,后面附上源程序(非截图)。

wKgaomUD8CKAcHdNAABaze8psik849.png 图7:声明函数

如图8在main()主函数里调用ADC1_Init()初始化函数(要去掉void),初始化函数一定要放在while(1)的前面,表示在进入while(1)无限循环前只执行一次。Analog_Processing()为模拟量处理函数,要放在while(1)无限循环里面(该函数在下面讲)。

wKgZomUD8CSAWHAdAADmyWUrGag933.png 图8:函数调用

以下为模拟量在main.c文件里的定义。

s16 Charging_Current;		 //充电电流实际值
s16 Battery1_Voltage;		 //电池组1电压实际值
s16 Battery2_Voltage;		 //电池组2电压实际值
s16 Battery_Voltage; 		 //电池组总电压值

下面三个函数的定义都在adc.c文件里面定义的。

以下代码为模拟量处理函数:①对数组ADC_ConvertedValue[3]缓存值进行滤波处理;②对滤波后的AD值转换为实际值。

/******************************
模拟量处理函数
******************************/
void Analog_Processing(void)
{
//对AD值进行滤波
ADC_Charging_Current=Filter(ADC_ConvertedValue[0],ADC_Charging_Current,1,10);
ADC_Battery1_Voltage=Filter(ADC_ConvertedValue[1],ADC_Battery1_Voltage,1,10);
ADC_Battery2_Voltage=Filter(ADC_ConvertedValue[2],ADC_Battery2_Voltage,1,10);
//AD值转换为实际值
Charging_Current = Adc_To_Act(ADC_Charging_Current, 10, 4096, 0, 220);//22.0A
Battery1_Voltage = Adc_To_Act(ADC_Battery1_Voltage, 10, 4096, 0, 267);//267V
Battery2_Voltage = Adc_To_Act(ADC_Battery2_Voltage, 10, 4096, 0, 267);//267V
//两组电压相加得到总电压
Battery_Voltage = Battery1_Voltage + Battery2_Voltage;
}

以下代码为滤波函数,滤波函数有很多,采用合适的才是最实用的(该函数滤波后的值是连续变化的,有些滤波函数滤波后的值是跳变的)。

/******************************
滤波函数(base/k越大,容性越大)
该函数相当于是一个电容,通常取值k=1,base=10
******************************/
u16 Filter(u16 NewData, u16 OldData, u8 k, u8 base)
{
	u16 uiResult;
	if (NewData > OldData)
	{
		uiResult = NewData - OldData;
		uiResult *= k;
		uiResult += base >> 2;
		uiResult /= base;
		uiResult = OldData + uiResult; 
	}
	else if (OldData > NewData)
	{
		uiResult = OldData - NewData;
		uiResult *= k;
		uiResult += base >> 2;
		uiResult /= base;
		uiResult = OldData - uiResult; 
	}
	else
	{
		uiResult = NewData;
	}
	
	return(uiResult);
}

使用方法如下:NewData表示最新采用的模拟量;OldData表示滤波后的模拟量。

ADC_Battery1_Voltage=Filter(ADC_ConvertedValue[1],ADC_Battery1_Voltage,1,10);

为便于逻辑计算、控制及显示,以下代码是把AD值转换为实际值,

/******************************
AD值转换实际值函数
******************************/
s16 Adc_To_Act(s16 Adc_Value, s16 Pre_Adc_Min, s16 Pre_Adc_Max, s16 Pre_Act_Min, s16 Pre_Act_Max)
{
s32 _temp;
s32 _range;
_temp = (s32)((Adc_Value - Pre_Adc_Min) * (Pre_Act_Max - Pre_Act_Min) / (Pre_Adc_Max-Pre_Adc_Min)) + Pre_Act_Min;
_temp = Adc_Value - Pre_Adc_Min;
_range = Pre_Act_Max - Pre_Act_Min;
_temp = _temp * _range;
_range = Pre_Adc_Max - Pre_Adc_Min;
_temp = _temp + _range / 2;
_temp = _temp / _range;
_temp = _temp + Pre_Act_Min;
return(_temp);
}

使用方法如下:Adc_Value表示要转换的模拟量;Pre_Adc_Min表示模拟量AD值的最小值;Pre_Adc_Max表示模拟量AD值的最大值;Pre_Act_Min表示转换后实际值的最小值;Pre_Act_Max表示转换后实际值的最大值;(以下最大实际值220表示22.0A,是因为数码管显示需要小数表示)。

Charging_Current = Adc_To_Act(ADC_Charging_Current, 10, 4096, 0, 220);//22.0A

要点:

① 模拟量的采样电路,我多采用运放的差分放大电路,原因是被测电压可以和运放不用共地,且可有效抑制共模噪声,可达到较高的精确线性测量,比如以上电池组的被测电压的误差与实际相差在0.3V左右;

② 电池组输入至运放的8个1M的电阻是两个为一组的,且功率至少1/4W以上,因为在高压下的电阻容易老化,为保险起见,通常一个电阻的最大压差在100V以下为宜;

③ 电池组分为两组检测,一是为了降低元件所承受的电压,二是为了监视两组电池电压之间是否平衡,达到保护电池目的。

④ 函数应功能模块化,且具备通用性质,便于移植和调用,对于很多朋友应先学会如何使用,底层代码只要会配置就完全足够了。

当然,以上提供的设计是我通常的做法,能满足大多数的常规应用。

来源:今日头条(版主:电卤药丸)
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理


审核编辑 黄宇

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

    关注

    6001

    文章

    43978

    浏览量

    620866
  • 滤波
    +关注

    关注

    10

    文章

    624

    浏览量

    56248
  • 模拟量
    +关注

    关注

    5

    文章

    437

    浏览量

    25077
收藏 人收藏

    评论

    相关推荐

    设计实例讲解单片机C语言高阶编程

    本帖最后由 eehome 于 2013-1-5 10:02 编辑 设计实例讲解单片机C语言高阶编程
    发表于 08-17 16:17

    AVR单片机C语言实例讲解带你轻松入门精通

    本帖最后由 eehome 于 2013-1-5 10:08 编辑 AVR单片机C语言实例讲解带你轻松入门精通
    发表于 11-05 14:22

    单片机8路模拟量采集,4个继电器控制,GPRS传输

    大家好,我想用单片机采集8路模拟量,控制4个继电器,下位单片机实现自动控制,然后把采集的8路
    发表于 04-19 12:55

    PROTEUS7.88.1版本正在整理中,先开贴,看看有多少人需。

    `PROTEUS7.88.1版本正在整理中,先开贴,看看有多少人需。本人从事电子开发多年,PROTEUS对于单片机初学者是一个很好的软件,亲自整理,并且每个版本进行稳定性测试,都可
    发表于 11-04 21:48

    单片机入门精通

    单片机入门精通
    发表于 12-12 14:53

    入门精通STC8051单片机核心技术(辅助参考视频)

    `《入门精通STC8051单片机核心技术》内容真实,言语简洁,以当今主流的STC15系列单片机为主线进行讲解,并介绍了很多具有重要实用价
    发表于 02-11 20:18

    入门精通STC8051单片机核心技术.pdf

    仿真(标准8051方式仿真,不能仿真单片机新增功能)1.3.2硬件仿真(利用STC专用仿真芯片仿真,可仿真所有功能)1.4经典流水灯实例1.5单片机C语言延时
    发表于 03-07 01:10

    误解程序运行(单片机开始)

    关于程序的执行,以前想的不多,没有意识一个程序在运行时,哪里读指令,数据又写在哪里。 最近在看CSAPP时这个念头经常在脑袋中晃荡。
    发表于 09-20 11:13

    一文搞懂PLC中的模拟量如何采集和处理

    存放到指定的数据单元中。经过采集转换后存入数据单元中的 BCD 码数字, 与物理的大小之间一定的函数关系, 但这个数字并不与物理
    发表于 12-14 08:00

    PLC对模拟量信号是怎么进行处理的?

    通过计算转换,将这些模拟量信号转换为内部的数值信号。从而实现系统的监控及控制。现场的物理信号PLC内部处理的数值信号,
    发表于 09-05 08:31

    怎样通过STC15系列单片机采集外部模拟量信号

    通过STC15系列单片机外部加了ADC采集芯片TM7750来采集外部模拟量信号。程序注释,注释
    发表于 07-19 09:37

    FreeRTOS单片机操作系统

    转载【连载】单片机操作系统③——走进FreeRTOS【1】 单片机操作系统①我们熟悉的
    发表于 08-23 07:03

    单片机嵌入式

    分享一下,避免走弯路单片机嵌入式,我该投哪个岗位小白一开始也很迷茫,先后投过硬件岗和软件岗;说说这些岗位的要求吧。硬件工程师 ,主要考察
    发表于 10-28 06:05

    单片机入门入土学习单片机

    、Windows编程和linux编程,但是近期想学习单片机,也希望自己能够坚持下来,最起码最起码,不说精通,但是能够坚持做到零基础入门熟练,精通不敢奢望,但求熟悉。1、学习
    发表于 01-27 06:19

    单片机处理模拟量程序流程是如何的

    单片机处理模拟量程序流程是一种常见的应用场景,单片机通常被用来处理各种类型的传感器信号,例如温度传感器、压力传感器、光敏传感器等。在本文中,我将详尽地描述
    的头像 发表于 12-15 09:28 515次阅读