STM32H7A3 ADC+DMA使用问题

2023-05-16

问题1:DMA采用半字传输16位ADC值,用于存储ADC数据的数组一定是采集数的两倍,否则会产生ADC溢出的错误中断HAL_ADC_ErrorCallback,从而无法进入ADC采集完成中断HAL_ADC_ConvCpltCallback。具体为什么是两倍,网上有很多解释,有兴趣的可以去查一下。

问题2:在使用ADC+DMA采集的时候突然发现一个奇怪的现象,就是只要在程序的任何一个地方再申请一个全局变量,ADC就会出现错误中断HAL_ADC_ErrorCallback。最后发现程序没有什么问题,就怀疑和初始化顺序相关,然后就使用STM32CUBEMX配置了一下ADC+DMA,看一下配置出来的初始化顺序,然后改成和CUBEMX配置顺序一样的,这个问题就解决了。


void ADC_Init(void)
{  
    ADC_ChannelConfTypeDef sConfig = {0};
	
	AdcHandle.Instance = ADC1;
    AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; 
    AdcHandle.Init.Resolution = ADC_RESOLUTION_16B; 
    AdcHandle.Init.ScanConvMode = ADC_SCAN_ENABLE; 
    AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; 
    AdcHandle.Init.LowPowerAutoWait = DISABLE; 
    AdcHandle.Init.ContinuousConvMode = ENABLE; 
    AdcHandle.Init.NbrOfConversion = 3; 
    AdcHandle.Init.DiscontinuousConvMode = DISABLE; 
    AdcHandle.Init.NbrOfDiscConversion = 1; 
    AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; 
    AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; 
    AdcHandle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; 
    AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; 
    AdcHandle.Init.OversamplingMode = DISABLE; /* 禁止过采样 */
    /* 初始化 ADC */
    if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
    {
    }
    /* 校准 ADC,采用偏移校准 */
    if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
    {
    }
	
	
	/*黄灯对应采集通道*/
    sConfig.Channel = ADC_CHANNEL_3; /* 配置使用的 ADC 通道 */
    sConfig.Rank = ADC_REGULAR_RANK_1; /* 采样序列里的第 1 个 */
    sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5; /* 采样周期 */
    sConfig.SingleDiff = ADC_SINGLE_ENDED; /* 单端输入 */
    sConfig.OffsetNumber = ADC_OFFSET_NONE; /* 无偏移 */
    sConfig.Offset = 0; /* 无偏移的情况下,此参数忽略 */
    sConfig.OffsetRightShift = DISABLE; /* 禁止右移 */
    sConfig.OffsetSignedSaturation = DISABLE; /* 禁止有符号饱和 */
	HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	

	sConfig.Channel = ADC_CHANNEL_7; /* 配置使用的 ADC 通道 */
    sConfig.Rank = ADC_REGULAR_RANK_2; /* 采样序列里的第 1 个 */
    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	

	sConfig.Channel = ADC_CHANNEL_4; /* 配置使用的 ADC 通道 */
    sConfig.Rank = ADC_REGULAR_RANK_3; /* 采样序列里的第 1 个 */
    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	

	sConfig.Channel = ADC_CHANNEL_9; /* 配置使用的 ADC 通道 */
    sConfig.Rank = ADC_REGULAR_RANK_4; /* 采样序列里的第 1 个 */
    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	
	
    /* 启动 ADC 的 DMA 方式传输 */
    if (HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)adc_buf, 3) != HAL_OK)
    {
    }

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
    /* ADC1 clock enable */
    __HAL_RCC_ADC12_CLK_ENABLE();
    __HAL_RCC_DMA1_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	
	ADC1DMA_Handler.Instance = DMA1_Stream1; 
    ADC1DMA_Handler.Init.Request = DMA_REQUEST_ADC1; 
    ADC1DMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY; 
    ADC1DMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
    ADC1DMA_Handler.Init.MemInc = DMA_MINC_ENABLE; 
    ADC1DMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; 
    ADC1DMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; 
    ADC1DMA_Handler.Init.Mode = DMA_CIRCULAR; 
    ADC1DMA_Handler.Init.Priority = DMA_PRIORITY_LOW; 
    ADC1DMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 
    ADC1DMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; 
    ADC1DMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE; 
    ADC1DMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;
    if(HAL_DMA_Init(&ADC1DMA_Handler) != HAL_OK)
    {
    }

	__HAL_LINKDMA(&AdcHandle, DMA_Handle, ADC1DMA_Handler);
	/* DMA interrupt init */
    /* DMA1_Stream0_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
    /* Peripheral clock disable */
    __HAL_RCC_ADC12_CLK_DISABLE();
    __HAL_RCC_DMA1_CLK_DISABLE();

    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_4|GPIO_PIN_5);
  }
}


