赞
踩
单片机是数字芯片,只认识由0和1组成的逻辑序列。但实际情况下,生活中还有许多非0和1的模拟物理量存在,例如温度,湿度等。这时候往往需要使用到AD转换,AD转换的英文就是Analog(模拟) to Digital(数字),由模拟量转化为数字量;同理DA,则为Digital to Analog,数字量转化为模拟量。
ADC,Analog to Digital Converter 的缩写,中文名称模数转换器。它可以将外部的模拟信号转化成数字信号。使用它去读取IO口上的数值将不再是简单的0或1,而是连续可变的数值。ADC采样就是把随时间连续变化的模拟量转换为时间离散的模拟量。
ADC几个比较重要的参数:
**(1)测量范围:**测量范围对于 ADC 来说就好比尺子的量程,ADC 测量范围决定了你外接的设备其信号输出电压范围,不能超过 ADC 的测量范围(比如,STM32系列的 ADC 正常就不能超过3.3V)。
**(2)分辨率:**假如 ADC 的测量范围为 0-5V,分辨率设置为12位,那么我们能测出来的最小电压就是 5V除以 2 的 12 次方,也就是 5/4096=0.00122V。很明显,分辨率越高,采集到的信号越精确,所以分辨率是衡量 ADC 的一个重要指标。
**(3)采样时间:**当 ADC 在某时刻采集外部电压信号的时候,此时外部的信号应该保持不变,但实际上外部的信号是不停变化的。所以在 ADC 内部有一个保持电路,保持某一时刻的外部信号,这样 ADC 就可以稳定采集了,保持这个信号的时间就是采样时间。
**(4)采样率:**也就是在一秒的时间内采集多少次。很明显,采样率越高越好,当采样率不够的时候可能会丢失部分信息,所以 ADC 采样率是衡量 ADC 性能的另一个重要指标(详细参考信号处理方向书籍)。
总之,只要是需要模拟信号转为数字信号的场合,那么肯定要用到 ADC。很多数字传感器内部会集成 ADC,传感器内部使用 ADC 来处理原始的模拟信号,最终给用户输出数字信号。
STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC,STM32F103系列则有3个ADC和1个DAC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。
特别说明: ADC 是12位逐次逼近型模数转换器,输出数值范围是 0 ~ 2^12 -1(0 ~ 4095),满量程是 3.3V ,分辨率就是最低有效位(LSB)的对应输入电压值。分辨率 =3300/4095 ≈ 0.806mV。
STM32F10X 系列将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于正常运行的程序,而注入通道呢,就相当于中断打断式通道选择。在程序正常执行的时候,中断是可以打断程序执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。
关于 ADC 的模式配置可选择性很高,一般无需太多了解,详情可以参考**《STM32 参考手册的》**第 155 页,第 11 章。
VOFA+是一款直观、灵活、强大的插件驱动高自由度的上位机,在与电气打交道的领域里,如自动化、嵌入式、物联网、机器人等,都能看到**VOFA+**的身影。**VOFA+**的名字来源于:Volt/伏特、Ohm/欧姆、Fala/法拉、Ampere/安培,是电气领域的基础单位,与他们的发明者——4位电子物理学领域的科学巨人,分别同名。他们的首字母共同构成了VOFA+的名字。
VOFA+特点概览:
**平台支持:**Windows、Linux、MacOS;
**接口支持:**串口(超高波特率,稳定支持)、网口(TCP客户端/服务端,UDP);
**协议支持:**协议为插件,已开源,人人可编写。目前已支持CSV风格的字符串协议,和十六进制浮点数组形式的字节流协议;
**控件支持:**控件为插件,已开源,人人可编写。目前已支持波形图、按钮、状态灯、图片、滑动条、3D立方控件(可更换模型)等;
**数据维度自由化:**2维度与3维,一个也不能拉下;
**自主研发的波形控件:**支持每通道百万采样点的绘制,性能强劲;
**自主研发的波形控件:**无缝嵌入了实时直方统计和点数可设置的傅里叶变换,可以使用VOFA+进行数据分析。
Vofa+网址:VOFA+ | VOFA+
VOFA+的数据协议引擎有3种:FireWater,JustFloat,RawData。每种数据协议引擎都有自己特殊的使用效果,读者朋友可以根据自己的实际需要去选择使用。作者这里主要给大家演示一下FireWater协议下的VOFA+使用效果和方法。
FireWater协议是CSV风格的字符串流,直观简洁,编程像printf简单。但由于字符串解析消耗更多的运算资源(无论在上位机还是下位机),建议仅在通道数量不多、发送频率不高的时候使用。
将鼠标放到FireWater协议上,可以很贴心的得到使用格式帮助。如上图所示,我们使用printf(“simples:%f, %f\n”, sin(t1), sin(t2)")函数进行打印测试。
测试代码:
#include "math.h" #include "stdio.h" .... int main(void) { /* USER CODE BEGIN 1 */ float t1 = 0; float t2 = 0; /* USER CODE END 1 */ ....... while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ t1 += 0.1; t2 += 0.5; printf("simples:%f, %f\n", sin(t1), sin(t2)); HAL_Delay(100); } /* USER CODE END 3 */ }
1、选择串口通讯、端口号、波特率等参数设置;
2、去控件中选择波形图,拉入tab中,右键选择Y轴将2个输入I0与I1都选中,之后开启串口连接;
3、运行上位机,使用波形图控件读取下位机参数;
补充:
不难看出VOFA+的使用是非常简单快捷的,其自由度也是相当的高,关键还是免费的。PID调参,无人机的姿态3D显示等等都可以借助VOFA+实现, 希望该软件可以给读者朋友的日常嵌入式开发提供便捷与帮助。
1、RCC配置外部高速晶振(精度更高)——HSE;
2、SYS配置:Debug设置成Serial Wire(否则可能导致芯片自锁);
3、UART1配置:使用串口通讯UART1与VOFA+上位机进行通讯显示;
4、ADC1配置:利用ADC1的通道IN1进行AD采样,保持独立模式;
5、时钟树配置:
6、工程配置:
受限于MCU自身的ADC外设缺陷,其精度和稳定性通常较差,很多场景下需要采取滤波补偿。
滤波的作用就是减少噪声与干扰对数据测量的影响。
重写printf函数:
#include "stdio.h"
//重定义
int fputc(int c,FILE *stream)
{
uint8_t ch[1]={c};
HAL_UART_Transmit(&huart1,ch,1,0xFFFF);
return c;
}
main函数:
while(1){
HAL_ADC_Start(&hadc1); //开启ADC1,放置在while循环中
ADC_value=HAL_ADC_GetValue(&hadc1); //获取ADC1的数值
HAL_Delay(10); //延迟函数,防止采样失效
printf("ADC_value:%d\n", ADC_value);
}
VOFA+读取到的数据:
上图借助VOFA+上位机可以清楚看出未使用滤波的ADC采样波动还是比较明显的,但是作者主观干啥F1系列的ADC确实好像比F4系列的ADC稳定些。(之所以不是4096可能是因为电源未达到3.3v)
方法:取a=0~1,本次滤波结果=(1-a)本次采样值+a上次滤波结果
优点:对周期性干扰具有良好的抑制作用适用于波动频率较高的场合
缺点:相位滞后,灵敏度低滞后程度取决于a值大小不能消除滤波频率高于采样频率的1/2的干扰信号
//一阶互补滤波
int firstOrderFilter(int newValue, int oldValue, float a)
{
return a * newValue + (1-a) * oldValue;
}
ADC_value=HAL_ADC_GetValue(&hadc1); //获取ADC1的数值
//主函数
while(1){
HAL_ADC_Start(&hadc1); //开启ADC1,放置在while循环中
Filtering_Value = firstOrderFilter(HAL_ADC_GetValue(&hadc1),ADC_value,0.3); //滤波算法
HAL_Delay(10); //延迟函数,防止采样失效
printf("ADC_value:%d\n", ADC_value);
}
VOFA+软件的效果图:
一阶互补滤波的局限性还是很大的,效果非常一般。
方法:连续采样N次(N取奇数)把N次采样值按大小排列取中间值为本次有效值
优点:能有效克服因偶然因素引起的波动干扰;对温度、液位等变化缓慢的被测参数有良好的滤波效果
缺点:对流量,速度等快速变化的参数不宜
//中值滤波算法 int middleValueFilter(int N) { int value_buf[N]; int i,j,k,temp; for( i = 0; i < N; ++i) { value_buf[i] = HAL_ADC_GetValue(&hadc1); } for(j = 0 ; j < N-1; ++j) { for(k = 0; k < N-j-1; ++k) { //从小到大排序,冒泡法排序 if(value_buf[k] > value_buf[k+1]) { temp = value_buf[k]; value_buf[k] = value_buf[k+1]; value_buf[k+1] = temp; } } } return value_buf[(N-1)/2]; }
VOFA+软件的效果图:
中值滤波对消除异常值和平稳化AD采样都具有十分有效的结果。
方法:连续取N个采样值进行算术平均运算;
N值较大时:信号平滑度较高,但灵敏度较低
N值较小时:信号平滑度较低,但灵敏度较高
N值的选取:一般流量,N=12;压力:N=4
优点:试用于对一般具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
缺点:测量速度较慢或要求数据计算较快的实时控制不适用。
//算术平均值滤波
int averageFilter(int N)
{
int sum = 0;
short i;
for(i = 0; i < N; ++i)
{
sum += HAL_ADC_GetValue(&hadc1);
}
return sum/N;
}
VOFA+软件的效果图:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!
[外链图片转存中…(img-dwdBM7AF-1712384086365)]
[外链图片转存中…(img-L6qYBMMC-1712384086366)]
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。