详解STM32 G4芯片ADC采集实现过程
本周完成:
1.学习使用STM32CUBEMX配置,使用hal库实现了串口发送接收和ADC的单通道采集实现。
2.探究如何对多个ADC的多通道进行采集的配置。
下周任务:
1.实现多ADC多通道采集。
2.探究hal库SPI的配置方法,对之前版本的标准库代码其他功能进行移植。
本周研究内容具体介绍:
1.开发工具
由于STM32芯片从F7系列开始就没有了标准库,改成了HAL库开发,所以需要对原来的代码进行移植,重新实现。
先使用CUBEMX图形化初始化配置,然后将工程在keil打开进行程序编写。
2.参考资料
(1)官方示例
研究过程中,使用了文档
该文档介绍了G4系列芯片的示例代码。
电脑中示例的位置在:
D:\stm32cubemx\repository\STM32Cube_FW_G4_V1.3.0\Projects\STM32G474E-EVAL\Examples
对官方代码进行理解,稍加改动放到自己的项目中。
官方代码均为英文,有详细注释,对注释可以使用bing AI进行翻译和解释更为易懂,也可以使用翻译软件。
(1)官方ADC_ContinuousConversion_TriggerSW示例,示例演示了软件触发单通道ADC的连续采集。
(2)官方ADC_GroupsRegularInjected示例,示例演示了规则和注入通道,规则通道使用DMA方式,注入通道使用IT方式。
(2)官方数据手册
阅读数据手册,了解ADC内部结构。
手册:STMicroelectronics的STM32G4系列高级ARM架构32位微控制器
(3)库文件注释
阅读工程中stm32g4xx_hal_adc.c文件开头的注释,有详细的编程思路介绍。
该文件提供固件功能来管理模数转换器(ADC)外设的以下功能:
a.初始化和反初始化功能
ADC的初始化和配置
b.操作功能
启动,停止,得到常规转换的结果
组,使用3种可能的模式:轮询,中断或DMA。
c.控制功能
通道配置在常规组
模拟看门狗配置
d.状态函数
ADC状态机管理
中断和标志管理
(4)网络博客
通过网络搜索相关博客,可以浅层了解大概的功能,实现简单的例程。
【STM32】HAL库 STM32CubeMX教程九—ADC_cubemx adc-CSDN博客
STM32三个ADC同步规则采样_stm32怎么用一个计时器触发三个adc-CSDN博客
STM32ADC同步采样_stm32 两个 adc 可以 同时 采集-CSDN博客
详解STM32中的ADC – 知乎 (zhihu.com)
STM32H743-梳理ADC模数转换器在CubeMX上的配置_overrun behaviour-CSDN博客
stm32g474 实现5个独立ADC同步采样 – stm32/stm8 – 电子工程世界-论坛 (eeworld.com.cn)
【STM32】CubeMX+HAL库之ADC+DMA_hal_adc_start_dma-CSDN博客
基于STM32CubeMX的ADC设置 – 知乎 (zhihu.com)
使用CubeMX配置STM32F401的ADC+DMA手动触发非连续转换(LL库) (izilzty.com)
STM32CubeMX教程14 ADC – 多通道DMA转换 – OSnotes – 博客园 (cnblogs.com)
3.G4的ADC介绍
(1)通道与引脚
G473芯片有5个ADC,其中4个(成对)可以以双模式运行:
ADC1连接14个外部通道+4个内部通道
ADC2连接16个外部通道+2个内部通道
ADC3连接15个外部通道+3个内部通道
ADC4连接16个外部通道+2个内部通道
ADC5连接13个外部通道+5个内部通道
实际映射到外部引脚,共有40引脚(去掉了晶振占用的两个)。
(2)三种采集方式及具体实现
polling |
interruption |
DMA |
轮询 |
中断 |
DMA方式 |
- 轮询ADC转换:
(+++)激活ADC外设并开始转换
使用函数HAL_ADC_Start()
(+++)等待ADC转换完成
(+++)检索转换结果
函数HAL_ADC_GetValue()
(+++)停止转换并禁用ADC外设
使用函数HAL_ADC_Stop()
使用函数HAL_ADC_PollForConversion()
- 中断ADC转换:
(+++)激活ADC外设并开始转换
使用函数HAL_ADC_Start_IT()
(+++)通过函数调用等待ADC转换完成
HAL_ADC_ConvCpltCallback ()
(此功能必须在用户程序中实现)
(+++)检索转换结果
函数HAL_ADC_GetValue()
(+++)停止转换并禁用ADC外设
使用函数HAL_ADC_Stop_IT()
- ADC转换与DMA传输:
(+++)激活ADC外设并开始转换
使用函数HAL_ADC_Start_DMA()
(+++)通过函数调用等待ADC转换完成
HAL_ADC_ConvCpltCallback()或HAL_ADC_ConvHalfCpltCallback()
(这些功能必须在用户程序中实现)
(+++)转换结果由DMA自动转换成
目的变量地址。
(+++)停止转换并禁用ADC外设
使用函数HAL_ADC_Stop_DMA()
(3)多个ADC多通道的采集思路(未完待续)
因为通道属于不同的ADC,所以目前思路为:
使用ADC1、ADC2、ADC3 ,3个ADC均工作,采集多个通道。
配置3个ADC为独立工作模式,
ADC只有一个16位的DR数据寄存器(疑问,5个ADC是不是每个都有一个DR),所以:
先转换ADC1,数据依次在DR,使用DMA依次移动到存储长度为14的数组。
然后ADC2
最后ADC3
将3个数组数据发送出去
然后再ADC1,DMA仍旧循环重复存在原来的位置
(DMA配置需要的参数:1哪一个ADC触发DMA,2多少个数据,3一个数据的长度,4 存储是递增 5存完一个数组,等选择下一个ADC)
(4)具体配置
ADC配置
ADC1、ADC2、ADC3配置一样
ADCs_Common_Settings
Mode |
Independent mode |
模式 | 独立模式,该ADC单独工作 |
ADC_Settings
Clock Prescaler |
Synchronous clock mode divided by 2 |
Resolution |
ADC 8-bit resolution |
Data Alignment |
Right alignment |
Gain Compensation |
0 |
Scan Conversion Mode |
Enabled |
End Of Conversion Selection |
End of sequence of conversion |
Low Power Auto Wait |
Disabled |
Continuous Conversion Mode |
Disabled |
Discontinuous Conversion Mode |
Disabled |
DMA Continuous Requests |
Enabled |
Overrun behaviour |
Overrun data overwritten |
时钟分频器 | 同步时钟模式除以2 |
分辨率(自己选) | ADC 8位分辨率 |
数据对齐 | 右对齐 |
增益补偿 | 0 |
扫描转换模式 | 启用 |
转换结束(EOC)选择 | 转换序列结束 |
低功耗自动等待 | 禁用 |
连续转换模式 | 禁用 |
不连续转换模式 | 禁用 |
DMA连续请求 | 启用 |
溢出行为 | 溢出数据被覆盖 |
DMA连续请求(DMA Continuous Requests):该参数仅在配置DMA Request时使用。否则就无关紧要了。当此ADC实例的DMA请求时,此参数指定DMA请求是否为在一次模式下执行(DMA传输在达到转换数量时停止)或在连续模式下执行(DMA传输无限制,无论转换数量如何)。注意:在连续模式下,DMA必须配置为循环模式。否则,当达到DMA缓冲区最大指针时将触发溢出。
DMA Continuous Requests 为DMA内存填满后是否继续请求DMA,如果使用此选项,则需要打开DMA的Circular模式,否则会造成溢出。
ADC_Regular_ConversionMode:ADC常规转换模式
Enable Regular Conversions | Enable |
Enable Regular Oversampling | Disable |
Number Of Conversion | 13 |
External Trigger Conversion Source | Regular Conversion launched by software |
External Trigger Conversion Edge | None |
Rank | 1 |
Channel | Channel 6 |
Sampling Time | 2.5 Cycles |
Offset Number | No offset |
启用常规转换 | 启用 |
启用常规过采样 | 禁用 |
转换次数(共几个通道) | 13 |
外部触发转换源 | 由软件启动的常规转换 |
外部触发转换沿 | 无 |
序号 | 1 |
通道(自己选) | 通道6 |
采样时间 | 2.5个周期 |
偏移量 | 无 |
DMA配置
开启DMA中断
Priority:优先级,自己选
DMA Request Settings:DMA请求设置
Mode模式: Circular 地址循环
Peripheral 外设 | Memory 存储器 | |
Increment Address 增量地址 | 打勾 | |
Data Width 数据宽度(自己选) | Half Word 半字(16位) | Half Word 半字(16位) |
4.过程中遇到的问题
- ADC DMA只能采集1次
串口显示为
0x23
0
0X3D
0
问题解决:
怀疑是不是没有按照例程的half word配置cube。
答案:DMA的配置长度(word)32位和程序中定义变量的长度(uint16_t)16位不一致,导致无法进行下一次传输。
解决:cube中DMA数据长度改成(half word)16位,收到数据正常。
在32位系统中,1字(word)=4字节(byte)=32位(bit)