STM32 CUbeIDE ADC采集单通道和多通道 DMA
STM32拥有 1~3个 ADC STM32F101/102系列只有 1个 ADC)),这些 ADC可以独立使用,也可以使用双重模式(提高采样率)。 STM32的 ADC是 12位逐次逼近型的模拟数字转换器。它有 18个通道,可测量 16个外部和 2个内部信号源。各通道的 A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在 16位数据寄存器中。
STM32F103系列最少都拥有 2个 ADC, STM32F103RCT包含有 3个ADC。STM32的 ADC最大的转换速率为 1Mhz,也就是转换时间为 1us(在ADCCLK=14M,采样周期为 1.5个 ADC时钟下得到),不要让 ADC的时钟超过 14M,否则将导致结果准确度下降。
1、ADC采集单通道
1.1 、创建工程选择ADC
开始创建工程文件,选择对应的芯片,我自己使用的是STM32F103RC
打开调试,可以下载代码
开启外部时钟
配置时钟树
开启ADC选择 ,选择了PA1
选择连续转换模式(Continuous Conversion Mode),并调整采样时间。
开启DMA转换,选择循环模式,半字。
为了方便调试,开启串口1,USART1,选择异步通信。
为了让生成的文件都是单独分开的,这样看着方便,选择如下所示
生成代码,在此之前,还有重要的一步,编码问题,STM32 CUbeIDE 默认UTF-8编码,会出现中文字符乱码问题,所以我选择了GBK编码,防止乱码。
1.2、重定向printf 可以输出小数
我的重定向和你看到一般重定向可能不一样,但是效果是一样的。特别注意的一点就是,在STM32 CUbeIDE中,要输出小数还要选择勾选对应的选项。
定义数组保存要发送的数据,和adc值保存数组,定义为uint16_t 是因为,在开启ADC的时候,选择了半字。
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "stdint.h"
#include <string.h> // correct header
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define printf(...) HAL_UART_Transmit((UART_HandleTypeDef *)&huart1, (uint8_t *)u_buf,\
sprintf((char*)u_buf,__VA_ARGS__), 0xFFFF);
/* USER CODE END PTD */
定义的发送数据数组,和adc值保存变量
/* USER CODE BEGIN PV */
uint8_t u_buf[64];//定义数据存放
uint16_t adc_buf[2];
/* USER CODE END PV */
生成hex文件,STM32 CUbeIDE默认不生成hex文件,需要勾选对应项。
1.3、开启 ADC DMA
在HAL 库中使用ADC 、定时器等,都是需要自己先开启,在使用的。
HAL_ADC_Start_DMA((ADC_HandleTypeDef*)&hadc1, (uint32_t*)adc_buf, (uint32_t)1); //通道数1
hadc1 :定义的ADC结构体变量,在adc.c中可以看到
adc_buf :前面定义的变量
串口输出ADC转换的值
while (1)
{
printf("ADC = %d\r\n",adc_buf[0]);
printf("voltage: %f\r\n,(float)adc_buf[0]/4096*3.3");
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
2、ADC采集2通道
既然有了1路的ADC采集,那么多路的ADC其实就是在1路ADC上面改改。现在生成2路ADC。选择了PA1 PA2
采样时间可以不修改,保持默认也是可以的,但是为了保证采样周期完整,周期修改大一点。
生成代码,开启ADC 。
扫描二维码关注公众号,回复:
11653652 查看本文章
HAL_ADC_Start_DMA((ADC_HandleTypeDef*)&hadc1, (uint32_t*)adc_buf,(uint32_t)2); //2路
输出采样数据