CubeMX_ADC学习笔记——ADC(DMA模式)的使用


学生党,写博客的目的纯粹是为了记录自己的学习经历,方便以后翻看,所以写的不是很专业和规范。如有解释错误、理解错误、术语使用错误等问题,亦可指出。

一、在CubeMX上创建项目工程

1、创建工程

在这里插入图片描述

2、搜索芯片型号

在这里插入图片描述

3、双击选择芯片型号(STM32G071RBTX)

在这里插入图片描述

4、进入界面,选择串口SWD调试方式

在这里插入图片描述

5、选择外部陶瓷晶振

在这里插入图片描述

6、GPIO配置

在这里插入图片描述

7、ADC配置

在这里插入图片描述

注 需要关注的有:

在设置通道优先级时要对应住:
在这里插入图片描述

synchronous clock mode divided by   同步时钟模式分频
asynchronous clock mode divided    异步时钟模式分频
resolution分辨率
data alignment 数据对齐(右)

Sequencer 扫描顺序        
Sequencer fully configurable  描通道的顺序与通道号channel number无关
Sequencer not fully configurable  通道扫描的顺序由通道编号定义

scan conversion mode       扫描转换模式(需要选择Sequencer not fully configurable)
continuous conversion mode 自动连续扫描模式(需要选择Sequencer not fully configurable)
Discontinuous Conversion Mode   非连续转换模式
MDA continuous Requests   DMA连续请求
(在开启DMA连续请求前 需先开启DMA配置)

End of conversion selection 转换结束选择   
End of single conversion 单次转换结束 
End of sequence of conversion 转换序列结束

overrun behaviour  侵占行为   
overrun data preserved 溢出的数据保存  
overrun data overwritten 溢出的数据覆盖

external trigger conversion edge 外部触发机制

8、定时器配置

在这里插入图片描述

记得在NVIC里使能定时器中断:
在这里插入图片描述

注 需要关注的有:

定时器的定时时间计算公式:
在这里插入图片描述

这里配置定时器是为了每1ms取出一次DMA的值。

ARR: 自动重装载寄存器( AutoReload Register )16位数据)
PSC:预分频器(16位数据)
TIM_CLK: ADC时钟频率

主要要修改的就是上面的参数,但计算的时候要注意TIM_CLK的单位是HZ不是MHZ

9、串口配置(默认配置即可,最后记得在NVIC里使能串口中断)

在这里插入图片描述

10、配置DMA

在这里插入图片描述

注 需要关注的有:

一定要选择Circular模式(循环模式)

11、时钟树配置

在这里插入图片描述

注 需要关注的有:

(由于芯片的特性,所以最大主频只能到64而不是下面的72。)

HSI:内部高速时钟,RC振荡器,频率为8MHz。可作为系统时钟或PLL锁相环的输入。
HSE:外部高速时钟,可通过外接一个频率范围是4-16MHz的时钟或者晶振,HSE可以作为系统时钟和PLL锁相环输入,还可以经过128分频后输入给RTC。
LSI:内部低速时钟,RC振荡器,频率大约为40K,可供独立看门狗和RTC使用,并且独立看门狗只能使用LSI时钟。
LSE:外部低速时钟,通常在外部低速时钟管脚上外接一个32.768KHz的晶振,供RTC使用。
PLL:锁相环,用于倍频输出,因为开发板外部高速晶振也只有8M,如果要使芯片的最大时钟频率是72M,可通过PLL锁相环来倍频。从图标5中可以看到,PLL时钟输入源可选择为HSI/2、HSE或者HSE/2,时钟源经过2-16倍频后输入给PLLCLK,如果系统时钟选择由PLLCLK提供,则PLLCLK最大值不要超过72M。
SYSCLK:系统时钟。它是STM32中绝大部分部件工作的时钟源。它的时钟来源可以由HSI、HSE、PLLCLK提供。
系统复位后, HSI振荡器被选为系统时钟,当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止。只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时钟源的切换才会发生。在被选择时钟源没有就绪时,系统时钟的切换不会发生。直至目标时钟源就绪,才发生切换。

二、在MDK中修改CubeMX上创建的项目工程:

1、头文件、数据类型及函数声明的添加位置

在修改工程代码前需要先了解在MDK中把用户代码添加在什么位置才不会在再次生成CubeMX代码时被覆盖:
在这里插入图片描述

2、添加用户头文件(用于调用sprintf函数)

在这里插入图片描述

3、添加变量定义与声明

在这里插入图片描述

4、编写用户函数(求平均值函数)

在这里插入图片描述

5、串口打印函数

在这里插入图片描述

注意:

其中真实的电压值应该是ADC寄存器去除的值value*3.3/4096

6、重写ADC中断回调函数 和 定时器TIM1中断回调函数

在这里插入图片描述

注意:

我的ADC中断服务函数只用来记录ADC采集次数。
在定时器中断服务函数里是将MDA的缓存数据取出来传给待计算值channel1、channel2、channel3。即使用定时器每秒采集一个DMA的数据(ADC_MDA的频率远高于每毫秒1次)来实现精确的1KHZ的ADC采集频率其中channel3 2ms/次 即500KHZ。

7、定时器和DMA初始化

在这里插入图片描述

说明:

__HAL_TIM_CLEAR_IT(&htim1 ,TIM_IT_UPDATE ); 清除TIM1中断挂起
HAL_TIM_Base_Start_IT(&htim1 );              启动定时器TIM1中断
HAL_ADC_Start_DMA (&hadc1,buffer,6);         启动ADC_MDA

8、主函数循环体while(1):

在这里插入图片描述

说明:

主函数使用average()函数求出ADC的平均值并每秒通过串口传输函数printf_ADCx()传输。

三、效果展示

1、未使用平均值函数的:(有明显突变和不稳定)

在这里插入图片描述

2、使用平均值函数的:(无明显突变)

在这里插入图片描述

对比数据可得出: 使用平均值的ADC更加平稳。ADC采集源稳定时,没有突变。

四、最后附加一张main.c完整的程序

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

TIM_HandleTypeDef htim1;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */




char TxData[10
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值