
前言 有的项目中需要对多个通道的电压进行一定频率的AD采样。6 s4 s) [* c! O$ h5 D 第一种:是使用定时器去读取,通过检查转换完成标志位来读取,但这样就会加重整个系统的负担,占用CPU资源。- F3 V; a# X, |# h+ t 第二种:是采用定时器触发多通道ADC扫描采样,且采样数据由DMA传到RAM中的缓存,通过DMA中断来获取数据。比如我们这次项目中就要1kHz的速度读取DMA,并通过DMA传输。; ~ e/ `& L1 B1 f; o9 v 这样做有以下几个好处:4 R7 |8 `" o' ]8 {# W 1、由定时器触发ADC采样,这样采样的频率可控,且定时器触发不会占用任何CPU资源;/ P2 k+ r; S6 X! \! z 2、DMA进一步降低了任务对CPU的占有率。5 X3 p" S4 M8 R. [6 k 2 f9 `# C: C |0 p3 T 1、硬件原理* {! o8 E: Q* D* S4 l, @2 a: Y 1.1定时器" T" S. Q. j# w9 w- \" A. w" w, f0 \" X 该项目中,我们选择TIM2的TRGO为触发源来触发ADC的转换。5 z* @: F. ^; M! b 即使用该函数: ![]() 下图为ADC转换的触发条件: ![]() 1.2 ADC STM32F407的ADC的有规则通道和注入通道,规则通道扫描采样,配置好规则通道后,定时器更新后 触发ADC转换,ADC转换完成后触发DMA传输。; I3 P5 D3 y* S. C+ n 6 i3 R; j1 h* a) Y 如下图为ADC 内部使用框图:& L6 n7 N9 m, E2 q1 S ![]() 1.3 DMA传输 STM32F407有DMA1 和DMA2两个控制器,下图为 DMA的请求映射。 ![]() ![]() 我们使用的ADC1,也就是DMA的数据流stream0 通道0,用ADC的转换完成标志触发DMA数据传输。 2、代码部分2 W' R" U9 @6 g' F* x3 p 2.1定时器/ Z) G0 A3 p5 s( a 2.1定时器初始化, F, {' I! K3 U6 ~; Z; J 我们采用的10K hz的读取频率,定时器使用的是TIM2,TIM2是挂载在APB1总线上面,时钟频率为84M。 我们设置TIM2时钟分频为84,即1秒钟计数1M个,每计数100个触发一次定时器中断(这里只是用于测试, 与触发ADC转换没有必然的联系)。$ M: n1 v" l8 e/ F8 l6 [ G ![]() ![]() 2.12 定时器中断函数; a+ a" L6 l7 r. m0 B2 S 为了测试定时器是否正常中断,我们加了定时器中断函数,并通过IO口的电平翻转进行测试。, _2 O8 j/ d: a, Y% ~$ A ![]() 通过逻辑分析仪可以看出,定时器按照设定的时间周期定时中断。 可以看出方波的频率5Khz,则进入定时器的频率为10Khz,则1秒钟触发了10Khz次ADC转换。 }7 h0 q9 v& X6 W ![]() 2.2 ADC部分% s. j2 g6 M* g0 o; e) c 每个通道都可以单独配置为不同的采样时间,我们获取ADC的频率为10khz,一共要转换的规则通道数为4, 也就是说留给每一路的转换时间最大是25us。 ![]() . p/ `& G6 o" H1 P y; ^$ v 由上图可得,在30M的ADC时钟频率下,12位ADC的最大转换时间为16.40us,虽然我们采用的是21M时钟" l/ n _; F4 q; ]) o L) n 时间也不会多到哪里去,依然满足我们的采样要求。ADC初始化代码部分- e, _( l, y! u1 L& A ![]() 设置规则转换通道和单路转换时间 ![]() 我们设置规则转换 通道数为4,转换优先级根据ADC_RegularChannelConfig函数) }5 t0 ?9 N5 _8 ~ void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)中、 bank的大小而决定。& u2 Z( i/ R9 b 每一路的采样时间为84个时钟周期,约等于5us左右,符合25us范围。" ]- {5 {3 y0 s) ~% U 2.3 DMA部分( a7 n& v. _) t) `0 a; |, _# | ![]() 2.4 main函数部分 我们定时DMA传输数据的个数 len 为64个字节 1ADC通道是2个字节,则4个通道就是8个字节 64个字节需要8次DMA传输,则会触发DMA传输中断。数据存储的输出uint16_t ADC_Rx[100];//接收的数据,即原地址 即DMA传输来的数据会存在该数组中。2 a% V6 T% J& y# Q- l8 Q7 q5 t ![]() 下图为仿真数据,我们将通道2接在GND上,因为为四个通道,所以每间隔3个位,会得到几乎相同的数据,1 c4 U/ K8 i* @4 }" T5 Y 也就是0V所对应的ADC值,数值在0左右,如下图所示。2 q6 m' K9 N& y* D1 k+ X ![]() s6 }4 c: ^. Z) I* N % \& T( |* r7 {$ S* Z 附加知识) d6 [- q4 a9 M/ x5 @0 s ADC注射转换 ADC注射转换最大可以插入四个通道。& E% b5 i, U% Z2 O# x% |! o X% e$ S # _9 G" Q) M6 J+ X- J 设置注入转换的通道数为1,通道号为14。. P' | z5 |; Z2 u k ![]() ADC_AutoInjectedConvCmd(ADC1,ENABLE)该函数作用是在规则ADC转换完成后,自动执行插入ADC通道的转换。 插入ADC通道的转换值位于ADC的JDR寄存器 ![]() 总结- ?0 v) H: e2 M# F4 s9 n 以上流程就是使用STM32的ADC+DMA+timer实现自动定时采样模拟电压的配置使用流程,若读者发先任何疑问,妄指教。% Y0 K) `. Q) M* f! p4 r9 F 作者:woai32lala6 H: q j9 p; y* c1 A4 s |
Nucleo-F429ZI开发板体验LWIP功能
TouchGFX应用移植自定义屏幕
STM32固件库分享,超全系列整理
【经验分享】新建基于STM32F40x 固件库的MDK5 工程
年终中奖---F429板卡网络应用
【NUCLEO STM32F429ZI开发板】之点灯大师
OpenBLT移植到STM32F405开发板
串口通信波特率异常的解决办法
《RT-Thread设备驱动开发指南》书籍学习记录
STM32F407/STM32F417通过以太网实现在应用中编程 (IAP)