void DMA1_Stream1_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&ADC1DMA_Handler);
}


void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
  
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32H7A3 ADC+DMA使用问题 的相关文章

  • I/O的控制方式——查询,中断,dma

    早期 xff0c I O串行 xff0c 查询方式 发展 xff0c I O并行 xff0c 两种方式其一是中断方式 xff0c 其二是dma方式 xff0c 使得外部设备能直接与主存储器信息交换 xff0c 减轻了cpu的工作量 技术继续
  • FIFO与DMA

    FIFO存储器是一个先入先出的双口缓冲器 xff0c 即第一个进入其内的数据第一个被移出 xff0c 其中一个存储器的输入口 xff0c 另一个口是存储器的输出口 主要有三个方面的作用 xff1a 1 xff09 对连续的数据流进行缓存 x
  • FIFO和DMA

    FIFO SPI端口增加了FIFO xff0c 使得传输数据有了缓冲区间 FIFO存储器是一个先入先出的双口缓冲器 xff0c 即第一个进入其内的数据第一个被移出 xff0c 其中一个存储器的输入口 xff0c 另一个口是存储器的输出口 主
  • stm32串口DMA方式向上位机连续发送数据

    目录 一 认识DMA1 DMA框图2 什么是DMA xff1f 3 DMA传输方式4 DMA传输参数5 DMA数据传输的四个要素6 DMA的应用场景 二 串口DMA方式向上位机发送数据1 实验要求2 通过STMCube配置项目 1 设置RC
  • 关于ADC的笔记1

    ADC xff0c 全称Anlog to Digital Converter xff0c 模拟 数字转换器 是指将连续变量的模拟信号转换为离散的数字信号的器件 xff0c 我们能通过ADC将外界的电压值读入我们的单片机中 常见的ADC有两种
  • AXI DMA总结、内核axidmatest.c测试程序分析、SG mode

    AXI DMA 概述 xff1a XILINX提供的AXI DMA支持Scatter Gather mode和Direct Register mode 数据位宽支持32 64 128 256 512 1024bits xff0c strea
  • 基于28035的ePWM触发ADC采样设计

    目录 前言实验目的实验要求硬件电路实验步骤代码解释实验结果总结体会 前言 玖道最近在做一个开关电源项目 xff0c 需要用到TI 的TMS320F28035 芯片 xff0c 实现控制电路的设计 简单来说就是利用28035采集信号量 xff
  • 模数转换ADC模块

    通用基础知识 ADC模块是嵌入式应用中重要的组成部分 xff0c 是嵌入式系统与外界连接的纽带 xff0c 是在测控系统中的重要内容 ADC模块 xff1a 即模数转换模块 AD转换模块 xff0c 功能是将电压信号转换为相应的数字信号 实
  • STM32F1应用DMA——串口收发不定长数据

    STM32F1应用DMA 串口收发不定长数据 使用STM32自带DMA传输数据 可以减轻CPU负担 只需设置一些参数即可发送想要发送的数据 以下是STM32F1系列芯片测试过的部分代码 可实现DMA串口收发数据 下图来自STM32官网的手册
  • 48脚STM32内部基准电压校准ADC的一些心得记录

    STM32的48脚的单片机因为没有Vref Vref 所以我们使用一些高精度参考电压芯片来提高ADC的精度很不方便 这里还有一种方法可以参考下 STM32内部有一个专门用于校准的稳压器VREFINT 它由外部的VSSA供电 他的电压一般为1
  • 负载均衡入门

    提纲 ADC 行业现状 ADC 原理 ADC 的实现方式 为什么是 ADC 而不是负载均衡 功能的扩展 解决了什么问题 可用性 Availability 伸缩性 Scalability 性能 End user performance 数据中
  • DSP T320F2803x 模数转换模块 ADC

    一 ADC 概览 1 1 特点 29803x 的 ADC 模块是12位循环 ADC 部分 SAR 部分流水线 其核心是 12 位的转换器 有两个采样保持器 可同时或顺序采样 通过多路复用后有 16 个模拟转换输入通道 转换器可以配置为与内部
  • STM32—ADC多通道采集电压

    文章目录 ADC详解 程序说明 函数主体 引脚配置 ADC和DMA配置 主函数 ADC详解 前面的博客中详细介绍了STM32中ADC的相关信息 这篇博客是对ADC内容的一个总结提升 ADC的详细介绍 ADC详解 程序说明 为了使这次代码阅读
  • 高速模数转换器(ADC)的INL/DNL测量

    摘要 尽管积分非线性和微分非线性不是高速 高动态性能数据转换器最重要的参数 但在高分辨率成像应用中却具有重要意义 本文简要回顾了这两个参数的定义 并给出了两种不同但常用的测量高速模数转换器 ADC 的INL DNL的方法 近期 许多厂商推出
  • simulink仿真 adc 采样ePWM输出例程

    新建文件夹并用matlab打开 写入这两个模块 配置 ADC 配置ePWM 不使能B 关了就行 其他的默认即可 配置烧录 连线 示波器接pwma1 和地 adc chanl1接 3 3v或者 0 3 3 都行 转化是 x 3 3 2 12
  • GD32F4xx MCU ADC+DMA 多通道采样

    1 GD32F4xx ADC GD32F4xx 的12位ADC是一种采用逐次逼近方式的模拟数字转换器 1 1 主要特征 可配置12位 10位 8位 6位分辨率 ADC采样率 12位分辨率为2 6MSPs 10位分辨率为3 0 MSPs 分辨
  • Linux内核设备驱动程序以DMA方式进入内核空间

    LDD3 p 453 演示dma map single使用作为参数传入的缓冲区 bus addr dma map single dev gt pci dev gt dev buffer count dev gt dma dir Q1 这个缓
  • Linux 内核中的 DMA 映射和 DMA 引擎是什么?

    Linux 内核中的 DMA 映射和 DMA 引擎是什么 DMA映射API和DMA引擎API何时可以在Linux设备驱动程序中使用 任何真正的 Linux 设备驱动程序示例作为参考都会很棒 Linux 内核中的 DMA 映射和 DMA 引擎
  • glBufferSubData什么时候返回? [复制]

    这个问题在这里已经有答案了 我想将一个非常大的内存块的内容传输到足够大的 GPU 缓冲区 然后立即更改 CPU 上的内存内容 伪代码是这样的 glBindBuffer very large buffer glBufferSubData ve
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015

