1. 本次实践目标 a. 完成外部 ADC 的采集, 连接引脚为 PC2 b. 完成 STM32 内置温度传感器 ADC 的采集 c. ADC 的采集必须以 DMA 的方式工作,通过 FreeRTOS 系统中创建的一个进程读取采集结果,并打包通过网络发送至上位机 2. 查看 datasheet 2.1 确认 STM32 内部温度传感器 使用哪个 ADCx , 使用哪个 channel 经确认,STM32 内部温度传感器使用 ADC1 的 channel_16。
2.2 查看 PC2 引脚作为 ADC 输入时,使用哪个 ADCx, 使用哪个 channel 经确认,STM32 的 PC2 引脚可以使用 ADC[1,2,3] 的 channel_12。
2.3 通过上面的分析,可以选择 ADC1,进行 DMA 多通道采集 ADC 确认,使用 STM32 的 ADC1,后需要确认使用哪个 DMAx
经过确认,ADC1 使用 DMA1 4 R8 E" H6 s( e; e4 u
2.4 确认外设的时钟源 5 ~3 Y; o' c( T P: a确认 ADC1 的时钟源为 APB2 时钟分枝,并且 GPIOC 的时钟源也为 APB2 时钟分枝
2.5 研究 STM32 DMA 多通道采集的方法 2.5.1 位分辨率 ' B6 U0 ? I& v8 x 在STM32所有系列芯片中只有少部分是16位的,如:F373芯片。
12位分辨率意味着我们采集电压的精度可以达到:Vref /4096。
采集电压 = Vref * ADC_DR / 4096; " }7 C0 V6 k& j2 c, p+ H) W Vref:参考电压
ADC_DR:读取到ADC数据寄存器的值
8 y7 m$ s3 @+ S9 p4 g/ x 由于寄存器是32位的,在配置的时候分左对齐和右对齐,一般我们使用右对齐,也就是对低12位数据为有效数据。 V% J# A3 N( H1 ]: {9 c+ p 2.5.2 转换模式 3 v6 O" t G/ G) m% i3 C/ k7 Q A.单次和连续转换 ! i2 ?+ v( }1 m4 p 单次:单通道单次转换、多通道单次(分多次)转换;
连续:单通道连续转换、多通道连续(循环)转换; # n( W$ c# H0 x6 j0 X B.双ADC模式 ; L2 c9 X4 l' [$ P6 D0 u: g 也就是使用到了两个ADC,比如:ADC1和ADC2同时使用也就是双ADC模式。在该模式下可以配置为如下一些模式:同步规则模式、同步注入模式、独立模式等。
2.5.3 引脚配置
2.5.4 ADC 配置 ; ^' G9 ^+ N' z* Y/ P
A.初始化基本参数: ; v' q6 l# j, n n1 V# O- ^3 p DMA_PeripheralBaseAddr = ADC1_DR_Address;
#define ADC1_DR_Address ((u32)0x40012400+0x4c) #define ADC1_BUF_SIZE 2 #define TOTAL_CONVERT_CH_NUM 2
vu16 ADC_Buf[2];
其中 ADC1_DR_Address 可从数据手册中查得 * U, h$ ~# e) X0 O, `" r
5 H6 w+ s @5 j5 J! e3 y
* [3 U5 o% {# v 第一个参数 DMA_PeripheralBaseAddr 用来设置 DMA 传输的外设基地址,比如要进行ADC采集,那么外设基地址 ADC1 数据存储器 ADC1->DR 的地址,表示方法为 (u32) & ADC1->DR,当然也可以通过数据手册直接算出外设的地址。 第二个参数 DMA_MemoryBaseAddr 为内存基地址,也就是我们存放DMA传输数据的内存地址 = (u32)ADC_Buf。 第三个参数 DMA_DIR 设置数据传输方向,决定是从外设读取数据到内存还送从内存读取数据发送到外设,也就是外设是源地还是目的地,这里我们设置为从外设地址读取数据,所以外设是源地了,所以选择值为DMA_DIR_PeripheralSRC。 第四个参数 DMA_BufferSize 设置一次传输数据量的大小,我们需要采集两个通道的数据 所以设置为 ADC1_BUF_SIZE 第五个参数 DMA_PeripheralInc 设置传输数据的时候外设地址是不变还是递增。设置为DMA_PeripheralInc_Disable; 第六个参数 DMA_MemoryInc 设置传输数据时候内存地址是否递增,由于我们是多通道采集,因此需要递增 第七个参数 DMA_PeripheralDataSize 用来设置外设的的数据长度是为字节传输(8bits),半字传输(16bits)还是字传输(32bits),这里我们是 16 位半字传输,所以值设置为 DMA_PeripheralDataSize_HalfWord 第八个参数 DMA_MemoryDataSize 是用来设置内存的数据长度,同样设置为半字传输 DMA_PeripheralDataSize_HalfWord。 第九个参数 DMA_Mode用来设置DMA模式是否循环采集。 第十个参数是设置 DMA 通道的优先级,有低,中,高,超高三种模式,这里我们设置优先级别为高级,所以值为DMA_Priority_High。因为开启多个通道,这个值非常重要。 第十一个参数 DMA_M2M 设置是否存储到存储器模式传输设置为 DMA_M2M_Disable。
工作模式:ADC_Mode = ADC_Mode_Independent;
总共有10种,主要都是针对双ADC下使用。针对初学者这里不多描述,感兴趣的朋友可以先自行研究一下各个模式的使用。
% O3 X2 R4 @. @6 L1 a 浏览模式:ADC_ScanConvMode = ENABLE;
主要是针对多条通道而言,也就是说你是否有多条通道。
多通道:ENABLE;
单通道:DISABLE;
转换模式:ADC_ContinuousConvMode =ENABLE;
这里是配置是否需要连续转换。 / y. _9 f6 ]0 a$ H 连续转换ENABLE:也就是只需要启动(触发)转换一次,后面就不用再次启动(触发)就可以连续工作了。 . g; b5 i( T$ l7 d
单次转换DISABLE:也就是根据一次转换完后需要再次启动(触发)才能工作。 0 Z- @, b o( ^1 ` d( v. d- m- o/ ^
触发方式:ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
触发方式也就是使用什么方法触发ADC转换。哟定时器、外部触发、软件触发,一般常用软件触发。这里有很多种触发方式,详情可以参考其参数。 7 ?1 W; k' g- l# c: {0 U" V8 ]; ]& @
对其方式:ADC_DataAlign = ADC_DataAlign_Right; * |4 h5 q: b9 @ L& j" ?2 B: ^ 右对齐:低12位数据为有效位(常用); - i/ u3 E- Y5 ^! ?. `( ?$ d 左对齐:高12为数据为有效位; & N) j# I( P( e& z
通道数:ADC_NbrOfChannel =TOTAL_CONVERT_CH_NUM; 7 H8 K( b1 s0 R6 b, J 这个参数比较简单,我们定义工作的通道数量。 1 ~3 K6 B7 e% J4 ^2 @& o1 R) O
B.设置规则组通道:
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5); ( ^9 w3 U, Z- _, ^ ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
我们定义通道12的转换顺序为第1、通道16的转换顺序为第2;
至于为什么 ADC_Channel_16 的采集周期要设置为 ADC_SampleTime_239Cycles5,是因为 STM32 的内部温度传感器要求的,现在 ADC1 的时钟源为 APB2 时钟分枝 8 分频,即 72MHz/8 = 9MHz。而要求采样周期 ≥ 17.1us, 所以 17.1 * 9 = 153.9,而最接近的也就是 ADC_SampleTime_239Cycles5 Z0 K+ q# P) I2 l+ r
2.5.4 读取采集结果
转载自:xqhrs232 0 Y1 m$ `" b8 L" o2 |2 b; ^! {5 Q3 p8 R5 g |
基于STM32U5系列TIMER+DMA+DAC应用经验分享
基于STM32双定时器+ADC+DMA实战经验分享
基于STM32的定时器触发ADC时可能遇到的情形
基于STM32的ADC片内信号经验分享
基于STM32 DMA传输的两个问题释疑
基于STM32的Timer 结合 DMA 2D 通道实现不同波形输出
TIM DMA burst 输出变频 PWM 波形
基于STM32的 DMA 实验经验分享
基于STM32U5 ADC+DMA配置经验分享
基于STM32H563演示UART+DMA经验分享