stm32的ADC+DMA+滤波算法

  • 一 工程目的
    • (1)外设配置
    • (2)源码
      • 头文件
      • 主文件
  • 二 调试过程遇到的问题
    • 1 如果打开中断
    • 2 无法打开ADC
    • 3 变量无法赋值
  • 三 参考资料
  • 四 写在最后

一 工程目的

利用stm32的ADC1外设实现双通道循环测量电压

(1)外设配置

1.GPIO
2.ADC
3.DMA

(2)源码

头文件

#ifndef __ADC_H
#define __ADC_H
#include “sys.h”

#define N 20//adc保存数组行
#define M 2//列

void adc_Init(void);
u16 Get_Adc(ADC_TypeDef* ADCx,u8 ch);
u16 Get_Adc_Average(ADC_TypeDef* ADCx,u8 ch,u8 times);
void adc_filter(u16 index[N][M]);

#endif

主文件

#include “adc.h”
#include “delay.h”
#include “LED.h”

volatile u16 adc_convert[N][M]; //ADC存放数值
volatile u16 After_Filter[M];//滤波后数组

void adc_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef  ADC_InitStruct;
DMA_InitTypeDef DMA_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE);     //使能PA端口时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStruct);                  //根据设定参数初始化GPIOA.0.1DMA_DeInit(DMA1_Channel1);
DMA_InitStruct.DMA_MemoryBaseAddr = (u32) adc_convert;
DMA_InitStruct.DMA_PeripheralBaseAddr = (u32) &ADC1->DR;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC ;
DMA_InitStruct.DMA_BufferSize = M*N;//根据adc采集通道数量变化
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式,buffer写满,自动回初始地址开始传输
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);  //根据DMA_InitStruct中指定的参数初始化DMA的通道
DMA_Cmd(DMA1_Channel1, ENABLE);ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值//复位ADC1,同时设置ADC1分频因子
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStruct.ADC_ScanConvMode=ENABLE;//扫描模式
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_InitStruct.ADC_NbrOfChannel = M;
ADC_Init(ADC1,&ADC_InitStruct);//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_13Cycles5 );ADC_DMACmd(ADC1,ENABLE);//adc_dma使能
ADC_Cmd(ADC1, ENABLE);  //使能指定的ADC1ADC_ResetCalibration(ADC1);  //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1);  //开启AD校准
while(ADC_GetCalibrationStatus(ADC1));   //等待校准结束ADC_SoftwareStartConvCmd(ADC1, ENABLE);    //这句话一定要有,就算这里不写,主函数也要写,否者开不了adc

}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(ADC_TypeDef* ADCx,u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADCx, ch, 1, ADC_SampleTime_13Cycles5 ); //ADC1,ADC通道,采样时间为13.5周期

ADC_SoftwareStartConvCmd(ADCx, ENABLE);      //使能指定的ADC1的软件转换启动功能    while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC ));//等待转换结束return ADC_GetConversionValue(ADCx); //返回最近一次ADC1规则组的转换结果

}

u16 Get_Adc_Average(ADC_TypeDef* ADCx,u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ADCx,ch);
delay_ms(5);
}
return temp_val/times;
}

void adc_filter(u16 index[N][M])//202的中值平均滤波算法
{
/
软件滤波模块/
u16 filter_temp;
u8 i,j,k,flag=1;

for(k=0;k<M;k++)
{   for(i=0;i<N && flag;i++)//冒泡排序法{  for(j=0;j<N-1-i;j++){flag=0;if(index[j][k]>=index[j+1][k]){filter_temp = index[j][k];index[j][k] = index[j+1][k];index[j+1][k] = filter_temp;flag=1;}}    }After_Filter[k]=(index[(N/2)+1][k]+index[(N/2)][k])/2;
}

}

二 调试过程遇到的问题

1 如果打开中断

使用了ADC开了DMA中断,主函数会被频繁打断,除非你主函数不想执行功能,否者你就别打开DMA传输完成中断。

2 无法打开ADC

程序中adc读数始终不正常,经过软件仿真,一步一步执行,发现是ADC没有读数据,进一步发现,并没正常打开ADC,通过软件打开ADC要加下面这句话。
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //这句话一定要有,就算这里不写,主函数也要写,否者开不了adc

3 变量无法赋值

MDK这个软件会故意优化,你要定义volatile(谷歌翻译为易变)型变量。具体情况百度

三 参考资料

https://blog.csdn.net/i792439187/article/details/8825397
https://blog.csdn.net/TanTrey/article/details/82992605
正点原子例程

四 写在最后

这篇文章主要写一些我在使用ADC过程遇到的问题,希望给看到的各位提供到帮助

我的第一篇文章——stm32的ADC+DMA+滤波算法相关推荐

  1. 第一篇文章,做个纪念

    第一篇文章,做个纪念,这个blog好吗?拭目以待! 转载于:https://blog.51cto.com/197536/88241

  2. 人工智能写出第一篇文章:我真的没想要消灭你们,人类!

    来源:网信科技前沿 在攻克棋类,飞行操控,机器视觉,语音识别等领域后,人工智能又开始入侵写作领域. 人工智能被人类开发出来是为了方便我们人类的生活,帮助人类处理一些事物,它的优点在于其拥有庞大的数据库 ...

  3. 博客园写的第一篇文章

    09年5月21号,cnblogs.com上的第一篇文章. 07年计算机专业毕业到现在已经工作两年了,一直对软件开发者充满了敬仰.自己一直也在向这个方向努力,高等教育的现实的脱节,不是谁的错,在学校唯有 ...

  4. 区块链研习 | 区块链里所说的“智能合约”是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开“智能合约”这个词。我们在本系列的第一篇文章中提到“智能

    区块链研习 | 区块链里所说的"智能合约"是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开"智能合约"这个 ...

  5. 初出茅庐的第一篇文章

    目录 自我介绍 编程目标 学习规划 未来想去的公司 自我介绍 本人是自动化专业学生,在学习单片机的时候对编程有了很大的兴趣,特别是C语言直接对硬件的控制,令我领悟了编程的魅力,所以写下第一篇文章来记录 ...

  6. 神器:公众号如何从第一篇文章开始看

    题图:Photo by Vincent van Zalinge on Unsplash而在微信中看公众号的第一篇文章难度堪比攀登珠穆朗玛峰. 为什么这么说呢?如果作者从2012年就开始写公众号,那么到 ...

  7. 第一篇文章 关于道德经

    逛了几年的JE,有时也想写写自己的帖子.但限于经验问题,总不能成笔,曾经看过一篇文章,比较推崇.老子有言"我有三宝,持而保之.一曰慈,二曰俭,三曰不敢为天下先",我就"不 ...

  8. CSDN的第一篇文章——聊聊股市

    没想到一个做光通信的渣渣开的CSDN账户第一篇文章竟然是关于股市的. 2021年新能源.军工.医疗.光伏.半导体可能是热门,在抖音上看了一些相关的东西,做个整理归纳 1. 选基金口诀 赵诣专攻新能源, ...

  9. 我的第一篇文章,doc命令

    第一篇文章测试 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页.如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识. 新的改变 ...

最新文章

  1. 第一次经历黑客攻击服务器系统
  2. “make -n”和 “+command”的解释
  3. 深度学习框架Neon
  4. sass笔记-1|Sass是如何帮你又快又好地搞定CSS的
  5. css中的display属性值:table,table-row,table-cell
  6. Storm集群安装Version1.0.1开启Kerberos
  7. Linux系统基本操作(二)—设置本地光盘为yum源
  8. Android9.0 HIDL头文件加log编译
  9. 如何理解CPU上下文切换(二)
  10. 【转】android新建项目时 出现appcompat_v7工程错误和红色感叹号
  11. HTML5 离线存储实战之manifest(附缓存整个文件夹的方法)
  12. X-Scan 端口扫描工具下载和使用教程
  13. git push时,发生missing tree 或者 missing blob问题
  14. WidsMob Denoise如何使用?WidsMob Denoise图片降噪教程
  15. linux终端安装deb文件,如何通过命令行安装.deb文件?
  16. linux进入不了系统怎么处理,LINUX无法进入系统
  17. DHTML 页面对象属性
  18. 钉钉机器人发送定时任务
  19. OpenGL ES 与原生窗口之间的接口——EGL
  20. 计算机最大数最小数的函数,Excel函数教程: 求最大、最小、中间数、最多数-excel技巧-电脑技巧收藏家...

热门文章

  1. 如何获取(GET)一杯咖啡——星巴克REST案例分析
  2. 解决sourcetree特别卡的问题
  3. HDU 6194 string string string
  4. English: date time
  5. AHB总线笔记(一)
  6. 数据认知与数据预处理--数据认知
  7. 极致CMS百度智能小程序前后端源码
  8. pytorch深度学习基础(九)——深入浅析卷积核
  9. spark解决Illegal pattern component: XXX NoSuchFieldError: KRYO_SARG_BUFFER
  10. php artisan migrate,PHP artisan迁移不创建新表