• STM32CUBEMX开发GD32F303(11)----ADC在DMA模式下扫描多个通道


    概述

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过GD32303C_START开发板内进行验证。需要GD样片的可以加Q_QUN申请:615061293。
    本章主要配置,双ADC轮询模式扫描多个通道,通过串口进行打印。
    查阅手册可以得知,PA9、PA10为串口0的输出和输入口。
    在这里插入图片描述

    视频教学

    csdn课程

    课程更加详细。
    https://download.csdn.net/course/detail/37152

    ADC通道配置

    ADC1IN0(PA0)IN1(PA1)IN4(PA4)

    生成例程

    这里准备了GD32303C_START开发板进行验证。
    在这里插入图片描述

    STM32CUBEMX配置

    在这里插入图片描述

    勾选中断。
    在这里插入图片描述

    ADC1配置。

    在这里插入图片描述

    • ADCs_Common_Settings:
      • Mode:Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1:DUALMOD 位。
    • ADC_Settings:
      • Data Alignment:
        • Right alignment 转换结果数据右对齐,一般我们选择右对齐模式。
        • Left alignment 转换结果数据左对齐。
      • Scan Conversion Mode:
        • Disabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
        • Enabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。
      • Continuous Conversion Mode:
        • Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。
        • Enabled 自动连续转换。
      • DiscontinuousConvMode:
        • Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。
        • Enabled 开启间断模式。
    • ADC_Regular_ConversionMode:
      • Enable Regular Conversions 是否使能规则转换。
      • Number Of Conversion ADC转换通道数目,有几个写几个就行。
      • External Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。
    • Rank:
      • Channel ADC转换通道
      • Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。
    • ADC_Injected_ConversionMode:
      • Enable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
    • WatchDog:
      • Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。

    DMA开启。
    在这里插入图片描述

    生成独立的文件。
    在这里插入图片描述

    keil配置

    microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,如果要使用printf(),必须开启。
    在这里插入图片描述

    代码

    在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。

    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    /* USER CODE END Includes */
    
    • 1
    • 2
    • 3

    函数声明和串口重定向:

    /* USER CODE BEGIN PFP */
    int fputc(int ch, FILE *f){
    	HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    	return ch;
    }
    
    /* USER CODE END PFP */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    定义变量,存放采集到的数据。

    /* USER CODE BEGIN 0 */
    uint32_t ADC1_1, ADC1_2,ADC1_3;//采集的三个通道的ADC
    uint32_t ADC1_Value[30];//DMA存放数组
    uint8_t i;
    uint8_t ADC1_Flag;//dma采集完毕中断
    
    /* USER CODE END 0 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使能ADC传输。

      /* USER CODE BEGIN 2 */
      HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
      /* USER CODE END 2 */
    
    • 1
    • 2
    • 3

    主循环。

      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    	  if(ADC1_Flag==1)
    	  {
    		  ADC1_Flag=0;
    		  ADC1_1=0;
    		  ADC1_2=0;
    		  ADC1_3=0;
    		  for(i=0;i<30;)
    		  {
    			  ADC1_1+=ADC1_Value[i++];
    			  ADC1_2+=ADC1_Value[i++];
    			  ADC1_3+=ADC1_Value[i++];
    		  }
    		  printf("\n");
    		  printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);
    		  printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);
    		  printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);
    		  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    	  }
    		HAL_Delay(1000);
      }
      /* USER CODE END 3 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    ADC回调函数。
    DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);

    
    /* USER CODE BEGIN 4 */
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
    {
    	if(hadc->Instance == ADC1){
    		ADC1_Flag=1;
    		/*
    		 * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语
    
    		 */
    		HAL_ADC_Stop_DMA(&hadc1);
    	}
    }
    /* USER CODE END 4 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试结果

    输入固定电压进行测试。

    ADC1IN0(PA0)IN1(PA1)IN4(PA4)
    输入电压VCC2.0VGND

    Normal下测试结果如下。
    在这里插入图片描述
    若不试用关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
    会造成数据错乱。
    在这里插入图片描述
    Circular可以下可以一直进行采集,不需要HAL_ADC_Stop_DMA(&hadc1)都可。
    在这里插入图片描述

    最后

    以上的代码会在Q群里分享。QQ群:615061293。
    或者关注微信公众号『记帖』,持续更新文章和学习资料,可加作者的微信交流学习!
    在这里插入图片描述

  • 相关阅读:
    Go runtime 调度器精讲(六):非 main goroutine 运行
    linux命令之printf
    python线程和进程
    Nginx代理MinIO时出现“Access Denied“错误
    智能井盖是什么?万宾科技智能井盖传感器有什么特点
    React 事件函数传播及捕获
    零售商贩mysql表设计:banner管理表
    golang标准库-crc32的使用
    多角度解读新兴公链Sui:团队、架构、代币、生态等
    [深入研究4G/5G/6G专题-58]: - L3信令控制-7-关键概念和常见问题之信道、UE 上下文, RRC连接,SRB0/1/2, DRB Bear。
  • 原文地址:https://blog.csdn.net/qq_24312945/article/details/126049591