| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> STM32 ADC DMA通道数减小引发的异常问题及解决 -> 正文阅读 |
|
[嵌入式]STM32 ADC DMA通道数减小引发的异常问题及解决 |
一、基础知识在讲具体问题之前先列出STM32系列单片机ADC部分的一些知识: ADC控制器STM32一共有3个ADC控制器:ADC1、ADC2、ADC3。 18个通道STM32的ADC多达18个通道:16个外部通道和2个内部信号源。
一共支持23个引脚支持ADC,包括21个外部和2个内部信号源。 STM32F10x系列芯片ADC通道和引脚对应关系如下图所示: ADC的转换模式
扫描模式简单地说是一次对全部所选中的通道进行转换。假设开了ch0、ch1、ch4、ch5,通道0转换完之后就会自动依次转换通道1、4、5,直到转换完,这个过程不能被打断。若是开启了连续转换模式,则会在转换完ch5以后开始新一轮的转换。 这就引入了间断模式,可以说是对扫描模式的一种补充。它能够把ch0、ch1、ch4、ch5这四个通道进行分组。既能够分成0、1一组,4、5一组;也能够每一个通道单独配置为一组。这样每一组转换以前都须要先触发一次。 ADC单通道
ADC多通道
也就是说:多通道必须使能扫描模式。 左对齐或右对齐由于ADC获得的数据是12位精度的,而数据存储在16位数据寄存器中,因此ADC的存储结果能够分为左对齐或右对齐方式(12位),如下表所示: ADC输入通道从ADCx_INT0-ADCx_INT15对应三个ADC的16个外部通道,进行模拟信号转换。此外,还有两个内部通道:温度检测和内部电压检测。选择对应通道以后,便会选择对应GPIO引脚,相关的引脚定义和描述可参见数据手册。 注入通道,规则通道在选择了ADC的相关通道引脚以后,在模拟至数字转换器中有两个通道:注入通道、规则通道。 规则通道 规则通道是关于你正常运行的程序,看它的名字就能够知道,很规矩,就是正常执行程序。 注入通道 注入通道能够打断规则通道,听它的名字就知道不安分,若是在规则通道转换过程当中,有注入通道进行转换,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程。 DMAADC还支持DMA触发,规则和注入通道转换结束后会产生DMA请求,用于将转换好的数据传输到内存。 注意,只有ADC1和ADC3能够产生DMA请求。 CubeMX中ADC配置项
对应Init.DataAlign。设置数据的对齐方式。
对应Init.ScanConvMode。是否开启扫描模式。若是只是用了一个通道的话,DISABLE就能够了(也只能DISABLE);若是使用了多个通道的话,会自动设置为ENABLE。
对应Init.Continuous。设置为ENABLE,即连续转换;若是设置为DISABLE,则是单次转换。二者的区别在于连续转换直到全部的数据转换完成后才中止转换,而单次转换则只转换一次数据就中止,要再次触发转换才能够进行转换。
对应Init.DiscontinuousConvMode。
对应Init.NbrOfConversion。用到多少个通道就设置为多少。
对应Init.ExternalTrigConv。设定ADC的触发方式。
对应sConfig.Rank。多个通道时会有多个Rank,能够设定每一个通道的转换顺序。
对应sConfig.SamplingTime。 ADC相关接口函数开启(启动)ADC 开启(启动)ADC有3种模式,分别是:轮询模式、中断模式、DMA模式。
HAL_ADC_Start?
HAL_ADC_Start_IT
HAL_ADC_Start_DMA 关闭(停止)ADC 相应地,关闭(停止)ADC也有3中模式,分别是:轮询模式、中断模式和DMA模式。
HAL_ADC_Stop
HAL_ADC_Stop_IT
HAL_ADC_Stop_DMA ADC校准 HAL_ADCEx_Calibration_Start 注:F4系列不支持此接口 读取ADC转换值 HAL_ADC_GetValue 等待转换结束函数 HAL_ADC_PollForConversion ADC中断回调函数 HAL_ADC_ConvCpltCallback 注:转换完成后回调,DMA模式下DMA传输完成后调用 规则通道配置 HAL_ADC_ConfigChannel 看门狗配置 HAL_ADC_AnalogWDGConfig 二、所遇问题项目中原来使用的ADC通道数为16,新的项目只使用了4路AD,因此通道数缩减为4。针对于次变化,对旧有程序做了相关的修改,主要涉及AD部分以及GPIO部分。但是,进行修改后出现了问题:原本运行正常的程序,变得响应非常慢,甚至无响应;而且读的AD值也不对,大多数数据本来有值,但一段时间后会无故变为0。仔细检查程序,并没有发现由老版本程序到新版本程序所做出的改变有什么问题和错误。进一步地,发现最基本的memset函数变得非常慢,而老版本程序中则无此问题。 正在百思不得其解、没有头绪的时候,一片博客文章如久旱逢甘雨般地出现了,地址如下:【STM32+cubemx】0008 HAL库开发:ADC的四种用法:轮询、中断、DMA、定时器触发_xiaobaibai_2021的博客-CSDN博客_adc中断触发方式 其中有这样一段内容,描述和解决的正是笔者所遇到的问题:
由于老板的通道数为16,DMA传输中断并不十分频繁,因此没有出现问题;而新版本中由于通道数大幅缩减至4,因此DMA传输中断频繁发生,导致移植在中断中执行,宏观上就表现为程序反应慢或者干脆无反应,以及其它一些匪夷所思的问题。 按照上面文章给出的建议,有两种解决方案: (1)将通道数增大,增加循环搬移数据的次数。这样会有一些冗余数据,如:将通道数设置为8,虽然问题能够解决,但是数据将是这样:ADC_CH0、ADC_CH1、ADC_CH2、ADC_CH3、ADC_CH0、ADC_CH1、ADC_CH2、ADC_CH3;而实际上只需要一次ADC_CH0、ADC_CH1、ADC_CH2、ADC_CH3。 (2)将AD采样时间设置长一些。这样每次的转换时间会变长。 最终笔者选用了第二种解决方案,将sConfig.SamplingTime由ADC_SAMPLETIME_1CYCLE_5改为了ADC_SAMPLETIME_7CYCLE_5。 经过测试,之前的问题现象都消失了,宏观上和老版本程序的表现一致了。 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/30 0:48:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |