这次调试有些久,缺乏的知识很多,最重要的是ADC的引脚配置为浮空之后,如果没有接入东西,其读取的ADC值是不确定的,所以在测试的时候,一定要把对应的电压接入ADC引脚,测量的值才是准确的。

上代码。

adc.c

#include "adc.h"/***********************
采样次数  30
ADC通道    4
***********************/
uint16_t gt_adc_val[30][4];  //DMA缓冲区// ADC Init
void ADC_DMA_Init(void)
{/* DMA初始化功能结构体定义 */dma_single_data_parameter_struct dma_single_data_parameter;/* 使能GPIOC组时钟 */rcu_periph_clock_enable(RCU_GPIOC);      /* 使能ADC0时钟 */rcu_periph_clock_enable(RCU_ADC0);        /* 使能DMA1时钟 */rcu_periph_clock_enable(RCU_DMA1);/*  配置ADC时钟 */ adc_clock_config(ADC_ADCCK_PCLK2_DIV4);  /*  配置PC1 PC2 PC3 PC4 为浮空模拟输入模式 */gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1); // PC1 : ADC012_IN11 gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2); // PC2 : ADC012_IN12 gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3); // PC3 : ADC012_IN13 gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4); // PC4 : ADC012_IN14 /*    配置ADC为独立模式  */adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);/*    使能连续转换模式    */adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);/* 使能扫描模式  */adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);/*   数据右对齐   */        adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);/*   ADC0设置为规则组  一共使用2个通道        */  adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 4);/*  ADC规则通道配置:ADC0的通道11,12,13,14的扫描顺序分别为0,1,2,3;采样时间:15个周期       */  /*  DMA开启之后 gt_adc_val[x][0] = PC1的数据   gt_adc_val[x][3] = PC4的数据  x的范围0-29 */adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_11, ADC_SAMPLETIME_15);//PC1adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_12, ADC_SAMPLETIME_15);//PC2adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_13, ADC_SAMPLETIME_15);//PC3adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_14, ADC_SAMPLETIME_15);//PC4/*  ADC0设置为12位分辨率       */  adc_resolution_config(ADC0, ADC_RESOLUTION_12B); /* ADC外部触发禁用, 即只能使用软件触发        */  adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);/* 使能规则组通道每转换完成一个就发送一次DMA请求        */  adc_dma_request_after_last_enable(ADC0);  /*    使能DMA请求     */  adc_dma_mode_enable(ADC0);/*    使能DMA       */      adc_enable(ADC0);/* 等待ADC稳定     */  delay_1ms(1);/* 开启ADC自校准        */adc_calibration_enable(ADC0); /*  清除 DMA通道0 之前配置  */dma_deinit(DMA1, DMA_CH0);/*  DMA初始化配置    */dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));        //设置DMA传输的外设地址为ADC0基地址dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;          //关闭外设地址自增dma_single_data_parameter.memory0_addr = (uint32_t)(gt_adc_val);             //设置DMA传输的内存地址为 gt_adc_val数组dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;         //开启内存地址自增(因为不止一个通道)dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;  //传输的数据位 为 16位dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;                          //DMA传输方向为 外设往内存dma_single_data_parameter.number = 4*30;                                                               //传输的数据长度为:4个通道 * 每个通道采集30次dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;                                  //设置高优先级dma_single_data_mode_init(DMA1, DMA_CH0, &dma_single_data_parameter);       //将配置保存至DMA1的通道0/*  DMA通道外设选择       *//*    数据手册的195页根据PERIEN[2:0]值确定第三个参数,例是100 则为DMA_SUBPERI4      例是010 则为DMA_SUBPERI2    *//*    我们是ADC0功能,PERIEN[2:0]值为000,故为DMA_SUBPERI0     */dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);/*  使能DMA1通道0循环模式       */dma_circulation_enable(DMA1, DMA_CH0);/*  启动DMA1的通道0功能        */dma_channel_enable(DMA1, DMA_CH0); /* 开启软件触发ADC转换     */adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}//对DMA保存的数据进行平均值计算后输出
//传入参数:CHx 第几个扫描的数据
//         根据前面的配置得知:PC1为0 PC2为1 PC3为2 PC4为3
//返回数据:对应扫描的ADC值
unsigned int Get_Adc_Dma_Value(char CHx)
{unsigned char i = 0;unsigned int AdcValue = 0;/* 因为采集30次,故循环30次 */for(i=0;i<30;i++){/*    累加    */AdcValue+=gt_adc_val[i][CHx];}/* 求平均值 */AdcValue=AdcValue/30;return AdcValue;
}

adc.h

#ifndef _ADC_h_
#define _ADC_h_#include "gd32f4xx.h"
#include "usart0.h"
#include "stdio.h"
#include "systick.h"extern uint16_t gt_adc_val[30][4];  //DMA缓冲区/************************//之前的单路采集
void ADC_Init(void);
unsigned int Get_ADC_Value(void);**************************/
void ADC_DMA_Init(void);
unsigned int Get_Adc_Dma_Value(char CHx);#endif

主函数

