Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ADC设备
STM32
设备驱动
STM32 ADC使用心得分享
发布于 2024-01-27 15:19:32 浏览:1158
订阅该版
[tocm] # STM32 ADC使用心得分享 最近对 stm32 的 adc 使用的比较多,也稍微有一点深入,之前都是简单使用,没有过多研究,发现还是有很多很意思的地方,并且一些功能在网上的介绍和使用也是比较少的,就想分享一下自己摸索的过程和思考,有些功能可能我用的也不太对或者有更好的用法,欢迎大家交流 ## 基本功能 我们通过 adc 可以直接读取到电压的大小,通过对读取到的电压进行转换可以获取到电流、温度等模拟信号的数字转换结果。在 stm32 中通常具备 3 个 adc ,每个 adc 又具备十多个通道,每个通道可以对应引脚采集数据(部分通道仅用于采集内部数据,没有引出外部引脚),其中规则通道最多有16路,注入通道最多有4路。有的 adc 之间还可以配置为主从模式,进行交叉采样等更复杂高级的操作,一般电机控制时用的比较多。但是需要注意的是,对于 adc 中的多个通道,**一般是不能直接指定通道进行读取**的,除非将通道使能为**注入模式**(稍后介绍)。之前我一般 adc 只会用到 1 个通道,是否指定其实都只能读到那一个通道,所以并没有注意到这个地方。但要写设备驱动就必须要做好通用性,为用户屏蔽好这些比较绕的问题。 ## 规则模式 规则模式(Regular)就是一般的普通模式,也是使用的比较多的。一般可以设置三个寄存器序列,可以根据自己的需要将多个规则通道划分到指定序列中的指定位置,开启 adc 序列转换后,就会开始按顺序对序列中的通道进行扫描转换。单数需要注意的是,每个 adc 只有一个规则数据寄存器,只够存储一个通道的数据,数据是会被覆盖的。也就是说在每个通道的数据读取完成以后,我们需要及时取出,并按顺序进行区分。可以用一个数组去存取转换的数据,之前设定的序列,也就知道的指定通道对应的数据。 一般还可以采用结合 DMA 的方式,在读取到数据后,将数据按顺序进行逐个装填,我们也能得到指定通道顺序的数据。 ## 注入模式 注入模式有点像中断,可以选择多种触发源,也可以用户软件触发,可以直接打断正在进行的规则通道转换。最多可以使能 4 个通道作为注入通道,并且每个通道都具备自己的数据寄存器,不会存在数据覆盖的问题。对于 DMA 资源紧张,不想引入阻塞,不便于维护转换序列时,可以选择采用该模式。 ## 交叉模式 交叉模式需要将两个adc配置为主从关系进行,一般是 ADC1/2,具体可参考官方手册。 ## 注意事项 - 规则通道数据寄存器只有一个,会存在数据覆盖问题,需要做好数据维护对应工作; - 通道使能为注入模式后无法使用连续转换模式; - 每个ADC只能使用4个注入模式通道,需要主要资源分配; - ADC的数据寄存器不会存在读取到脏数据的情况; ## 设备驱动对比 接下来分析对比一下主流RTOS的adc设备驱动都是怎么写的,是如何为用户屏蔽好这些比较绕的底层细节的。 ### RT-Thread adc初始化设置如下,关闭连续采样模式: ```c #define ADC1_CONFIG \ { \ .Instance = ADC1, \ .Init.DataAlign = ADC_DATAALIGN_RIGHT, \ .Init.ScanConvMode = ADC_SCAN_DISABLE, \ .Init.ContinuousConvMode = DISABLE, \ .Init.NbrOfConversion = 1, \ .Init.DiscontinuousConvMode = DISABLE, \ .Init.NbrOfDiscConversion = 1, \ .Init.ExternalTrigConv = ADC_SOFTWARE_START, \ } #endif /* ADC1_CONFIG */ ``` 均设置为规则通道,并放到同一个序列中: ```c ADC_ChanConf.Rank = ADC_REGULAR_RANK_1; ``` 读取函数:(入参有 channel,但并没有用) ```c static rt_err_t stm32_adc_get_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value) { ADC_HandleTypeDef *stm32_adc_handler; RT_ASSERT(device != RT_NULL); RT_ASSERT(value != RT_NULL); stm32_adc_handler = device->parent.user_data; /* Wait for the ADC to convert */ HAL_ADC_PollForConversion(stm32_adc_handler, 100); /* get ADC value */ *value = (rt_uint32_t)HAL_ADC_GetValue(stm32_adc_handler); return RT_EOK; } ``` 去adc设备设备驱动看看怎么维护的: ``` static rt_ssize_t _adc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) { rt_err_t result = RT_EOK; rt_size_t i; struct rt_adc_device *adc = (struct rt_adc_device *)dev; rt_uint32_t *value = (rt_uint32_t *)buffer; for (i = 0; i < size; i += sizeof(int)) { result = adc->ops->convert(adc, pos + i, value); if (result != RT_EOK) { return 0; } value++; } return i; } ``` 可以看出来就是我们说的第一种方法,所有通道为规则模式,同一转换序列,逐个读取并对按序存储到数组中。 ## Zephyer Zephyer 采用的方法是规则通道序列读取,引入 DMA 进行维护,相比起来更加高效一些,不会引入阻塞。在DMA 资源不紧张的时候使用这种方法是比较好的。Zephyer 的设备驱动一般只要有中断,那就都是基于中断实现的,更加高效,有助于提高系统实时性,降低CPU占用。之后要是有时间的话,看看能不能优化一下rtt的adc设备驱动。 ## Refer - [STM32H723/733, STM32H725/735 and STM32H730 Value line advanced Arm®-based 32-bit MCUs - Reference manual](https://www.st.com/resource/en/reference_manual/rm0468-stm32h723733-stm32h725735-and-stm32h730-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) - [野火\]STM32库开发实战指南——基于野火指南者开发板 文档 (embedfire.com)](https://doc.embedfire.com/mcu/stm32/f103zhinanzhe/std/zh/latest/book/ADC.html)
4
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
螺丝松掉的人
这家伙很懒,什么也没写!
文章
42
回答
0
被采纳
0
关注TA
发私信
相关文章
1
裸机工程移植 RT-Thread
2
Keil MDK 移植 RT-Thread Nano
3
移植 Nano,rt_thread_mdelay()延迟时间不对
4
裸机工程移植 RT-Thread内核
5
关于利用0x68000000作为扩展sram?
6
STM32F413 SD 卡写入速度提升方法
7
STM32 RTC 闹钟
8
http_ota 提示no memory
9
studio中怎么把PB3 和PA15引脚设置为普通IO口使用?
10
求一份基于RTT系统封装好的STM32F1系列的FLASH操作程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部