赞
踩
目录
扫描模式失能,间断模式失能,连续转换模式使能
规则模式使能
对于F1系列的芯片
HAL_ADCEx_Calibration_Start(&hadc1); //AD校准
F4则不需要,已经自动进行了校准
在while前只需启动一次ADC
HAL_ADC_Start(&hadc1); //启动ADC转换
定时读取adc
- if(adct>1000){
- adct=0;
-
- HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms
- if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
- {
- adcval[0] = HAL_ADC_GetValue(&hadc1); //获取AD值
- printf("ADC1 Reading : %d \r\n",adcval[0]);
- printf("PA1 True Voltage value : %.4f \r\n",adcval[0]*3.3f/4096);
-
- }
-
- }
串口读取
[2022-07-20_18:10:59:740]ADC1 Reading : 2017
[2022-07-20_18:10:59:740]PA1 True Voltage value : 1.6250
而单次转换每次转换都要启动adc
- HAL_ADC_Start(&hadc1); //启动ADC转换
- HAL_ADC_PollForConversion(&hadc1, 50); //等待转换完成,50为最大等待时间,单位为ms
这个问题困扰了我很久,轮询模式(单次加间断)我也试过了,多通道测试的时候数据不准,比如两个通道的引脚外接0或3.3v的电压,要么就都是0要么就都是3.3
但经过测试又读出来不一样两个通道的电压值又不一样
参考
stm32cubeMX配置ADC多通道采集(非dma和中断方式)_Error-500的博客-CSDN博客_stm32扫描多通道采集
对比cubeMX依据hal库生成的adc初始化代码
只要在cubeMX里配置多通道,那么多通道就给你使能了。
另外还有这两句
- sConfig.Channel = ADC_CHANNEL_5;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- /** Configure Regular Channel
- */
- sConfig.Channel = ADC_CHANNEL_1;
- sConfig.Rank = ADC_REGULAR_RANK_2;
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
这样配置明显后者设置的通道覆盖了前者,属于冗余的代码。
这是通道配置的结构体参数,也就是sConfig
再进入HAL_ADC_ConfigChannel(对寄存器进行赋值)
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
还是之前没有去仔细看配置过程,单纯为了用库而用库,所以按照很多教程(非DMA得多通道采样都失败了。)
最终看到正点原子文档上的代码。(它用的hal库,但延续了标准库的风格,所以完全就是自己写,没有用cubeMX去自动生成代码)
最终解决方法:简单地说就是让多通道变成单通道,改配置就好了,改的配置就是通道!因为cubeMX只生成了一次,所以就定义了一次配置。。。。
重写adc的初始化: 也就是变成单通道
- void MX_ADC1_Init(void)
- {
- ADC_ChannelConfTypeDef sConfig = {0};
-
- /** Common config
- */
- hadc1.Instance = ADC1;
- hadc1.Init.ScanConvMode = DISABLE;
- hadc1.Init.ContinuousConvMode = DISABLE;
- hadc1.Init.DiscontinuousConvMode = DISABLE;
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- hadc1.Init.NbrOfConversion = 1;
-
- }
另外引脚的GPIO初始化为模拟输入这个用cubeMX生成的就可以。
每次根据自己想读的adc通道去进行读取,也就是改adc句柄的配置,以adc1位例子
- u16 get_adc(u32 ch){
-
- ADC_ChannelConfTypeDef _adc;
- _adc.Channel=ch;
- _adc.Rank=1;
- _adc.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;
- HAL_ADC_ConfigChannel(&hadc1,&_adc);
- HAL_ADC_Start(&hadc1);
- HAL_ADC_PollForConversion(&hadc1,10);
- return (u16)HAL_ADC_GetValue(&hadc1);
- }
效果 (引脚测试电压正确)
结论:多通道按单通道配置。我测试的时候是单次转换和连续转换都行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。