GD32/STM32ADC采样及滤波

GD32/STM32ADC采样及滤波

本文主要讨论代码层面的ADC采集及程序滤波。

ADC注意事项

  1. ADC的参考电压为单片机的VDDA电压。

ADC单采

采用单路采集,然后通过DMA去ADC_RDATA(ADC0)读取数据。以下为GD32例程。

/*!\brief      configure the GPIO peripheral\param[in]  none\param[out] none\retval     none
*/
void gpio_config(void)
{/* config the GPIO as analog mode */gpio_init(ADC_GPIO_PORT, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, ADC_GPIO_PIN);
}/*!\brief      configure the DMA peripheral\param[in]  none\param[out] none\retval     none
*/
void dma_config(void)
{/* ADC_DMA_channel configuration */dma_parameter_struct dma_data_parameter;/* ADC DMA_channel configuration */dma_deinit(DMA0, DMA_CH0);/* initialize DMA single data mode */dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;dma_data_parameter.memory_addr  = (uint32_t)(&adc_value);dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;dma_data_parameter.number       = 1;dma_data_parameter.priority     = DMA_PRIORITY_HIGH;dma_init(DMA0, DMA_CH0, &dma_data_parameter);dma_circulation_enable(DMA0, DMA_CH0);/* enable DMA channel */dma_channel_enable(DMA0, DMA_CH0);
}/*!\brief      configure the ADC peripheral\param[in]  none\param[out] none\retval     none
*/
void adc_config(void)
{/* reset ADC */adc_deinit(ADC0);/* ADC mode config */adc_mode_config(ADC_MODE_FREE);/* ADC contineous function enable */adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);/* ADC scan mode disable */adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);/* ADC data alignment config */adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);/* ADC channel length config */adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, BOARD_ADC_CHANNEL, ADC_SAMPLETIME_55POINT5);/* ADC trigger config */adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);/* enable ADC interface */adc_enable(ADC0);delay_1ms(1);/* ADC calibration and reset calibration */adc_calibration_enable(ADC0);/* ADC DMA function enable */adc_dma_mode_enable(ADC0);/* ADC software trigger enable */adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}

ADC多路采集+DMA

采用多路采集,然后通过DMA去ADC_RDATA(ADC0)读取数据。以下为GD32例程。

