STM32 LL库下ADC + DMA多通道连续扫描采集通道错乱问题记录

本文主要是介绍STM32 LL库下ADC + DMA多通道连续扫描采集通道错乱问题记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

         cubemx配置ADC+DMA转换后,代码在 adc.c 中将ADC_REG_InitStruct.DMATransfer 属性设置为:

        LL_ADC_REG_DMA_TRANSFER_UNLIMITED 或者

        LL_ADC_REG_DMA_TRANSFER_LIMITED(在MX中配置时只有这两选项)

,都会在初始化ADC时同时使能DMA。

/* ADC init function */
void MX_ADC_Init(void)
{/* USER CODE BEGIN ADC_Init 0 *//* USER CODE END ADC_Init 0 */LL_ADC_InitTypeDef ADC_InitStruct = {0};LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};LL_GPIO_InitTypeDef GPIO_InitStruct = {0};/* Peripheral clock enable */LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);/**ADC GPIO ConfigurationPA0   ------> ADC_IN0PA5   ------> ADC_IN5PA6   ------> ADC_IN6PA7   ------> ADC_IN7PB0   ------> ADC_IN8PB1   ------> ADC_IN9*/GPIO_InitStruct.Pin = OTP_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(OTP_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = VSENSE_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(VSENSE_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = OVP1_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(OVP1_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = OVP2_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(OVP2_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = SIGNAL1_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(SIGNAL1_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = SIGNAL2_Pin;GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;LL_GPIO_Init(SIGNAL2_GPIO_Port, &GPIO_InitStruct);/* ADC DMA Init *//* ADC Init */LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);/* USER CODE BEGIN ADC_Init 1 *//* USER CODE END ADC_Init 1 *//** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_0);/** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_5);/** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_6);/** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_7);/** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_8);/** Configure Regular Channel*/LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_9);/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)*/ADC_InitStruct.Clock = LL_ADC_CLOCK_ASYNC;ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;LL_ADC_Init(ADC1, &ADC_InitStruct);ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD);LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_239CYCLES_5);/* USER CODE BEGIN ADC_Init 2 *//* USER CODE END ADC_Init 2 */}

开启通道转换前,如果调用了 LL_ADC_StartCalibration 开启ADC校准,ADC的DMA转换通道顺序会错乱(比如原本通道0的数据会跑掉其他通道去),在该函数的表述中就有 

        In case of usage of ADC with DMA transfer:
  *         On this STM32 serie, ADC DMA transfer request should be disabled
  *         during calibration:  * @note   In case of usage of ADC with DMA transfer:
  *         On this STM32 serie, ADC DMA transfer request should be disabled
  *         during calibration:
  *         Calibration factor is available in data register
  *         and also transfered by DMA.
  *         To not insert ADC calibration factor among ADC conversion data
  *         in array variable, DMA transfer must be disabled during
  *         calibration.
  *         (DMA transfer setting backup and disable before calibration,
  *         DMA transfer setting restore after calibration.
  *         Refer to functions @ref LL_ADC_REG_GetDMATransfer(),
  *         @ref LL_ADC_REG_SetDMATransfer() ).

/*** @brief  Start ADC calibration in the mode single-ended*         or differential (for devices with differential mode available).* @note   On this STM32 serie, a minimum number of ADC clock cycles*         are required between ADC end of calibration and ADC enable.*         Refer to literal @ref LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES.* @note   In case of usage of ADC with DMA transfer:*         On this STM32 serie, ADC DMA transfer request should be disabled*         during calibration:*         Calibration factor is available in data register*         and also transfered by DMA.*         To not insert ADC calibration factor among ADC conversion data*         in array variable, DMA transfer must be disabled during*         calibration.*         (DMA transfer setting backup and disable before calibration,*         DMA transfer setting restore after calibration.*         Refer to functions @ref LL_ADC_REG_GetDMATransfer(),*         @ref LL_ADC_REG_SetDMATransfer() ).* @note   On this STM32 serie, setting of this feature is conditioned to*         ADC state:*         ADC must be ADC disabled.* @rmtoll CR       ADCAL          LL_ADC_StartCalibration* @param  ADCx ADC instance* @retval None*/
__STATIC_INLINE void LL_ADC_StartCalibration(ADC_TypeDef *ADCx)
{/* Note: Write register with some additional bits forced to state reset     *//*       instead of modifying only the selected bit for this function,      *//*       to not interfere with bits with HW property "rs".                  */MODIFY_REG(ADCx->CR,ADC_CR_BITS_PROPERTY_RS,ADC_CR_ADCAL);
}

 由于在初始化时开启了DMA使能,会导致ADC在校准时产生的数据也被DMA搬运;应在 LL_ADC_StartCalibration 前 ADC_REG_InitStruct.DMATransfer 设置为 LL_ADC_REG_DMA_TRANSFER_NONE

LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);

关闭ADCDMA转换使能;

这篇关于STM32 LL库下ADC + DMA多通道连续扫描采集通道错乱问题记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/388785

相关文章

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu