【嵌入式】HC32F07X ADC采样及软件滤波

news2024/11/16 3:42:01

目录

一 背景说明

二 原理分析

三 电压采样

四 软件滤波


一 背景说明

        使用小华(华大)的MCU HC32F07X实现四个通道的 0-5V 电压采样,并对采样结果进行滤波处理。

二 原理分析

【1】ADC原理说明:

        单片机是数字芯片,只认识由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,HC32F07X的ADC可以支持5V范围内的采样)。

(2)分辨率:假如 ADC 的测量范围为 0-5V,分辨率设置为12位,那么我们能测出来的最小电压就是 5V除以 2 的 12 次方,也就是 5/4096=0.00122V。很明显,分辨率越高,采集到的信号越精确,所以分辨率是衡量 ADC 的一个重要指标。

(3)采样时间:当 ADC 在某时刻采集外部电压信号的时候,此时外部的信号应该保持不变,但实际上外部的信号是不停变化的。所以在 ADC 内部有一个保持电路,保持某一时刻的外部信号,这样 ADC 就可以稳定采集了,保持这个信号的时间就是采样时间。

(4)采样率:也就是在一秒的时间内采集多少次。很明显,采样率越高越好,当采样率不够的时候可能会丢失部分信息,所以 ADC 采样率是衡量 ADC 性能的另一个重要指标(详细参考信号处理方向书籍)。

【2】HC32F07X的ADC外设:

        HC32F07X内部集成了一个 12 位高精度、高转换速率的逐次逼近型模数转换器(SAR ADC)模块。具有以下特性:

■ 12 位转换精度;
■ 1M SPS 转换速度;
■ 41 个输入通道,包括 36 路外部管脚输入、 1 路内部温度传感器电压、 1 路 1/3 AVCC 电压、
1 路内建 BGR 1.2V 电压、 2 路 DAC 输出;
■ 4 种参考源: AVCC 电压、 ExRef 引脚、内置 1.5v 参考电压、内置 2.5v 参考电压;
■ ADC 的电压输入范围: 0~Vref;
■ 4 种转换模式:单次转换、顺序扫描连续转换、插队扫描连续转换、连续转换累加;
■ 输入通道电压阈值监测;
■ 软件可配置 ADC 的转换速率;
■ 内置信号跟随器,可转换高阻信号;
■ 支持片内外设自动触发 ADC 转换,有效降低芯片功耗并提高转换的实时性

        ADC框图如下:

        转换时序和转换速度如下所示:一次完整的 ADC 转换由转换过程及逐次比较过程组成。其中转换过程需要 4~12 个 ADCCLK,由 ADC_CR0.SAM 配置;逐次比较过程需要 16 个 ADCCLK。所以,一次 ADC转换共需要 20~28 个 ADCCLK。

        ADC 转换速度的单位为 SPS,即每秒进行多少次 ADC 转换。 ADC 转换速度的计算方法为: ADCCLK的频率 / 一次 ADC 转换所需要的 ADCCLK 的个数。

        ADC 转换速度与 ADC 参考电压及 AVCC 电压相关,最高转换速度如下表所示:

        更多详细的内容可以参考HC32F07X芯片的DATASHEET。

三 电压采样

        选用引脚 PA00、PA01、PA02、PA03进行四路的电压采样,采样形式为顺序扫描,参考电压为AVCC(5V)

【1】ADC初始化GPIO

//模拟量输入引脚定义
#define SPL_AIN0_PORT       (GpioPortA)
#define SPL_AIN0_PIN        (GpioPin0)
#define SPL_AIN1_PORT       (GpioPortA)
#define SPL_AIN1_PIN        (GpioPin1)
#define SPL_AIN2_PORT       (GpioPortA)
#define SPL_AIN2_PIN        (GpioPin2)
#define SPL_AIN3_PORT       (GpioPortA)
#define SPL_AIN3_PIN        (GpioPin3)

/**************************************************************************
* 函数名称: ADC_Init
* 功能描述: ADC初始化GPIO
**************************************************************************/
void ADC_Init(void)
{
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    Gpio_SetAnalogMode(SPL_AIN0_PORT, SPL_AIN0_PIN);        //PA00 (AIN0)
    Gpio_SetAnalogMode(SPL_AIN1_PORT, SPL_AIN1_PIN);        //PA01 (AIN1)
    Gpio_SetAnalogMode(SPL_AIN2_PORT, SPL_AIN2_PIN);        //PA02 (AIN2)
    Gpio_SetAnalogMode(SPL_AIN3_PORT, SPL_AIN3_PIN);        //PA03 (AIN3)
}

【2】ADC初始化配置

/**************************************************************************
* 函数名称: ADC_Cfg
* 功能描述: ADC初始化配置
**************************************************************************/
void ADC_Cfg(void)
{
    stc_adc_cfg_t              stcAdcCfg;

    DDL_ZERO_STRUCT(stcAdcCfg);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE); 
    Bgr_BgrEnable();        ///< 开启BGR
    ///< ADC 初始化配置
    stcAdcCfg.enAdcMode         = AdcScanMode;              ///<采样模式-扫描
    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            ///<采样分频-1
    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk;      ///<采样周期数-8
    stcAdcCfg.enAdcRefVolSel    = AdcMskRefVolSelAVDD;      ///<参考电压选择-VCC
    stcAdcCfg.enAdcOpBuf        = AdcMskBufEnable;          ///<放大器BUF配置-开
    stcAdcCfg.enInRef           = AdcMskInRefDisable;       ///<内部参考电压使能-关
    stcAdcCfg.enAdcAlign        = AdcAlignRight;            ///<转换结果对齐方式-右
    Adc_Init(&stcAdcCfg);
}

【3】ADC顺序扫描功能配置

/**************************************************************************
* 函数名称: ADC_SqrCfg
* 功能描述: ADC顺序扫描功能配置
**************************************************************************/
void ADC_SqrCfg(void)
{
    stc_adc_sqr_cfg_t          stcAdcSqrCfg;
    
    DDL_ZERO_STRUCT(stcAdcSqrCfg);
        
    ///< 顺序扫描模式功能及通道配置
    ///< 注意:扫描模式下,当配置转换次数为n时,转换通道的配置范围必须为[SQRCH(0)MUX,SQRCH(n-1)MUX]
    stcAdcSqrCfg.bSqrDmaTrig = FALSE;
    stcAdcSqrCfg.u8SqrCnt    = 4;
    Adc_SqrModeCfg(&stcAdcSqrCfg);

    Adc_CfgSqrChannel(AdcSQRCH0MUX, AdcExInputCH0);
    Adc_CfgSqrChannel(AdcSQRCH1MUX, AdcExInputCH1);
    Adc_CfgSqrChannel(AdcSQRCH2MUX, AdcExInputCH2);
    Adc_CfgSqrChannel(AdcSQRCH3MUX, AdcExInputCH3);
    
    ///< ADC 中断使能
    Adc_EnableIrq();
    EnableNvic(ADC_DAC_IRQn, IrqLevel3, TRUE);
    
    ///< 启动顺序扫描采样
    Adc_SQR_Start();
}

【4】ADC中断服务子程序

uint32_t spl_buff[4];

/**************************************************************************
* 函数名称: Adc_IRQHandler
* 功能描述: ADC中断服务函数
**************************************************************************/
void Adc_IRQHandler(void)
{
    if(TRUE == Adc_GetIrqStatus(AdcMskIrqSqr))
    {
        Adc_ClrIrqStatus(AdcMskIrqSqr);
        
        spl_buff[0] = Adc_GetSqrResult(AdcSQRCH0MUX);
        spl_buff[1] = Adc_GetSqrResult(AdcSQRCH1MUX);
        spl_buff[2] = Adc_GetSqrResult(AdcSQRCH2MUX);
        spl_buff[3] = Adc_GetSqrResult(AdcSQRCH3MUX);
        
        Adc_SQR_Stop();
    }
}

【5】主函数调用

int32_t main(void)
{
    //采样模块
    ADC_Init();
    ADC_Cfg();
    ADC_SqrCfg();
    
    //调试模块
    Dbg_Init();
    Dbg_Cfg();
    Dbg_Printf("Hello World!\n");
    
    while(1)
    {
        //采样
        Adc_SQR_Start();
        Dbg_Printf("Ch1:%d\n", spl_buff[0]);  //FireWater协议
        
        delay1ms(10);
    }
}

【6】实际测试

        使用 VOFA+ 软件(【注1】:VOFA+的下载地址为VOFA+官网)( 【注2】:VOFA+的使用方法参考博文VOFA+的使用),分析串口传送过来的采样电压值,我现在给定 PA00(AIN0) 脚的电压为2V,根据参考电压5V可以计算得到采样值约为 2V * 4095 / 5V = 1638(实际输入的参考电压AVCC比5V小,采样值实际在1690左右):

        由实际测试可以发现,采样到的电压数据存在振荡的情况,需要考虑硬件滤波或者软件滤波的方法来处理数据

四 软件滤波

【1】增加软件滤波(滑动平均滤波

方法:把连续取N个采样值看成一个队列,队列的长度固定为N。每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则)。把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。
N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
优点:对周期性干扰有良好的抑制作用,平滑度高;试用于高频振荡的系统
缺点:灵敏度低;对偶然出现的脉冲性干扰的抑制作用较差,不适于脉冲干扰较严重的场合
比较浪费RAM(改进方法,减去的不是队首的值,而是上一次得到的平均值)

        方法参考这一篇博文,其中详细列举了不少ADC采样滤波的算法(ADC采样滤波算法)。我这边考虑的是滑动平均滤波,对博文中的算法做了一些改动:

