rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

[stm32][adc]更改配置通道与校准函数顺序

Open wdfk-prog opened this issue 3 years ago • 8 comments

  • 添加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

image

  • 测试代码如下
#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

wdfk-prog avatar Dec 20 '22 05:12 wdfk-prog

这个PR可否找一个非h7的型号测一下?

mysterywolf avatar Dec 24 '22 20:12 mysterywolf

这个PR可否找一个非h7的型号测一下?

  • F4测了一下.编译过不了了.... image
  • F4是17\18就是相应测量通道... image
  • 我修改一下吧~

wdfk-prog avatar Dec 26 '22 01:12 wdfk-prog

是的 因为H7系列和其他的系列不太一样,所以最好H7测一遍,再找一个非H7的测一下😂

mysterywolf avatar Dec 26 '22 01:12 mysterywolf

是的 因为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);

wdfk-prog avatar Dec 26 '22 02:12 wdfk-prog

  • 我用F429进行了测试没问题了.

  • default是为了兼容,有些芯片温度和参考电压通道就是0~19里面的通道.剩下不是的再在default里选择一遍 image

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

image

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

wdfk-prog avatar Dec 26 '22 03:12 wdfk-prog

  • 本来想把测量温度的函数也集成进去.
  • 发现有些芯片可以使用__HAL_ADC_CALC_TEMPERATURE,芯片内部寄存器已经有了校准值了.
  • 有些芯片没有,只能用__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS.这个函数得自己看数据手册填参数,每个手册不一样,就没有操作.

wdfk-prog avatar Dec 26 '22 03:12 wdfk-prog

没关系可以正确获取原始温度ADC就可以了,stm32不同型号计算温度的公式貌似还不一样,所以adc转温度留给用户按照手册去操作就可以了

mysterywolf avatar Dec 26 '22 05:12 mysterywolf

l475潘多拉测试通过

mysterywolf avatar Dec 26 '22 07:12 mysterywolf