Bootstrap

【CubeIDE】STM32 HAL库史上最详细教程(二):单/多通道ADC读取电压

0x00前言

小葵花妈妈课堂:

   由ST数据手册AN4195可知STM32 F1 F3系列ADC为12bit精度的逐级逼近式ADC,属于中速ADC,F1系列拥有16个外部单端输入,而F3系列有15个外部单端/差分ADC和三个内部通道。

学习内容:

      1.轮询方式单通道ADC读取电压

      2.中断方式单通道ADC读取电压

      3.DMA方式单通道ADC读取电压

      4.DMA方式多通道ADC读取电压

      5.STM32 ADC工作模式介绍

      6.STN32 HAL库相关ADC函数

使用硬件:

      1.F103C8T6核心板

      2.光敏电阻模块(可选)

 

0x01软件配置

1.配置外部晶振

配置时钟树(根据自己板子情况而定)

2.配置SW Debug接口

     注:因为博主ADC选的是IN0通道,占用了PA0,所以 System Wake-UP 就无法选中,如果需要 System Wake-UP  可以使用其他的ADC通道

3.配置USART串口

如果对HAL库串口操作不是很了解。可以参考我的上一篇博客:

【CubeIDE】STM32 HAL库史上最详细教程(一):UART串口收发

3.配置ADC (单通道)

 

0x02 模式讲解

  • 间断/连续模式:

       1.如果开启间断模式,每次需要先使用HAL_ADC_Start()或HAL_ADC_Start_IT(),HAL_ADC_Start_DMA()下文不再赘述)启动转换,需要使用HAL_ADC_PollForConversion()等待转换完成,HAL_ADC_GetState()获取ADC转换状态(若返回值为HAL_OK说明转换完成),转换完成后使用HAL_ADC_GetValue()读取ADC原始值,读取完成后,使用HAL_ADC_Stop()停止转换,如需再次获取ADC数据,需重复执行上述步骤。

      2.间断模式的缺点很明显:麻烦~  优点就是节省系统资源,安全性更高,而间断模式会不断抛出DMA,IT中断,导致系统安全性降低~

      3.如果开启连续模式,只需要使用一次HAL_ADC_Start(),开启转换,ADC会马不停蹄的电压转换成数字量,用户只需要调用HAL_ADC_GetValue(),读取ADC原始值

      4.连续模式的优缺点和间断模式真好相反~

  • 扫描模式(开启/关闭)

     1.如果设置了多个ADC转换通道(不是勾选的通道数量,是Number Of Conversion里配置的数量),扫描模式自动开启,且无法关闭,如果只有一个转换通道,则扫描模式默认关闭,且无法开启。

     2.假设开启了扫描模式,且RANK1 RANK2 RANK3分别对应IN3 IN2 IN1 通道,则转换一次通道顺序为IN3 IN2 IN1

 

0x03 ADC单通道采样

(模式:间断模式   非扫描模式)

1.重定向 printf(),不清楚怎么操作见上一篇博客

【CubeIDE】STM32 HAL库史上最详细教程(一):UART串口收发

#include "stdio.h"

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1,100);
    return ch;
}

2.打开浮点数转义,CubeIDE 默认不支持浮点数类型进行字符转义(这里困扰了我很久~)

选项目->属性(CubeIDE下拉框没法截图QAQ)

一定要记得点应用啊喂~

3.串口打印电压值

    定义两个变量,分别用于储存原始值和转换完的电压值

    这里要插一嘴,stm32f1系列是12bit ADC,所以转换完是12位的无符号整型,C语言中没有能够12bit的数据类型,所以取最节省系统资源又能保持数值不变的uint16_t (就是unsigned short)类型,由于ADC采样电压范围是0-3.3v,采样值呈线性分布,假设ADC转换值为Ax 那么实际电压就等于 Ax * 3.3 / 2 ** 12 即  Ax * 3.3 / 4096

串口打印电压值

运行结果

4.使用连续采样模式打印电压值

使能连续模式

别忘了生成代码~

在原来的基础上修改代码

运行结果

5.中断方式读取电压值

(模式:连续模式  非扫描模式)

使能ADC全局中断

在原有的基础上修改代码

运行结果

6.DMA方式读取电压值

(模式:连续模式 非扫描模式)

配置DMA

增大转换周期

CubeIDE默认配置1.5Cycles的转换周期,导致DMA触发的中断干扰CPU导致串口无法正常发送数据。

解决方法有二,一者取消DMA中断,但CubeIDE 图形化配置中 DMA全局中断无法取消,网上有很多大佬通过修改DMA初始化代码取消DMA中断,这样既麻烦还会影响到其他需要DMA的外设,所以博主采取第二种方法,即增大转换时间

如果有不信邪的小伙伴可以试试用默认的1.5Cycles~

在原来的基础上修改代码

运行结果

 

0x04 ADC DMA方式多通道采样

    由数据手册可知,F1和F3系列ADC外设用于储存数据的ADC_DR只有16bit,所以一个ADC配置多个通道的时候,下一个通道的转换数据就会覆盖这次的数据,如果DMA方式进行多通道读取数据就可以解决这个问题(具体怎么个原理我也不知道),所以本文只讨论DMA方式ADC多通道读取数据。 

1.配置 ADC多通道

2.定义用于储存 电压和的ADC原始值的变量

Tip: 多通道ADC转换顺序跟RANK有关,详见SCAN模式讲解部分

3.添加代码

运行结果

0xFF 完

既然都看完了,点个赞吧

;