文章目录

  • 一、ADC简介
    • 1、ADC采样频率
    • 2、ADC转换时间
    • 3、ADC寄存器
    • 4、ADC引脚与外部通道对应关系
  • 二、DMA简介
  • 三、代码配置
    • 1、ADC、DMA初始化配置
    • 2、adc.h文件的配置
    • 3、main.c文件配置

一、ADC简介

TM32F767xx系列有3个ADC,这些ADC可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F767的ADC是12位逐次逼近型的模拟数字转换器。它有19个通道,可测量16个外部源、2个内部源和Vbat通道的信号。我使用的是STM32F767IGT6

1、ADC采样频率

不要让ADC的时钟超过36M,否则将导致结果准确度下降。STM32F767的ADC最大工作频率是36Mhz,而ADC时钟(ADCCLK)来自APB2,APB2频率一般是108Mhz,我们设置ADCPRE=01,即4分频,这样得到ADCCLK频率为27Mhz

2、ADC转换时间

ADC的转换时间: 总转换时间(Tcovn)=采样时间+12个周期
例如,当ADCCLK=27Mhz的时候,并设置3个周期的采样时间,则得到:Tcovn=3+12=15个周期=0.55us。
stm32f767的采样时间周期可以在stm32f7xx_hal_adc.h中选择,可以选择3~480个周期的采样时间。如下图所示:

3、ADC寄存器

ADC里面用到的寄存器有很多,常用的有以下几个,具体使用方法就不一一介绍了

4、ADC引脚与外部通道对应关系

二、DMA简介

DMA 全称Direct Memory Access,即直接存储器访问。
DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。
DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高。

STM32最多有2个DMA控制器,2个DMA控制器总共有16个数据流(每个控制器8个)。每个DMA控制器都用于管理一个或者多个外设的存储器访问请求。

三、代码配置

1、ADC、DMA初始化配置