#include "gd32f4xx.h"
#include "systick.h"
#include "usart0.h"
#include "stdio.h"
#include "adc.h"int main(void)
{unsigned char temp_buff[200]; unsigned int  show_buff[4];nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组systick_config();                                                                   //系统滴答定时器   定时1MSUSART1_Init();ADC_DMA_Init();         USART0_send_String((unsigned char *)"--开始--");while(1)  {        /*   获取数据        */show_buff[0] = Get_Adc_Dma_Value(0); //根据扫描顺序得知数组[0] = PC1的数据show_buff[1] = Get_Adc_Dma_Value(1);  //根据扫描顺序得知数组[1] = PC2的数据show_buff[2] = Get_Adc_Dma_Value(2);  //根据扫描顺序得知数组[2] = PC3的数据show_buff[3] = Get_Adc_Dma_Value(3);  //根据扫描顺序得知数组[3] = PC4的数据/* 串口显示数据      */sprintf((char *)temp_buff, "PC1=%d\r\nPC2=%d\r\nPC3=%d\r\nPC4=%d\r\n",\show_buff[0], show_buff[1], show_buff[2], show_buff[3]);                 USART0_send_String(temp_buff);/*    串口显示刷新太快,加个延时    */delay_1ms(1000);}
}

实际效果

对PC1和PC3接入3.3V,因为ADC是12位的,所以最大采集数为4096,实际采集也接近了4096。

对PC2和PC4接入GND,实际采集也接近0。

注意!引脚不能浮空进行采集!不然数据是不确定的!

代码链接:

链接:https://pan.baidu.com/s/15G_t-jW82Ms6FLD_fTCBqw?pwd=1234
提取码:1234

立创梁山派GD32F450ZGT6--使用DMA实现多通道ADC采集相关推荐

  1. STM32F4基于DMA的多通道ADC采集——遇到的问题解决

    这几天在尝试用DMA实现规则通道多通道的ADC采集,遇到了不少问题,在这记录一下我遇到的问题,一方面理顺一下思路,也希望后人少走弯路. 一开始按照开发板资料中的程序源码编写,但无论如何配置,也无法实现 ...

  2. 立创梁山派GD32F450ZGT6--0.96IIC屏移植u8g2

    一.硬件准备 使用的主控是:立创梁山派GD32F450ZGT6 使用的OLED是:0.96寸4针IIC通信的OLED屏 二.u8g2介绍 U8g2 是一个用于嵌入式设备的单色图形库.U8g2支持单色O ...

  3. 立创梁山派GD32F450ZGT6--屏幕扩展板LVGL应用

    该文章工程是基于裸机情况下运行的LVGL,通过GUI-Guider-1.4.0进行页面布局配置. 一.介绍 GUI Guider是恩智浦为LVGL开发了一个上位机GUI设计工具,可以通过拖放控件的方式 ...

  4. 立创梁山派GD32F450ZGT6--通过PCA9685控制16路舵机

    PCA9685芯片,每一路LED输出端均可自由调节PWM波的频率 (40~1000Hz) 和占空比 (0%~100%) .这款芯片主要通过输出不同占空比的PWM脉冲信号来控制舵机转动的角度.是16通道 ...

  5. 立创梁山派学习笔记——GPIO输出控制

    梁山派 前言 开发板简介 GD32F407ZGT6官方资源 数据手册 1.系统框图 2. 引脚复用表 3.命名规则 4.其他 用户手册 固件库与PACK包 开发环境搭建 立创官方的资料包 资料齐活,开 ...

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

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

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

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

  8. STM32F767多通道ADC采集+DMA传输

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

  9. 使用STM32 CUBE IDE配置STM32F7 用DMA传输多通道ADC数据

    我的使用环境: 硬件:STM32F767ZGT6.串口1.ADC1.16MHz晶振.216MHz主频 软件:STM32 CUBE IDE 优点:不用定时触发采样,ADC数据是不停的实时更新,ADC数据 ...

最新文章

  1. 2017,AI偏见为何如此受关注?
  2. arm linux 内核启动,Linux(ARM)内核启动地址
  3. android drawpath填充,Android如何用图片来填充Path封闭路径
  4. 文档扫描识别——OpenCV与C++实现OCR文字识别
  5. 神策数据入选铅笔道 2021 真榜“企业服务未来独角兽排行榜·营销与销售 TOP20”...
  6. 767. 重构字符串
  7. 先生,要点单吗? (HTTP协议概览)
  8. html5 indexeddb 排序,html5 – 在IndexedDB中,有没有办法进行排序复合查询?
  9. 数据结构上机时间第三周项目4(1)—顺序表应用
  10. NYOJ--106--背包问题
  11. 微信商户中查看 appid
  12. M3U8 Downloader的使用
  13. uni-app调用android方法,uni-app 调用 jar 包
  14. Fite-C02-1班成员学习进度记录
  15. 树莓派操控SG90舵机
  16. 需求提炼:产品需求、技术需求
  17. 74LVC245电平转换电路
  18. 游戏场景设计思维:黑白与颜色的现代构成艺术
  19. Navicat安装教程和评测
  20. OSPF(第六天笔记)

热门文章

  1. JavaScript中的Date日期、String字符串、Array数组、Math提供对数据的数学计算
  2. JavaScript进阶 - 第7章 JavaScript内置对象
  3. Oracle Cloud Infrastructure:Oracle Cloud Marketplace提供了一个扩展的Oracle和第三方机器映像库
  4. video标签样式铺满全屏
  5. 焦耳小偷工作原理分析
  6. IDEA中光标变成了黑色的块块
  7. 让人费解的统计(股票、幸福指数等)
  8. 企业想做好数字化转型,中台是关键
  9. [足式机器人]Part1 双足和四足的运动Ch04——【Legged Robots that Balance 读书笔记】
  10. 【传感器大赏】巡线模块