基于HAL库的ADC采样(常规转换+注入模式)ADC_Regular_ConversionMode & ADC_Injected_ConversionMode


第一次使用,难免会有缺漏,后面发现不合适的地方会再进行更新

ADC Regular Conversion Mode下对多通道模拟信号进行采集的最好办法是使用DMA,即直接存储器读取方式。
但是在一些场合下,如电机控制,在SVPWM中我们要用到供电电压U_dc,并且我们也想知道温度信息,温度和电压我们使用常规通道即可,温压保护我们交给比较器。同时我们也需要知道实时的电流值,这个关系到我们在无感条件下到对电机转子的位置估计,对电机的稳定运行至关重要,要在每一个上桥关闭下桥打开时进行采样,因此在电机控制中常使用类似于中断的注入通道来对电流值进行采集,触发源选择为定时器,采集与SVPWM同步。
因此我们需要2个常规通道和3个注入通道,但是在对常规通道进行DMA方式采集时会导致注入通道失效,原因暂时不知,百度也没找到相应解决方案。所以我选择不用DMA,暂时通过判断ADC的状态寄存器ISR的相应位来进行数据采集。

ADC注入模式触发源TIM1初始化

TIM1的时钟为170MHz,经分频后为170MHz /(169+1) = 1MHz,周期为1000 * (1/1MHz) = 1ms,并选择触发输出OC4REF,这里选择Channel4输出是因为前面三个通道要用作输出6路互补PWM波,并且不是每一个输出比较器OC都可作为ADC注入模式的触发源
image.png
占空比设置为10(不是0就行)
image.png

ADC初始化

ADC的可选触发源(Regular/Injected)

ADC_Injected触发源我们这里选择的是TIM1_CC4,因为tim1_trgo比较麻烦,用在这里不合适

在这里插入图片描述
以下是手册对ADC触发源的说明
image.png
image.png

ADC初始化

ADC1初始化配置如下,我们设置ADC数据为右对齐,因为此单片机ADC最大可选精度为12位,故左对齐的话需要将数据右移四位才是正确数据,而右对齐则不用。在进行多通道数据采样时需要使能Scan Conversion Mode,单通道不用
在这里插入图片描述

ADC_Regular_Mode

常规通道采用软件触发,采样时第一个通道就是以下Rank 1channel 1,第二个通道就是以下Rank 2channel 5,至于是哪个通道由我们自己选择,采样时间越长采样越准
image.png

ADC_Injected_Mode

在这里插入图片描述
我们可以打开ADC的中断,在中断处理函数里做一些处理

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

在这里插入图片描述

ADC采样时间

ADC最小采样周期为2.5Cycles,12.5是固定的12位数据的转换时间故一个ADC通道的转换时间

$T_{CONV} = (T_{simpling} + T_{12.5}) * T_{ADC_CLK}$

在这里插入图片描述
在这里插入图片描述

ADC数据读取

ADC_Regular_Mode常规通道数据读取

在手册里可以找到对ADC_ISR寄存器的描述
在这里插入图片描述
‘数据完成转换后被硬件置位,并且在DR寄存器被读后清除。我们可以利用这个标志来决定什么时候去读数据。当然,EOS也可以作为一个判断,只是在这里只判断EOC就可以了。

//      HAL_ADC_Start(&hadc1);
		hadc1.Instance->CR |= 0x04;
		//wait conversion complete
		while((hadc1.Instance->ISR & 0x04) == 0){	  
		}
//		adc_buffer[0] = HAL_ADC_GetValue(&hadc1);//读第一个通道
		adc_buffer[0] = hadc1.Instance->DR;
		//wait regular sequence complete
		while((hadc1.Instance->ISR & 0x04) == 0){
		}
//		adc_buffer[1]=HAL_ADC_GetValue(&hadc1);//读第二个通道
		adc_buffer[1] = hadc1.Instance->DR;
		HAL_Delay(1000);
ADC_Injected_Mode数据读取

直接读ADC的JDR寄存器即可,Rank1的数据保存在JDR1,Rank2的数据保存在JDR2,什么时候用什么时候读

adc_injected_buffer[0] = LPF_current(hadc1.Instance->JDR1 * 3.3 / 4096);

在这里插入图片描述

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>