/**************************************************************************
* 函数名称: analogAvgFilter
* 功能描述: 模拟量输入滑动滤波处理
**************************************************************************/
#define CACHE_LEN 5

uint32_t analogAvgFilter(uint32_t in_data)
{
    static uint32_t in_buf[CACHE_LEN];
	uint32_t sum = 0;
    uint8_t  i = 0;
    
	for(i = 0; i < (CACHE_LEN-1); i ++)
	{
		in_buf[i] = in_buf[i + 1];
		sum = sum + in_buf[i];
	}
	in_buf[CACHE_LEN-1] = in_data;
	sum = sum + in_buf[CACHE_LEN-1];
	
	return (sum / CACHE_LEN);
}

【2】主函数调用

uint32_t result_spl;

int32_t main(void)
{
    //采样模块
    ADC_Init();
    ADC_Cfg();
    ADC_SqrCfg();
    
    //调试模块
    Dbg_Init();
    Dbg_Cfg();
    Dbg_Printf("Hello World!\n");
    
    while(1)
    {
        //采样
        Adc_SQR_Start();
        result_spl = analogAvgFilter(spl_buff[0]);
        Dbg_Printf("Ch1:%d,%d\n", spl_buff[0], result_spl);  //FireWater协议
        
        delay1ms(10);
    }
}

【3】实际测试

        滤波前后效果对比如下,效果还是比较明显的:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1139503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法】

Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法 错误原因解决办法 错误原因 这是因为ibus输入法有一个快捷键占用了这个终端终结者的快捷键 解决办法 打开命令行输入 ibus-setup进入到如下页面随后将其中的表情注释的快捷键删除即可

Java生成Jar包方法

1. 设置->项目结构 2. Artifacts->JAR->From modules… 3. 打开菜单栏 4. Build Artifacts… 5. Build或Rebuild (完)

《SpringBoot项目实战》第二篇—接口用户上下文的设计与实现

系列文章导航 第一篇—接口参数的一些弯弯绕绕 第二篇—接口用户上下文的设计与实现 第三篇—留下用户调用接口的痕迹 第四篇—接口的权限控制 第五篇—接口发生异常如何统一处理 本文参考项目源码地址&#xff1a;summo-springboot-interface-demo 前言 大家好&#xff01;…

解决:谷歌浏览器访问http时,自动转https访问的问题

问题背景&#xff1a;某个系统网站&#xff0c;之前一直用https域名访问&#xff0c;现在改成http域名后&#xff0c;用http访问&#xff0c;谷歌浏览器会自动跳转到https。 解决方法&#xff1a; 在浏览器中输入网址&#xff1a;chrome://net-internals/#hsts -》 在“Delete…

Response Header中不暴露Server(IIS)版本、ASP.NET及相关版本等信息

ASP MVC开发的Web默认情况下会在请求的回应中暴露Server、X-AspNet-Version、X-AspNetMvc-Version、X-Powered-By等相关服务端信息&#xff0c;公开这些敏感信息会存在一定的安全风险。 X-SourceFiles标头用于被IIS / IIS Express中某些调试模块理解&#xff0c;它包含到磁盘上…

首个集成AI的国产操作系统带来了哪些惊喜

在2023年的统信UOS技术开放日暨deepin Meetup北京站上&#xff0c;统信UOS展示了其最新的AI技术和应用&#xff0c;标志着国产操作系统进入了一个全新的AI时代。作为国内领先的操作系统&#xff0c;统信UOS不仅为用户提供了更智能、更高效的服务&#xff0c;还为开发者打开了强…

颈肩肌筋膜炎做什么检查

颈肩肌筋膜炎症状 颈肩背部广泛疼痛酸胀沉重感、麻木感&#xff0c;僵硬、活动受限&#xff0c;可向后头部及上臂放散。疼痛呈持续性&#xff0c;可因感染、疲劳、受凉、受潮等因素而加重。查体见颈部肌紧张&#xff0c;压痛点常在棘突及棘突旁斜方肌、菱形肌等&#xff0c;压…

语雀宕机8小时,是否说明现在高可用架构很脆弱?

系列文章目录 高并发架构去重难&#xff1f;架构必备技能 - 布隆过滤器 当Dubbo遇到高并发&#xff1a;探究流量控制解决方案 主从选举机制&#xff0c;架构高可用性的不二选择 面试Dubbo &#xff0c;却问我和Springcloud有什么区别&#xff1f; 消息队列选型——为什么选择R…

06 rpm和yum