我将它们都配置在了adc.c文件中,代码如下所示:

         #include "adc.h"#include "delay.h"#include "usart.h"#include "sdram.h"#include "led.h"#include "lcd.h"#define M 8 //定义M#define N 4u16  value[N][M];uint32_t ADC_ConvertedValueRead[4];uint32_t ADC_ConvertedValue[4];ADC_HandleTypeDef  ADC1_Handler;       //ADC句柄DMA_HandleTypeDef  ADC1TxDMA_Handler;      //DMA句柄//初始化ADCvoid MY_ADC_Init(void){ ADC_ChannelConfTypeDef ADC1_ChanConf;//GPIO初始化GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟__HAL_RCC_GPIOA_CLK_ENABLE();            //开启GPIOA时钟__HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_7;            //PA5GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉HAL_GPIO_Init(GPIOA,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;     //|GPIO_PIN_5;            GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉HAL_GPIO_Init(GPIOC,&GPIO_Initure);//ADC1功能配置ADC1_Handler.Instance=ADC1;ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,ADCCLK=PCLK2/4=108/4=27MHZADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐ADC1_Handler.Init.ScanConvMode=ENABLE;                       //扫描模式,扫描模式用于多通道采集ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断ADC1_Handler.Init.ContinuousConvMode=ENABLE;                //开启连续转换模式,即不停地进行ADC转换    ADC1_Handler.Init.NbrOfConversion=4;                         //规则序列中有4个转换ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式ADC1_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0   ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发ADC1_Handler.Init.DMAContinuousRequests=ENABLE;             //开启DMA请求ADC1_Handler.DMA_Handle=&ADC1TxDMA_Handler;HAL_ADC_Init(&ADC1_Handler);                                 //初始化 //采样通道、顺序配置  ADC1_ChanConf.Channel=ADC_CHANNEL_7;                         //通道ADC1_ChanConf.Rank=1;                                        //序列ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;         //采样时间ADC1_ChanConf.Offset=0;                 HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置ADC1_ChanConf.Channel=ADC_CHANNEL_14;                         //通道ADC1_ChanConf.Rank=2;                                        //序列ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;         //采样时间ADC1_ChanConf.Offset=0;                 HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置ADC1_ChanConf.Channel=ADC_CHANNEL_15;                         //通道ADC1_ChanConf.Rank=3;                                        //序列ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;         //采样时间ADC1_ChanConf.Offset=0;                 HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置ADC1_ChanConf.Channel=ADC_CHANNEL_5;                         //通道ADC1_ChanConf.Rank=4;                                        //序列ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;         //采样时间ADC1_ChanConf.Offset=0;                 HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置}//初始化DMAvoid DMA_Config(void){__HAL_RCC_DMA2_CLK_ENABLE();   //DMA2时钟使能ADC1TxDMA_Handler.Instance=DMA2_Stream0;                            //数据流选择ADC1TxDMA_Handler.Init.Channel=DMA_CHANNEL_0;                      //通道选择ADC1TxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器ADC1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式ADC1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式ADC1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //外设数据长度:32位ADC1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;       //存储器数据长度:32位ADC1TxDMA_Handler.Init.Mode=DMA_CIRCULAR;                            //外设流控模式  循环模式ADC1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级ADC1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              ADC1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      ADC1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输ADC1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输ADC1TxDMA_Handler.XferCpltCallback = HAL_DMA_IRQHandler;HAL_DMA_DeInit(&ADC1TxDMA_Handler); HAL_DMA_Init(&ADC1TxDMA_Handler);__HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1TxDMA_Handler);    //将DMA与ADC1联系起来(发送DMA)HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,0,0);HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);}void DMA2_Stream0_IRQHandler(void){HAL_DMA_IRQHandler(&ADC1TxDMA_Handler);}//采样函数void task_adc(void){    int i; HAL_ADC_Start_DMA(&ADC1_Handler,&ADC_ConvertedValueRead[0],4);  for(i=0; i<M; i++){ delay_us(10);value[0][i] = (u16)(ADC_ConvertedValue[0]&0xFFF ); //获取ADC的值value[1][i] = (u16)(ADC_ConvertedValue[1]&0xFFF);  //获取ADC的值value[2][i] = (u16)(ADC_ConvertedValue[2]&0xFFF); value[3][i] = (u16)(ADC_ConvertedValue[3]&0xFFF);//              printf("\r\n 编号%d  \t 编号%d  \t AD值: %d\r\n", 0,i,  value[0][i]);//            printf("\r\n 编号%d  \t 编号%d  \t AD值: %d\r\n", 1,i,  value[1][i]); //           printf("\r\n 编号%d  \t 编号%d  \t AD值: %d\r\n", 2,i,  value[2][i]);//            printf("\r\n 编号%d  \t 编号%d  \t AD值: %d\r\n", 3,i,  value[3][i]); LCD_ShowxNum(134,130,value[0][i],4,16,0);    //显示ADCC采样后的原始值LCD_ShowxNum(134,150,value[1][i],4,16,0);    //显示ADCC采样后的原始值LCD_ShowxNum(134,170,value[2][i],4,16,0);    //显示ADCC采样后的原始值LCD_ShowxNum(134,190,value[3][i],4,16,0);    //显示ADCC采样后的原始值   //          delay_us(50);}HAL_ADC_Stop_DMA(&ADC1_Handler);      //传输完成以后关闭串口DMA}/*** 函数功能: ADC转换完成回调函数* 输入参数: hadc:ADC外设设备句柄* 返 回 值: 无* 说    明: 读取ADC转化结果时,一定要关闭Cache,否则数组中的数据为空,即关闭Cache后读取数据,读完在打开。此函数在 void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) 中调用*/void  HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {uint32_t i;SCB_DisableDCache();for(i=0;i<4;i++){ADC_ConvertedValue[i] = ADC_ConvertedValueRead[i];}SCB_EnableDCache();   }

注意 :STM32767在使用时一定要注意Cache的问题

2、adc.h文件的配置

     #ifndef __ADC_H#define __ADC_H#include "sys.h"/********* 扩展变量 **********/extern ADC_HandleTypeDef ADC1_Handler;      //ADC句柄extern DMA_HandleTypeDef  ADC1TxDMA_Handler;      //DMA句柄/********* 函数声明**********/void MY_ADC_Init(void);                //ADC通道初始化void DMA_Config(void);void task_adc(void);#endif

3、main.c文件配置

 #include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "key.h"#include "lcd.h"#include "sdram.h"#include "adc.h"extern uint32_t ADC_ConvertedValueRead[4];int main(void){Cache_Enable();                 //打开L1-CacheHAL_Init();                      //初始化HAL库Stm32_Clock_Init(432,25,2,9);   //设置时钟,216Mhz delay_init(216);                //延时初始化uart_init(115200);                //串口初始化LED_Init();                     //初始化LEDKEY_Init();                     //初始化按键SDRAM_Init();                   //初始化SDRAMLCD_Init();                     //LCD初始化MY_ADC_Init();                  //初始化ADC1DMA_Config();POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");  LCD_ShowString(30,70,200,16,16,"ADC TEST");   LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2019/4/18");    POINT_COLOR=BLUE;//设置字体为蓝色LCD_ShowString(30,130,200,16,16,"ADC1_PA7_VAL:");LCD_ShowString(30,150,200,16,16,"ADC1_PC4_VAL:");LCD_ShowString(30,170,200,16,16,"ADC1_PC5_VAL:");LCD_ShowString(30,190,200,16,16,"ADC1_PA5_VAL:");   printf("采样开始\r\n ");task_adc();printf("采样结束\r\n ");while(1);}

以上代码我亲测有效,当然,如果有什么问题,欢迎交流讨论。

