借助DMA可以快速采集大量数据,如果数据采集过来却不使用就是浪费。在我的板子上,AD值代表温度,如果系统检测到温度过高,可能会采取一些强制的保护措施。而AD采样是容易受干扰的,所以要对采样数据进行滤波,减少噪声对系统的干扰。接下来我们采用计算平均值的算法来滤波。
我们从每256个数据中,提取出1个算数平均值。2个通道,每个通道采集256个数据的话,共需要采集512个数据。由于DMA转换数据是循环进行的,如果等512个数据全部采集完,再做算数平均的话,新的数据已经采集完毕,旧的数据被覆盖,发生了改变。因此可以采用分两段处理的思想。
开启一个1024大小的数组,在前半段转化完成时,也就是前512个数据个数据已经处理完毕的时候,遍历前512个数据,计算算数平均值。此时DMA正在处理后512个数据,并且需要保证在后半段数据处理完之前,计算完前半段数据的平均值。然后等DMA处理完所有的数据以后,会从头开始,重新转换数据。我们要赶在DMA处理前半段数据的期间,计算出后半段数据的平均值。
HAL库提供了HAL_ADC_ConvHalfCpltCallback函数,在转换完成一半时会调用。另外,由于前512个数据包含了两个通道的AD值,所以要分开计算平均值。函数HAL_ADC_ConvCpltCallback在转换完成时调用。为了区分是前半段还是后半段的数据处理,可以新增标志位。
//AD.c
u8 DMA_FLG = 0;
uint32_t ADC1_RANK1_AVG = 0;
uint32_t ADC1_RANK2_AVG = 0;
/**
* @brief 获取不同通道的平均值
* @param DMA转换进度,是前一半还是后一半
* @retval None
*/
void Get_ADC_Avg(u8 flg)
{
int start,end;
int ADC1_RANK1_SUM = 0;
int ADC1_RANK2_SUM = 0;
if(flg)//DMA后半段
{
start = ADC_CHANNEL_CNT>>1;
end = ADC_CHANNEL_CNT;
}
else
{
start = 0;
end = ADC_CHANNEL_CNT>>1;
}
for(int i = start; i < end;i++)
{
if(0 == i%2)//偶数
{
ADC1_RANK1_SUM += AD_Buf[i];
}
else
{
ADC1_RANK2_SUM += AD_Buf[i];
}
}
ADC1_RANK1_AVG = ADC1_RANK1_SUM/(ADC_CHANNEL_CNT>>2);
ADC1_RANK2_AVG = ADC1_RANK2_SUM/(ADC_CHANNEL_CNT>>2);
}
/**
* @brief ADC通道转化结束以后触发回调函数
* @param 触发转换完成中的的ADC句柄
* @retval None
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc==(&hadc1))
{
DMA_CNT++;
DMA_FLG = 1;
Get_ADC_Avg(DMA_FLG);
}
}
/**
* @brief ADC通道转化完成一半时触发回调函数
* @param 触发转换完成中的的ADC句柄
* @retval None
*/
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc==(&hadc1))
{
DMA_FLG = 0;
Get_ADC_Avg(DMA_FLG);
}
}
在main函数中,打印平均AD值,并区分是前/后半段处理的结果。
//main()
while (1)
{
HAL_Delay(1000);
printf("采样次数: %d\n",ADC_CHANNEL_CNT/2);
printf("TempA均值 %d ;TempB均值 %d. \n",ADC1_RANK1_AVG,ADC1_RANK2_AVG);
if(DMA_FLG)
printf("当前是后半段\n");
else
printf("当前是前半段\n");
printf("DMA采集数据的次数是 %d\n",DMA_CNT);
DMA_CNT=0;
}
观察现象可以发现,当1s的时间到达的时候,刚刚处理的是DMA的前半段数据还是后半段,并不能确定。但不论是前后半段,由于这种类似于“互斥”做法,在读取数据计算平均值的时候,可以保证数据没有被“篡改”。
文章浏览阅读1.4k次,点赞67次,收藏75次。上一篇在进程中提到了【Linux】进程状态&&僵尸进程和孤儿进程&&阻塞、挂起和运行,这次来继续来谈进程。在进程的PCB中存在一个进程的优先级,那么什么是进程的优先级?进程的优先级就是指定一个进程获取某种资源的顺序。进程中使用task_struct进程控制块结构体中的内部字段用一个整型prio表示优先级。Linux中优先级数字越小,优先级越高。比较一下优先级和权限:权限决定一件事能不能做,而有优先级就表示一件事情能做只是代表获取资源的顺序。
文章浏览阅读6.5k次,点赞6次,收藏68次。通常振动信号为一时间序列,衡量振动信号的指标包括时域指标和频域指标,网上分享计算公式和源程序的比较少,本文给出了公式定义以及matlab/python源码。常见时域指标:对应的Matlab程序%%%%matlab程序close allclearclcst = 0.01;data = sin(0:st:10);Xr = mean(sqrt(abs(data)))*mean(sqrt(abs(data)));Xmean = mean(abs(data));Xrms = rm_振动信号时域分析
文章浏览阅读1.4k次。敲《Python机器学习及实践》上的code的时候,对于数据预处理中涉及到的fit_transform()函数和transform()函数之间的区别很模糊,查阅了很多资料,这里整理一下:涉及到这两个函数的代码如下:# 从sklearn.preprocessing导入StandardScalerfrom sklearn.preprocessing import StandardScale..._fit_transform函数参数
文章浏览阅读1.2k次。图文并茂走迷宫_一起talk c栗子吧
文章浏览阅读666次,点赞29次,收藏20次。JAVA:Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。Vue:Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的JavaScript框架。
文章浏览阅读1.3k次,点赞72次,收藏27次。字节序——是以字节为单位,来讨论存储顺序的其实超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。
文章浏览阅读1.2w次,点赞5次,收藏18次。USB数据线的调试方式,大家应该比较常用,今天就专门说说怎么在不使用USB数据线的方式下进行安卓的开发调试。_不使用usb调试连接电脑
文章浏览阅读2.7k次,点赞2次,收藏2次。但在 SQLyog 上查看时却是不存在的。这是因为 MySQL 异常停止后,导致某些文件丢失或损害引起的,具体为什么会到至 MySQL 异常停止,只能进一步查看。本地 MySQL 异常停止后,手动启动服务,热庵后执行 sql 脚本时,发现又报错信息,于是手动创建表,发现还是无法创建,报了。表空间已存在,在导入数据之前需要将表空间释放掉。_please discard the tablespace before import.
文章浏览阅读2.7k次,点赞11次,收藏28次。四足机器人|机器狗|仿生机器人|多足机器人|PPT|汇报|科研汇报PPT|技术汇报_四足机器人关键技术ppt
文章浏览阅读1k次。org.springframework.data.redis.serializer.SerializationException: Could not read JSON将数据存储到redis中报错,由于对象(实体)中缺少json的某个字段属性引起解决办法。@JsonIgnoreProperties(ignoreUnknown = true) _org.springframework.data.redis.serializer.serializationexception: could not
文章浏览阅读375次。在本节中,将设置商品提醒组件,当用户点击‘Notify Me’的时候,像商品列表组件发出事件。1、打开 product-alerts.component.ts, 从 @angular/core 中导入 Output 和 EventEmitter。2、在组件类中,用 @Output 装饰器和一个事件发射器(EventEmitter)实例定义一个名为 notify 的属性。这可以让商品提醒组件在 ..._angular notifychange$
文章浏览阅读661次。一周时间快速阅读了400页的《javascript基础教程》,理解了主要概念。解决了一个很久之前的疑问。我的网站是使用flask框架搭建的,介绍flask web的一本著名的书(之前提到过)作者搭建个人博客时,向读者推荐了flask-bootstrap,flask_moment这两个库,前者能快速的解决前端样式问题,后者提供了时间戳功能。但在某种情况下,比如网络延迟或者运营商的问题,访问网..._bootstrap 速度慢 maxcdn