/***********************************************************************
*@brief	:ADC初始化
*@param	:None
*@return:None
***********************************************************************/
void ADC_Init(void)
{/* config the GPIO as analog mode */gpio_init(ADC_CHL1_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL1_PIN);gpio_init(ADC_CHL2_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL2_PIN);gpio_init(ADC_CHL3_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL3_PIN);gpio_init(ADC_CHL4_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL4_PIN);gpio_init(ADC_CHL5_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL5_PIN);gpio_init(ADC_CHL6_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL6_PIN);gpio_init(ADC_CHL7_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL7_PIN);gpio_init(ADC_CHL8_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL8_PIN);gpio_init(ADC_CHL9_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL9_PIN);gpio_init(ADC_CHL10_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL10_PIN);gpio_init(ADC_CHL11_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL11_PIN);gpio_init(ADC_CHL12_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL12_PIN);gpio_init(ADC_CHL13_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL13_PIN);gpio_init(ADC_CHL14_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL14_PIN);gpio_init(ADC_CHL15_PORT, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, ADC_CHL15_PIN);/* enable ADC clock */rcu_periph_clock_enable(RCU_ADC0);/* config ADC clock */rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);    //12MHz;/* reset ADC */adc_deinit(ADC0);/* ADC mode config */adc_mode_config(ADC_MODE_FREE);/* ADC contineous function enable */adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);/* ADC scan mode disable */adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);/* ADC data alignment config */adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);/* ADC channel length config */adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, ADC_MAX_NUM);adc_tempsensor_vrefint_enable();  // 开启温度传感器/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_41POINT5); adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_2, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_3, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_5, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_6, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 6, ADC_CHANNEL_7, ADC_SAMPLETIME_41POINT5);  adc_regular_channel_config(ADC0, 7, ADC_CHANNEL_8, ADC_SAMPLETIME_41POINT5); adc_regular_channel_config(ADC0, 8, ADC_CHANNEL_9, ADC_SAMPLETIME_41POINT5); adc_regular_channel_config(ADC0, 9, ADC_CHANNEL_10, ADC_SAMPLETIME_41POINT5); 	adc_regular_channel_config(ADC0, 10, ADC_CHANNEL_11, ADC_SAMPLETIME_41POINT5);	adc_regular_channel_config(ADC0, 11, ADC_CHANNEL_12, ADC_SAMPLETIME_41POINT5);adc_regular_channel_config(ADC0, 12, ADC_CHANNEL_13, ADC_SAMPLETIME_41POINT5);adc_regular_channel_config(ADC0, 13, ADC_CHANNEL_14, ADC_SAMPLETIME_41POINT5);	adc_regular_channel_config(ADC0, 14, ADC_CHANNEL_15, ADC_SAMPLETIME_41POINT5);	adc_regular_channel_config(ADC0, 15, ADC_CHANNEL_16, ADC_SAMPLETIME_41POINT5);/* ADC trigger config */adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);/* enable ADC interface */adc_enable(ADC0);
//    delay_1ms(1);/* ADC calibration and reset calibration */adc_calibration_enable(ADC0);/* ADC DMA function enable */adc_dma_mode_enable(ADC0);/* ADC software trigger enable */adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}
/***********************************************************************
*@brief	:DMA初始化
*@param	:ADC传送
*@return:None
***********************************************************************/
void DMA_Init(void)
{/* enable DMA0 clock */rcu_periph_clock_enable(RCU_DMA0);/* ADC_DMA_channel configuration */dma_parameter_struct dma_data_parameter;/* ADC DMA_channel configuration */dma_deinit(DMA0, DMA_CH0);/* initialize DMA single data mode */dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;dma_data_parameter.memory_addr  = (uint32_t)(&adc_memory[0]);dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;dma_data_parameter.number       = ADC_MAX_NUM;dma_data_parameter.priority     = DMA_PRIORITY_HIGH;dma_init(DMA0, DMA_CH0, &dma_data_parameter);dma_circulation_enable(DMA0, DMA_CH0);/* enable DMA channel */dma_channel_enable(DMA0, DMA_CH0);
}

去极值求平均值滤波

采用一个数组采样10次,去掉一个最大值一个最小值,剩下八个求平均值。

#include <stdio.h>
#include <stdlib.h>int main() {// 定义数组和变量int arr[10];int i, j, temp;float avg;// 获取 10 个样本值printf("Enter 10 sample values:\n");for (i = 0; i < 10; i++) {scanf("%d", &arr[i]);}// 排序数组for (i = 0; i < 10; i++) {for (j = i + 1; j < 10; j++) {if (arr[i] > arr[j]) {// 交换 arr[i] 和 arr[j]temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}// 去掉最大值和最小值for (i = 1; i < 9; i++) {avg += arr[i];}// 计算平均值avg /= 8;// 打印去极值后的平均值printf("Average of the remaining 8 values: %.2f\n", avg);return 0;
}

滑动求平均值滤波

一组数据采用10位数组,队列式进队和出队,然后求平均值得到最终的值。

#include <stdio.h>
#include <stdlib.h>#define ARRAY_SIZE 10int main() {// 定义队列数组和变量int queue[ARRAY_SIZE];int head = 0;int tail = 0;int count = 0;float avg;// 获取 10 个样本值printf("Enter 10 sample values:\n");for (int i = 0; i < ARRAY_SIZE; i++) {scanf("%d", &queue[tail]);tail = (tail + 1) % ARRAY_SIZE;count++;}// 滑动求平均值while (count > 0) {// 计算平均值avg = 0;for (int i = 0; i < count; i++) {avg += queue[head];head = (head + 1) % ARRAY_SIZE;}avg /= count;// 打印平均值printf("Average: %.2f\n", avg);// 出队count--;}return 0;
}

振幅平均滤波法