STM32F767多通道ADC采集+DMA传输相关推荐

  1. STM32CubeMX关于ADC采集DMA传输

    什么是ADC,ADC也叫做模数转换,既将外面的模拟信号转换为数字信号. 模拟信号:连续变化的物理量表示的信息,其信号的幅度,或频率,或相位随时间作连续变化,或在一段连续的时间间隔内,其代表信息的特征量 ...

  2. [STM32F4]STM32F407 ADC采集+DMA传输

    前言        有的项目中需要对多个通道的电压进行一定频率的AD采样. 第一种:是使用定时器去读取,通过检查转换完成标志位来读取,但这样就会加重整个系统的负担,占用CPU资源. 第二种:是采用定时 ...

  3. STM32Cubemx——ADC采集+DMA传输

    文章目录 一.准备工具 二.前置知识 1.ADC简介 2.DMA简介 2.STM32Cubemx配置 1.新建工程 2.时钟源选择及时钟树配置 3.时基选择调试接口选择 4.配置ADC采集 1.选择要 ...

  4. 基于STM32F4:多通道ADC采集,采用DMA的形式,亲测有效

    基于STM32F4的多通道ADC采集 单片机源程序如下: #include "sys.h" #include "delay.h" #include " ...

  5. STM32——多通道ADC的DMA方式采集方法

    前言: 最近在调试STM32F205芯片ADC多通道DMA方式采集数据,总结下STM32多通道ADC的DMA方式采集的使用方法. 硬件平台:STM32F205 软件平台:keil v5 函数库:标准库 ...

  6. axi dma 寄存器配置_STM32 ADC多通道转换的DMA传输示例

    这里以STM32F334 Nucleo板作为硬件平台,使用ARM keil MDK集成开发环境. 对3个ADC通道进行连续.扫描转换,转换结果通过DMA传输到内存,再作为TIM2的3个比较寄存器的值, ...

  7. stm32f429之多通道ADC通过DMA数据采集

    stm32f429之多通道ADC通过DMA数据采集 原来的程序使用时stm32f103的芯片,现在给为stm32f429的芯片,查看一下几家开发板例程,发现没有使用adc+dma的,在网上也搜索了一下 ...

  8. 瑞萨e2studio(16)----基于DTC的多通道ADC采集

    瑞萨e2studio.16--基于DTC的多通道ADC采集 概述 视频教学 csdn课程 样品申请 完整代码下载 硬件准备 开发板 新建工程 工程模板 保存工程路径 芯片配置 工程模板选择 uart配 ...

  9. STM32h743开启cache后ADC采集DMA数据不更新问题

    STM32h743开启cache后ADC采集DMA数据不更新问题 解决办法 解决办法 1.DMA数据缓存地址进行32字节对齐,即地址是0x20的整数倍: __attribute__((at(0x380 ...

最新文章

  1. python t检验_A or B A/B测试-python独立双样本t检验
  2. UVA10391复合词
  3. 机器学习笔记(十)——Logistic Function AND Softmax Function
  4. linux常用命令--实用小技巧
  5. leetcode 1164 python
  6. (10)FPGA面试技能提升篇10(MATLAB)
  7. 【java】序列化:ProtoBuf 与 JSON 的比较
  8. 炒菜机器人放食材的顺序_2年要开1000家 碧桂园旗下千玺机器人餐厅开业
  9. 3dmax 注意事项
  10. Mac电脑没声音了怎么办?苹果电脑没声音的解决方法
  11. 计算机组装与维护标准教程(2010-2012版)电子教材,计算机组装与维护标准教程(2015—2018版)...
  12. 目前计算机无法显示的四叠字,四叠字列表(共19个),还能用的四叠字大全,带拼音,部分注释!...
  13. R语言笔记3(NA解释)
  14. mysql表新增添加一列
  15. 服务器创建虚拟环境跑代码
  16. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之一环境搭建跑起来模拟器!
  17. 金叉走势图解上半年暴跌行情,如何证明macd金叉死叉模型确实有用?
  18. BaoDing University热身赛 2020-1-31 13:50 3 hours
  19. 前端包管理器的依赖管理原理
  20. LoadLibrary

热门文章

  1. 如何选择NTC热敏电阻
  2. 防火墙入侵与检测 day03 详解NAT及配置
  3. STM32F10xxx20xxx21xxxL1xxxx Cortex-M3程序设计手册 阅读笔记四(3):嵌套向量中断控制器
  4. 【java】方法练习1-商品总价对应折扣
  5. android 内功修炼参考
  6. HTML小游戏20 —— html5版开心斗地主小游戏(附完整源码)
  7. 廖雪峰老师个人网站推荐
  8. os.system() 和os.popen()的区别
  9. 怎么建立win7无线热点
  10. opencv图像对齐与图像相减python