rpm -ivh 软件包名 安装软件 yum仓库的配置和基本的命令使用 1 配置本地仓库文件 local.repo cd /etc/yum.repos.d/ vi local.repo 输入 [c6-local] nameCentOS-$releasever - local baseurlhttp://192.168.230.128/centos/6/os/x86_64 gpgcheck0 enabled1 gpgkeyfile:///et…

基于SpringBoot+SSM苍穹外卖之实战项目

功能介绍&#xff1a; 基于SpringBootSSM苍穹外卖之企业级实战项目。该系统定位的是一款为餐饮企业&#xff08;餐厅、饭店&#xff09;定制的软件产品&#xff0c;在线外卖系统&#xff0c;顾客可以通过网站或者手机 App 订购餐点。 主要功能&#xff1a; 管理端 模块描述登…

小红书为什么流量不好,小红书笔记质量评判标准有哪些?

我们都知道小红书平台强大的种草力与传播力&#xff0c;需要依靠优质笔记的输出来达成。但是很多时候&#xff0c;我们撰写了笔记&#xff0c;却无法被收录&#xff0c;获得流量&#xff0c;这都是因为笔记质量出现了问题。那么小红书为什么流量不好&#xff0c;小红书笔记质量…

20PIN直插百兆网络变压器 H82022D

这是一颗20PIN直插百兆网络变压器 PIN距为2.0 &#xff0c;与H82002D是一样的&#xff0c;但内部线路刚好相反 本产品我司可支持一件代发&#xff0c;并支持出口 专业网络变压器&#xff0c;尽在Hqst

微信小程序分销商城源码系统+带PC端+收银台+付费会员卡 带完整搭建教程

在当今数字化的世界里&#xff0c;微信小程序已成为商业发展的重要一环。而其中&#xff0c;分销商城更是备受商家和消费者青睐的一种业务模式。为了帮助您快速搭建起自己的微信小程序分销商城&#xff0c;小编来给大家分享一款微信小程序分销商城源码系统&#xff0c;带PC端的…

iOS发布证书.p12文件无密码解决办法及导出带密码的新.p12文件方法

摘要&#xff1a; 本文将以iOS技术博主身份&#xff0c;分享解决使用无密码的.p12文件发布应用时遇到的问题&#xff0c;并介绍如何以带密码的方式重新导出.p12文件的方法。通过本文提供的步骤&#xff0c;开发者可以顺利完成证书的发布流程。 引言 在iOS应用发布过程中&…

电脑监控软件系统有哪些

电脑监控软件系统在当今信息化时代的应用越来越广泛&#xff0c;它们可以帮助企业或个人解决许多问题。 电脑监控软件有哪些功能&#xff1a; 1、实时监控&#xff1a;对电脑的屏幕、键盘、鼠标等设备进行实时监控&#xff0c;以便及时发现异常情况并采取相应的措施。 2、数据采…

作为前端开发,你应该知道的这十几个在线免费工具

​偶然刷到知乎一位前端大佬 表歌 多篇优秀实用的文章&#xff0c;真的发现宝藏了 以下内容就是他在知乎分享的十几个在线免费工具 1. 页面设计检查清单&#xff1a;https://www.checklist.design/ 页面设计检查清单 通过清单可以检查一些常用容易忽略的设计要素。 2. 背景色…

[UDS] --- WriteDataByIdentifier 0x2E

1 0x2E功能描述 根据ISO14119-1标准中所述&#xff0c;诊断服务2E主要用于Client向Server(ECU)通过DID的方式写入相关的数据。 2 0x2E应用场景 一般而言&#xff0c;对于2E诊断服务&#xff0c;主要应用场景为以下场合&#xff1a; 在整车下线的过程中写入相关配置信息&…

AMEYA360:罗姆开发出LiDAR用的120W高输出功率激光二极管“RLD90QZW8”

全球知名半导体制造商ROHM(总部位于日本京都市)开发出一款高输出功率半导体激光二极管“RLD90QZW8”&#xff0c;该产品非常适用于搭载测距和空间识别用LiDAR*1的工业设备领域的AGV(Automated Guided Vehicle/无人搬运车)和服务机器人、消费电子领域的扫地机器人等应用。 近年来…

图片能预览但无法打开

# -*- coding: utf-8 -*- # Time : 2022/1/14 9:35 # Author : Cocktail_pyfrom PIL import Image import imghdrfilename xxx.jpg # 查看图片是什么类型 print(imghdr.what(filename))# 转换成能打开的类型 image Image.open(filename) image image.convert("RGB&…

leetcode:1323. 6 和 9 组成的最大数字(python3解法)

难度&#xff1a;简单 给你一个仅由数字 6 和 9 组成的正整数 num。 你最多只能翻转一位数字&#xff0c;将 6 变成 9&#xff0c;或者把 9 变成 6 。 请返回你可以得到的最大数字。 示例 1&#xff1a; 输入&#xff1a;num 9669 输出&#xff1a;9969 解释&#xff1a; 改变…