#include <stdio.h>
#include <stdlib.h>// 定义滑动窗口大小
#define WINDOW_SIZE 5int main() {// 定义输入信号和滤波器参数int input_signal[] = {1, 3, 5, 10, 15, 20, 25, 30, 25, 20, 15, 10, 5, 3, 1};int threshold = 10;int window[WINDOW_SIZE];int head = 0;int tail = 0;int count = 0;float avg;// 循环处理输入信号for (int i = 0; i < sizeof(input_signal) / sizeof(int); i++) {// 限制幅度int limited_value = input_signal[i];if (limited_value > threshold) {limited_value = threshold;}// 滑动窗口进队window[tail] = limited_value;tail = (tail + 1) % WINDOW_SIZE;if (count < WINDOW_SIZE) {count++;}// 计算平均值avg = 0;for (int j = 0; j < count; j++) {avg += window[head];head = (head + 1) % WINDOW_SIZE;}avg /= count;// 打印滤波后的信号printf("Filtered signal: %.2f\n", avg);}return 0;
}

总结

大家可以取其精华然后结合具体进行应用。

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

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

相关文章

【算法集训】基础算法:贪心

1913. 两个数对之间的最大乘积差 void insertSort(int * a, int n) {for(int i 1; i < n; i) {int temp a[i];int j i - 1;while(j > 0 && temp < a[j]) {a[j 1] a[j];j--;}a[j 1] temp;} }int maxProductDifference(int* nums, int numsSize){insert…

什么是Java语言的反射机制?

什么是反射 反射&#xff08;Reflection&#xff09;主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。&#xff08;就像照镜子反射一样&#xff09; Java反射机制是指在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&…

大模型时代,各行各业该如何抓住AI大模型的机遇

AI大模型&#xff1a;跨界的智慧融合&#xff0c;驱动未来生活与工作的革新 在数字化浪潮席卷全球的今天&#xff0c;人工智能&#xff08;AI&#xff09;作为引领未来发展的重要力量&#xff0c;正在不断地改变着我们的生活和工作方式。AI大模型学习作为其中的重要分支&#…

外包干了一个月,忘记Git怎么使用了...

外包干了一个月&#xff0c;忘记Git怎么使用了… Git 是一个流行的版本控制系统&#xff0c;它允许开发人员跟踪和管理代码更改。在本篇文章中&#xff0c;我们将介绍 Git 的配置和使用命令&#xff0c;以帮助您更好地理解和使用这个强大的工具。 首先&#xff0c;让我们开始…

docker -compose运行时端口被占用异常

解决方法&#xff1a;在docker-compose.yml文件中去掉端口的配置&#xff08;去掉下图圈住部分&#xff09;&#xff0c;我们要启动5个&#xff0c;配置了端口我们只能启动一个&#xff0c;所以就会报错

Android Studio实现内容丰富的安卓教学学习平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号088 1.开发环境 android stuido3.6 jak1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看教学视频资料 3.播放教学视频 4.浏览作业&#…

Android Framework 基础篇 之 C++

C语法入门 目录 C语法入门 一、变量和数据类型 二、运算符 三、条件语句 四、循环语句 五、函数 六、类和对象 七、指针 八、数组与字符串 九、文件操作 十、STL&#xff08;标准模板库&#xff09; 十一、异常处理 十二、模板 十三、命名空间 十四、操作符重载…

超清gif怎么制作?教你制作gif动图的小窍门

Gif动画作为当下非常受欢迎的一种图片格式&#xff0c;在各种社交软件中也经常的常见。而制作gif动图也没有大家想象的那么难&#xff0c;只需要使用gif动态图片制作&#xff08;https://www.gif.cn/&#xff09;工具&#xff0c;不用下载软件。上传jpg、png格式的图片&#xf…

奶瓶哪个品牌质量比较好?五大热销奶瓶实力全解析

相信每个宝妈宝爸在选奶瓶的时候都犹豫住了&#xff0c;市面上的款式和品牌五花八门&#xff0c;完全不知道怎么选。而且还有很多商家为了减少成本花销&#xff0c;开始采用大量不耐高温、不防腐蚀的材料进行加工&#xff0c;如果选到这种没有经过优化过的产品带回家&#xff0…

AcWing 796. 子矩阵的和

这个题的重点是仿照一维的数组&#xff0c;所以a[N][N]也是从1索引开始的。画个图举个例子就非常清晰了 之所以不好理解是因为没画格子&#xff0c;一个格子代表一个点&#xff0c;就很好理解了。 java代码&#xff1a; import java.io.*; public class Main{static int N 1…

C语言经典算法-5

文章目录 其他经典例题跳转链接26.约瑟夫问题&#xff08;Josephus Problem&#xff09;27.排列组合28.格雷码&#xff08;Gray Code&#xff09;29.产生可能的集合30.m元素集合的n个元素子集 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. …

如何在 Postman 中执行断言测试?

在当今的软件构建流程中&#xff0c;应用程序编程接口&#xff0c;简称 API&#xff0c;起到了不可或缺的作用&#xff0c;它们使得不同的软件应用能够互相沟通和交换数据。随着应用程序的不断演进变得越发复杂&#xff0c;保障API的可靠性及其稳定性显得格外关键。正因如此&am…

【NLP】关于Transformer模型的一些认知

目录 一. Transformer模型简介 二. Transformer模型的架构 1. 编码器&#xff1a; 2. 解码器&#xff1a; 三. Transformer模型中残差连接层的作用 四. Transformer模型中, 输入部分的位置编码&#xff08;PisitionalEncoding&#xff09;矩阵为什么要使用三角函数对奇数…

人脸聚类原理和算法解释

人脸聚类是指将大量人脸图像根据它们的相似性分组到不同的群集中的过程。人脸聚类通常利用人脸的特征向量表示来度量人脸之间的相似性&#xff0c;并将相似的人脸图像聚集在一起。 以下是人脸聚类的一般原理&#xff1a; 人脸特征提取&#xff1a;对每张人脸图像提取特征向量。…

vue3使用eventBus,模拟一个事件车

vue3使用eventBus需要自己定义一个ts文件来模拟事件车&#xff0c;先创建一个ts文件 class eventBus {list: { [key: string]: Array<Function> };constructor() {// 收集订阅信息,调度中心this.list {};}// 订阅$on(name: string, fn: Function) {// this.list[name] …

美摄科技剪同款SDK解决方案全面升级

视频内容已成为企业宣传、品牌塑造和市场营销的重要载体。然而&#xff0c;如何快速、高效地制作出高质量的视频内容&#xff0c;成为摆在众多企业面前的一大难题。针对这一挑战&#xff0c;美摄科技凭借深厚的技术积累和创新能力&#xff0c;推出了全新的剪同款SDK解决方案&am…

亮数据Bright Data,跨境电商一站式解决方案

目录 一、跨境电商的瓶颈1、技术门槛2、语言问题3、网络稳定性4、验证码处理和自动识别5、数据安全6、法律法规 二、机不可失三、动态住宅代理1、网络代理2、动态住宅代理3、动态住宅代理的主要优点 四、动态住宅代理的使用场景五、如何使用亮数据动态代理1、开始使用2、添加新…

上海王梓标准件制造有限公司隆重参加上海紧固件专业展

随着全球工业制造业的高速发展&#xff0c;标准件行业做为基础部件的供应链环节越来越受到重视。标准件&#xff0c;这类微不足道的小零件&#xff0c;在维护工业世界的稳定和发展中是至关重要的。在这样一个紧要关头&#xff0c;上海王梓标准件制造有限公司&#xff08;下称“…

Linux hook系统调用使你文件无法删除

文章目录 前言一、什么是hook技术二、Linux hook种类三、系统调用表hook3.1 查看删除文件用到系统调用3.2 获取系统调用函数3.3 编写hook函数3.4 替换hook函数3.5 测试 参考资料 前言 hook技术在Linux系统安全领域有着广泛的应用&#xff0c;例如通过hook技术可以劫持删除文件…

多源BFS - 01矩阵

LCR 107. 01 矩阵 到最近的0的距离&#xff0c;对每一个非0的位置进行搜索&#xff0c;找到最短的距离即可&#xff0c;但如果对每一个非0的点都进行一次搜索的话&#xff0c;肯定是会超时的。这里可以考虑&#xff0c;将所有0点想象成一个0点(超级0)。然后找到所有1点到超级0的…