当前位置:   article > 正文

STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度_tim+adc+dma采集

tim+adc+dma采集

STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度



注:本片文章以STM32F103系列为例,其他系列可能稍有不同。


1、ADC简介

1.1 采样定理
1.2 模式介绍
  • 扫描模式: 使用STM32CUBEMX配置了多通道后,这一项默认开启且无法设置成关闭。这个模式就是自动扫描你开启的所有通道进行转换,直至转换完。例如你开启了CH0、CH1、CH2、CH3这四个通道,启动转换后ADC会自动将这4个通道全部转换完,但是这种连续性是可以被打断的,所以就引出了间断模式。

  • 连续模式: 在CUBE中选中ENABLE就是连续模式,DISABLE就是单次模式。开启连续模式后,ADC的转换不由其他控制。例如将ADC设置为了定时器的TGRO触发采样,如果开启连续模式,ADC将忽略定时器的触发采样。(连续转换模式开启后其实就是满频率的采样)。

  • 间断模式: 可以将多个通道进行分组采集,例如你开启了CH0~3这4个通道,假如你设置了间断次数为4,就相当于将4个通道分成了4组,每组1个通道,那么要想采集完这4个通道就需要手动触发4次ADC采集;如果设置了间断次数为2,那么采集完4个通道就需要手动触发2次ADC采集。

1.3 采样时间和采样频率的计算

ADC采样两点间隔的时间一定要大于ADC的采样时间! 采样时间怎么算,下面就细说一下。

STM32F103一般将时钟配置主频为72M、APB2为72M。ADC挂在APB2时钟总线上,且ADC的时钟不能超过14M。所以一般将ADC的分频设置为6,ADC的时钟主频就为72/6=12MHz。那么一个周期就是:1/12MHz=0.0833us。

以下截图为STM32F1参考手册(手册编号RM0008,可在ST官网直接搜索下载):

上图的意思是:ADC对输入电压采样若干个ADC_CLK周期,这些周期可通过ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位进行修改。每个通道都可以用不同的采样时间进行采样。

ADC转换时间 = 采样时间 + 12.5个周期

示例:
         ~~~~~~~~         当ADC时钟主频为14MHz并且采样时间为1.5个周期时:采样时间 = 1.5 + 12.5 = 14个周期;一个周期的时间为1/14MHz,一共14个周期,1 / 14MHz * 14个周期 = 1us,那么此时ADC的采样频率就是1/1us=1000KHz=1MHz,这也是理论上ADC的最大采样频率。

STM32F1系列的时钟主频一般设置为了12M,采样时间的设置所对应采样频率如下图所示:

知道了最短时间后,当ADC时钟主频为12M并且采样时间为1.5个周期时,ADC采样两点的时间必须大于1.17us。

而STM32F031系列的ADC时钟主频为14MHz,采样时间的设置所对应采样频率如下图所示:

当ADC时钟主频为14M并且采样时间为1.5个周期时,ADC采样两点的时间必须大于1us。


2、轮训方式的多通道采集

2.1 方式一:间断模式+扫描模式

我开启了通道0、1、2以及内部温度读取通道一共四个通道:

在这里插入图片描述
在这里插入图片描述
如果想使用轮训方式并且不使用DMA的多通道采集,那么就要配置为 【单次模式+间断模式】,并且将Number Of Discontinuous Conversions为1,也就是每个通道分成了一个组,配置如下图:
在这里插入图片描述

由于我这里设置间断数为1,也就是将4个通道分成了4组,那么我每次采集的时候都需要手动去触发ADC采集,也就是调用一次HAL_ADC_Start函数,完整代码如下:

在这里插入图片描述
我将通道0分别接到3.3V和GND上,4通道采集运行效果如下:

在这里插入图片描述

2.2 方式二:完全轮训

完全使用轮训的方式不能使用扫描模式(理论上来说多通道需要使用扫描模式,而不是完全轮训),但是使用STM32CUBEMX配置多通道扫描模式不无法被关闭的,所以我们先用STM32CUBEMX配置成一个通道:

然后读取ADC采集数值的函数是这样:

uint16_t ADC_Read(uint32_t Channel)
{
	ADC_ChannelConfTypeDef sConfig = {0};
	sConfig.Channel = Channel;                                         /* 通道 */
	sConfig.Rank = ADC_REGULAR_RANK_1;                              
	sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;                  /* 采样时间 */
	if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)             
	{
		Error_Handler();
	}
	HAL_ADC_Start(&hadc1);
	HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
	return (uint16_t)HAL_ADC_GetValue(&hadc1);
}

/*
	uint16_t ADC_Value[5];
	
	ADC_Value[0] = ADC_Read(ADC_CHANNEL_1);  // 采集并读取通道1
	ADC_Value[1] = ADC_Read(ADC_CHANNEL_4);
	ADC_Value[2] = ADC_Read(ADC_CHANNEL_5);
	ADC_Value[3] = ADC_Read(ADC_CHANNEL_6);
	ADC_Value[4] = ADC_Read(ADC_CHANNEL_7);
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

3、DMA实现多通道采集

通过DMA实现多通道数据采集,要将连续模式和间断模式关闭!

如果连续模式开启,那么通过DMA传输到的数组中,每个通道所采集到的值对应数组中的一个位置就是不固定的。

例如你开启了IN0~IN3这四个通道,并通过DMA将这四个通道的数据放到ADC_Value这个大小为4的u16类型数组,

你在第一次采集的时候IN0通道的数值通过DMA被放在ADC_Value[0],

第二次采集的时候IN0采集到的数值就可能被放到了ADC_Value[1],

这样的话就极不方便我们对每个通道的数据进行分析和提取。

配置如下,将连续转换模式和间断转换模式关闭,并开启ADC的DMA通道,将DMA的模式配置为周期模式:

在这里插入图片描述

代码如下:


4个通道采集运行效果如下:

在这里插入图片描述


4、TIM+DMA实现多通道采集

在不使用DMA的情况下,定时器控制ADC进行数据采集只能是单通道!如果开启了多通道,读取到的ADC采集值只会是最后一个通道的值!

所以,要想使用定时器控制ADC采集多通道,必须使用DMA!

CubeMX配置如下,使能ADC的DMA:

ADC的触发方式设置为定时器3的触发事件:

采样时间设置为了55.5个周期,对应采样频率为176.47KHz,所以定时器3的频率设置要低于176.47KHz。

设置定时器3分频系数为72,重载值为10,得到72MHz / 72分频 / 10 = 100KHz的定时器3:

代码如下:

运行结果如下:

当然也可以选择进行一组数据,例如将32个点为一组数据进行采集,设置如下:

运行结果如下:


5、补充:内部温度传感器ADC通道


上面图片是截取在STM32F103RC的datasheet中的,中文意思就是:温度传感器必须产生随温度线性变化的电压。转换范围在2v < VDDA < 3.6 V之间。温度传感器内部连接ADC1_IN16输入通道,用于将传感器输出电压转换为数字值。

内部温度计算公式:

【Temperature = {(V25 - VSENSE) / Avg_Slope} + 25】

字段说明:

  • V25: 最小1.34V,最大1.52V,典型值1.43V
  • Avg_Slope: 最小4.0,最大4.6,典型值4.3mv/℃
  • VSENSE: ADC采集到的电压

ADC值转电压值计算公式:【电压 = ADC采集到的值 * 3.3 / 4096】

看上图我采集到的值为1703,先转换为电压值:1703*3.3/4096≈1.37

(1.43 - 1.37)/ 0.0043 + 25 ≈ 38.95℃


ends…

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

闽ICP备14008679号