随机推荐

  • UCOSII原理与应用----任务调度

    任务调度 xff1a UCOSII任务调度思想 xff1a 近似地每时每刻让优先级最高的就绪任务处于运行状态 具体上 xff0c 采用系统或用户任务调用系统函数及执行中断服务程序结束时来调用调度器 xff0c 以确定应该运行的任务并运行它
  • Docker的使用(docker pull拉取镜像失败问题解决)

    在docker拉取Nginx镜像过程中 xff0c 速度慢 xff0c 或者不成功 报错代码 xff1a Error response from daemon Get https registry 1 docker io v2 net ht
  • Hexo-Next 博客搭建

    lt span style 61 34 color 777777 34 gt title Hexo 搭配 GitHub 建立博客 选用 nexT 主题 date 2021 04 26 19 21 20 categories 兴趣 网站 博客
  • 进阶之路:Prometheus —— 技巧篇

    前言 入门篇 xff1a 从零开始 xff1a Prometheus 理解篇 xff1a 进阶之路 xff1a Prometheus 理解篇 本文记录了一些我在使用Prometheus的过程中的技巧 xff0c 以后还会随着使用的深入不定期
  • Linux系统如何离线安装软件

    Linux系统如何离线安装软件 前言 xff08 一堆废话 xff0c 不看也罢 xff09 功能需求具体操作 前言 xff08 一堆废话 xff0c 不看也罢 xff09 升学足足两个月了 xff0c 但是截至目前 xff0c 还没有认认
  • python中出现变量前后带下划线的是什么意思

    前后没有下划线的是公有方法 xff0c 前边有一个下划线的为私有方法或属性 xff0c 子类无法继承 xff0c 前边有两个下划线的 一般是为了避免于子类属性或者方法名冲突 xff0c 无法在外部直接访问 前后都有双下划线的为系统方法或属性
  • 普通程序员如何入门AI

    毫无疑问 xff0c 人工智能是目前整个互联网领域最火的行业 xff0c 随着AlphaGo战胜世界围棋冠军 xff0c 以及各种无人驾驶 智能家居项目的布道 xff0c 人们已经意识到了AI就是下一个风口 当然 xff0c 程序员是我见过
  • 扩展卡尔曼线性化近似与仿真

    扩展卡尔曼线性化近似与仿真 关于线性化直入主题 上例子小车运动方式 xff1a 沿着圆心在原点 半径为5的圆进行匀速圆周运动 xff0c 其角速度为w 即每次更新变化w个角度 仿真结果总结Matlab测试代码 xff08 EKF test
  • Ubuntu挂载硬盘

    Ubuntu挂载硬盘 1 查看磁盘信息命令 fdisk l 2 查看硬盘的UUID命令sudo blkid 3 mkdir创建挂载点WorkpaceP2和WorkpaceP2 4 永久性挂载分区 xff0c 修改分区文件 xff0c 输入如
  • FreeRTOS——创建任务

    FreeRTOS的设计小巧且简易 xff0c 整个核心代码只有3到4个C文件 xff0c 为了让代码容易阅读 移植和维护 xff0c 大部分的代码都是以C语言编写 xff0c 只有一些函数 xff08 多数是架构特定排班副程序 xff09
  • QT二次开发Kvaser

    前言 最近工作中需要自己去开发一个上位机 xff0c 上位机的通讯方式是CAN xff0c 利用Kvaser将CAN信息传递到上位机 xff0c 所以就需要二次开发Kvaser xff0c 保证上位机的正常通讯 原本是本着前人栽树 xff0
  • Ubuntu 安装ROS (解决rosdep init 失败)

    当前网络上有很多的ROS安装教程 xff0c 但是由于国内的网络问题 xff0c 所以在教程进行到rosdep init时 xff0c 会出现问题 xff0c 所以这篇博客主要解决这个问题 xff0c 以下为教程全部内容 xff1a 引用教
  • Ubuntu20.04部署编译LVI-SAM

    该动图来自LVI SAM开源地址 xff08 https github com TixiaoShan LVI SAM xff09 1 写在开头 1 1 为何诞生此文 近期在学习SLAM相关知识 xff0c 拜读了此篇经典论文LVI SAM
  • QT中的强制类型转换

    当使用C语言那种形式的强制转换 xff0c 发现QT会给出一个使用旧的方式的警告 所以在QT中使用如下类型转换 xff0c 就不会有警告 xff0c 而且这种方式的强制转换更加的安全 xff08 1 xff09 dynamic cast l
  • QT之QCharts的使用(绘制折线图)

    一 画折线图 1 修改 pro文件 在里面添加QT 43 61 charts 2 MyWidget h程序 ifndef MYWIDGET H define MYWIDGET H include lt QWidget gt 添加以下三个头文
  • 恢复经过软件处理过的U盘导致的U盘空间显示不正确等问题

    1 win 43 R xff0c 打开运行 xff0c 输入CMD xff0c 点击确定 2 在命令行中输入DISKPART并回车 xff0c 会跳出一个窗口 xff0c 这就进入了diskpart 3 在跳出的窗口diskpart 中输入
  • 关于STM32 CAN 发送失败问题解释

    首先解释一下CAN几个配置的功能 xff1a 1 CAN InitStruct CAN TTCM 61 DISABLE 这个只在某些CAN标准中使用 xff0c 就设置为DISABLE 2 CAN InitStruct CAN ABOM 6
  • VS2022调试vector无法显示详细信息

    使用vs2022调试vector发现这样的现象 xff1a 为了显示vector大小以及详细的元素 xff0c 需要编写natvis文件 span class token operator lt span span class token
  • STM32H7 PVD断电的使用

    1 遇到的问题 我使用的是STM32H747 xff0c 在初始化后发现断电后并没有进入中断 最后查找到因为STM32H747是双核CPU xff0c 在HAL库源码中 xff0c 有双核的宏定义将一些配置给屏蔽了 xff0c 因为我只用到
  • STM32H7A3 ADC+DMA使用问题

    问题1 xff1a DMA采用半字传输16位ADC值 xff0c 用于存储ADC数据的数组一定是采集数的两倍 xff0c 否则会产生ADC溢出的错误中断HAL ADC ErrorCallback xff0c 从而无法进入ADC采集完成中断H