[stm32][adc]更改配置通道与校准函数顺序
- 添加16位与14位分辨率配置
- 添加内部参考电压与温度,电池电压通道配置
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
- 更改配置通道与校准函数顺序 在使能函数中配置通道更为合适
- 添加16位与14位分辨率配置 H7芯片支持16位与14位分辨率
- 添加内部参考电压与温度,电池电压通道配置 在H7芯片中,使用17~19通道去读取上述信息值错误. 需要单独配置通道,才可读取正常
你的解决方案是什么 (what is your solution)
- 进行修改
在什么测试环境下测试通过 (what is the test environment)
- ART-PI H750

- 测试代码如下
#include <rtthread.h>
#include <rtdevice.h>
#include <main.h>
#define ADC_DEV_NAME "adc3" /* ADC 设备名称 */
#define ADC_VREF_CHANNEL ADC_CHANNEL_VREFINT - ADC_CHANNEL_0 /* ADC Vref 通道 */
#define ADC_TEMP_CHANNEL ADC_CHANNEL_TEMPSENSOR - ADC_CHANNEL_0 /* ADC Temp 通道 */
static int adc_vol_sample(void)
{
rt_uint32_t vref_value,temp_value;
rt_uint16_t vref_mv,temp_mv;
rt_adc_device_t adc_dev;
rt_err_t ret = RT_EOK;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
return RT_ERROR;
}
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_VREF_CHANNEL);
/* 读取采样值 */
vref_value = rt_adc_read(adc_dev, ADC_VREF_CHANNEL);
/* 关闭通道 */
ret = rt_adc_disable(adc_dev, ADC_VREF_CHANNEL);
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_TEMP_CHANNEL);
/* 读取采样值 */
temp_value = rt_adc_read(adc_dev, ADC_TEMP_CHANNEL);
/* 关闭通道 */
ret = rt_adc_disable(adc_dev, ADC_TEMP_CHANNEL);
rt_kprintf("Vref is %u.\n", vref_value);
rt_kprintf("Temp is %u.\n" , temp_value);
// Calculating Vref voltage
vref_mv = __HAL_ADC_CALC_VREFANALOG_VOLTAGE(vref_value, ADC_RESOLUTION_16B);
rt_kprintf("Vref voltage is %u mV.\n", vref_mv);
// Calculate Temperature
rt_kprintf("%d are Temperature in Degree C.\n",
__HAL_ADC_CALC_TEMPERATURE(vref_mv, temp_value, ADC_RESOLUTION_16B));
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
- [ ] 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
- [x] 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
- [x] 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
- [x] 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
- [x] 没有垃圾代码,代码尽量精简,不包含
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up - [x] 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
- [ ] 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
- [x] 代码是高质量的 Code in this PR is of high quality
- [x] 已经使用formatting等源码格式化工具确保格式符合RT-Thread代码规范 This PR complies with RT-Thread code specification
这个PR可否找一个非h7的型号测一下?
这个PR可否找一个非h7的型号测一下?
- F4测了一下.编译过不了了....

- F4是17\18就是相应测量通道...

- 我修改一下吧~
是的 因为H7系列和其他的系列不太一样,所以最好H7测一遍,再找一个非H7的测一下😂
是的 因为H7系列和其他的系列不太一样,所以最好H7测一遍,再找一个非H7的测一下😂
- 我修改了一下,把F4可以使用了
- F429芯片内部温度测出来的和我这室温差不多...我不知道有没有问题,摸起来倒是没感觉
- F7的四十多度倒是正常
msh />adc_vol_sample
Vref is 1502.
Temp is 947.
Vref voltage is 3328 mV.
7 are Temperature in Degree C.
- 测试代码如下
#include <rtthread.h>
#include <rtdevice.h>
#include <main.h>
#define ADC_DEV_NAME "adc1" /* ADC 设备名称 */
#define ADC_VREF_CHANNEL ADC_CHANNEL_VREFINT - ADC_CHANNEL_0 /* ADC Vref 通道 */
#define ADC_TEMP_CHANNEL ADC_CHANNEL_TEMPSENSOR - ADC_CHANNEL_0 /* ADC Temp 通道 */
static int adc_vol_sample(void)
{
rt_uint32_t vref_value,temp_value;
rt_uint16_t vref_mv,temp_mv;
rt_adc_device_t adc_dev;
rt_err_t ret = RT_EOK;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
return RT_ERROR;
}
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_VREF_CHANNEL);
/* 读取采样值 */
vref_value = rt_adc_read(adc_dev, ADC_VREF_CHANNEL);
/* 关闭通道 */
ret = rt_adc_disable(adc_dev, ADC_VREF_CHANNEL);
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_TEMP_CHANNEL);
/* 读取采样值 */
temp_value = rt_adc_read(adc_dev, ADC_TEMP_CHANNEL);
/* 关闭通道 */
ret = rt_adc_disable(adc_dev, ADC_TEMP_CHANNEL);
rt_kprintf("Vref is %u.\n", vref_value);
rt_kprintf("Temp is %u.\n" , temp_value);
// Calculating Vref voltage
vref_mv = __LL_ADC_CALC_VREFANALOG_VOLTAGE(vref_value, ADC_RESOLUTION_12B);
rt_kprintf("Vref voltage is %u mV.\n", vref_mv);
// Calculate Temperature
rt_kprintf("%d are Temperature in Degree C.\n",
__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(2500,760,10,vref_mv, temp_value, ADC_RESOLUTION_12B));
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
-
我用F429进行了测试没问题了.
-
default是为了兼容,有些芯片温度和参考电压通道就是0~19里面的通道.剩下不是的再在default里选择一遍

-
直接用HAL_ADC_Start,是因为HAL_ADC_Start里已经包含ADC_Enable了,不需要重复.


- __LL_ADC_CALC_VREFANALOG_VOLTAGE进行宏判断是因为有些芯片(如F7或者旧版本HAL库)没有这个函数,只能用数字代替.

- 本来想把测量温度的函数也集成进去.
- 发现有些芯片可以使用__HAL_ADC_CALC_TEMPERATURE,芯片内部寄存器已经有了校准值了.
- 有些芯片没有,只能用__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS.这个函数得自己看数据手册填参数,每个手册不一样,就没有操作.
没关系可以正确获取原始温度ADC就可以了,stm32不同型号计算温度的公式貌似还不一样,所以adc转温度留给用户按照手册去操作就可以了
l475潘多拉测试通过