当前位置:   article > 正文

STM32基于HAL库的非DMA的轮询ADC单通道与多通道的采样_hal_adc_configchannel

hal_adc_configchannel

目录

单通道(连续转换模式)

单通道(单次转换模式) 

非DMA的多通道采样


单通道(连续转换模式)

扫描模式失能,间断模式失能,连续转换模式使能

规则模式使能

 

对于F1系列的芯片

HAL_ADCEx_Calibration_Start(&hadc1);    //AD校准

F4则不需要,已经自动进行了校准

在while前只需启动一次ADC

 HAL_ADC_Start(&hadc1);     //启动ADC转换

定时读取adc

  1. if(adct>1000){
  2. adct=0;
  3. HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms
  4. if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
  5. {
  6. adcval[0] = HAL_ADC_GetValue(&hadc1); //获取AD值
  7. printf("ADC1 Reading : %d \r\n",adcval[0]);
  8. printf("PA1 True Voltage value : %.4f \r\n",adcval[0]*3.3f/4096);
  9. }
  10. }

 串口读取

[2022-07-20_18:10:59:740]ADC1 Reading : 2017 
[2022-07-20_18:10:59:740]PA1 True Voltage value : 1.6250 

 

单通道(单次转换模式) 

而单次转换每次转换都要启动adc

  1. HAL_ADC_Start(&hadc1); //启动ADC转换
  2. HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms

非DMA的多通道采样

这个问题困扰了我很久,轮询模式(单次加间断)我也试过了,多通道测试的时候数据不准,比如两个通道的引脚外接0或3.3v的电压,要么就都是0要么就都是3.3

但经过测试又读出来不一样两个通道的电压值又不一样

 

参考

stm32cubeMX配置ADC多通道采集(非dma和中断方式)_Error-500的博客-CSDN博客_stm32扫描多通道采集

对比cubeMX依据hal库生成的adc初始化代码

只要在cubeMX里配置多通道,那么多通道就给你使能了。

另外还有这两句

  1. sConfig.Channel = ADC_CHANNEL_5;
  2. sConfig.Rank = ADC_REGULAR_RANK_1;
  3. sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  4. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  5. {
  6. Error_Handler();
  7. }
  8. /** Configure Regular Channel
  9. */
  10. sConfig.Channel = ADC_CHANNEL_1;
  11. sConfig.Rank = ADC_REGULAR_RANK_2;
  12. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  13. {
  14. Error_Handler();
  15. }

这样配置明显后者设置的通道覆盖了前者,属于冗余的代码。

这是通道配置的结构体参数,也就是sConfig 

 再进入HAL_ADC_ConfigChannel(对寄存器进行赋值)

 

#define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))

还是之前没有去仔细看配置过程,单纯为了用库而用库,所以按照很多教程(非DMA得多通道采样都失败了。)

最终看到正点原子文档上的代码。(它用的hal库,但延续了标准库的风格,所以完全就是自己写,没有用cubeMX去自动生成代码)

最终解决方法:简单地说就是让多通道变成单通道,改配置就好了,改的配置就是通道!因为cubeMX只生成了一次,所以就定义了一次配置。。。。

 

 重写adc的初始化: 也就是变成单通道

  1. void MX_ADC1_Init(void)
  2. {
  3. ADC_ChannelConfTypeDef sConfig = {0};
  4. /** Common config
  5. */
  6. hadc1.Instance = ADC1;
  7. hadc1.Init.ScanConvMode = DISABLE;
  8. hadc1.Init.ContinuousConvMode = DISABLE;
  9. hadc1.Init.DiscontinuousConvMode = DISABLE;
  10. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  11. hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  12. hadc1.Init.NbrOfConversion = 1;
  13. }

另外引脚的GPIO初始化为模拟输入这个用cubeMX生成的就可以。

每次根据自己想读的adc通道去进行读取,也就是改adc句柄的配置,以adc1位例子

  1. u16 get_adc(u32 ch){
  2. ADC_ChannelConfTypeDef _adc;
  3. _adc.Channel=ch;
  4. _adc.Rank=1;
  5. _adc.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;
  6. HAL_ADC_ConfigChannel(&hadc1,&_adc);
  7. HAL_ADC_Start(&hadc1);
  8. HAL_ADC_PollForConversion(&hadc1,10);
  9. return (u16)HAL_ADC_GetValue(&hadc1);
  10. }

效果 (引脚测试电压正确)

 

结论:多通道按单通道配置。我测试的时候是单次转换和连续转换都行。

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/125991
推荐阅读
相关标签
  

闽ICP备14008679号