|
有人想使用STM32的TIMER及DMA,通过DAC实现指定的模拟输出,实现起来似乎不太顺畅。我这里借助于STM32F334Nucleo开发板,通过TIM6触发DMA传输,让DAC输出一路正弦波【半波】,做个简单示例,仅供参考。 1、基本原理:TIM6的更新事件周期性的触发DMA;DMA将预备好的内存数据写入到DAC的输出数据寄存器;以实现DAC通道1输出一路半波正弦波信号。 ! [: [( R5 k0 J2 @ T* s 2、初始配置:【使用STM32CubeMx图形化工具进行配置】9 b( L- X% K1 w2 W1 U# s 9 ]8 U+ J. ^, }. R2 i 2.1 TIM6的配置,做基本时基参数配置即可,同时开启基于TIM6更新事件的DMA传输配置【circula 模式】
$ E- i W+ S* y* g4 _( G 3、完成上述配置后,生成含有初始化代码的工程。 4、添加用户代码。 4.1 准备用于DAC输出的数据。. `) ~; R) T$ }3 n/ b2 h* x 7 h9 F3 z3 P6 p) L 我这里准备的数据基于如下正弦函数来做。准备好的数据放在数组 TodisplayData【】里,供DMA取用。, }+ L, d# ]- |: u $ z x7 g3 v; o/ t5 |/ Z; h
#define Step (200) * X% _1 l& P" p #define half_pai (3.141592/2) #define StepAngel (half_pai/Step) 4 e/ \$ C: H: i# t ^ + a" F' c$ T$ G3 X1 V- t& O #define Size_Array (Step* 2) ' S& c* T& Y5 B7 ? S0 `" J8 b' ~7 v; X uint16_t TodisplayData[Size_Array] = {0};7 r8 z- G0 f% v/ A for (i=0;i<Step;i++)& ]# _$ _1 a$ H% U) ^ o# M . z* A# H3 a0 T! d/ a {2 x8 K5 |- O" D) ?& ~ 0 \0 d6 Y) Y) f8 J3 w / c( H; b* p( R8 q TodisplayData=(uint16_t)(4000*sinf(StepAngel*i)); }7 \" X- H! o8 Z0 _$ v! i( J for (i=Step;i<Step*2;i++) / M' E$ U+ M5 |- c {; w; E4 d4 T4 V1 K2 m TodisplayData=(uint16_t)(4000*sinf(StepAngel*(Step*2-i))); r6 o% _" F7 a: ^' } } , P# O8 R8 w5 u4 M- u2 I% E ! ~' C7 V, q0 C# Z/ S! ^' Z 4.2使能TIM6的基于更新事件的DMA请求。- N5 I& c) k Z / U+ ?7 E/ W s" D3 P# T9 R __HAL_TIM_ENABLE_DMA(&htim6,TIM_DMA_UPDATE); 4.3使能TIM6的计数器计数。 $ b( k0 w) Y9 t% N7 x- C. [ __HAL_TIM_ENABLE(&htim6); 5 D Q# V: ~8 T( b7 e 4.4使能DAC通道1输出启动。$ K* z }9 {; W7 S- E$ a8 M ( k7 z7 k# _7 Y7 K3 a HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 ); 5 s( ]7 I. n+ V" d' f E1 H 4.5完成基于TIM6更新事件的DMA传输的相关配置,并开启该传输相关中断。) P- W6 f$ s, X, `. |4 N% z+ w HAL_DMA_Start_IT(&hdma_tim6_up,(uint32_t)TodisplayData, (uint32_t)&DAC1->DHR12R1 , Step*2-1);# l+ s/ ?: V4 x" ^1 ] 5、验证结果。 2 ?7 |8 C5 P! j 我们可以通过示波器看到DAC通道1输出周期性的波形。我这里是借助MDK IDE自带的逻辑分析仪看到的结果,可以参考。如下图:
. J+ i: X7 C, ?9 y( [ OK,到此也实现了预期的结果,其实整个过程也比较简单。3 G' a7 S+ H* a; W 最后,稍微提醒两点:' N3 z- P7 L( h M( ~% S3 U( [ 1 y. l# y4 F# |4 a* H2 m# ] 1、对于DAC输出数据寄存器多说几句,以12位为例。 + `3 v+ I5 |. y- y 我们要写入的DAC数据输出寄存器是DAC_DHR12Rx或DAC_DHR12Lx,即数据保持寄存器,具体使用哪个看你选择的是左对齐还是右对齐数据格式。而真正体现在输出端所对应的输出数据寄存器是DORx寄存器,该寄存器是只读的,即不能被写入的。DAC_DHR寄存器的内容被加载到DOR寄存器,可能是自动完成,也可能需依靠触发事件激发完成。具体跟我们的配置有关。我们读取DAC通道实际输出的数据时应以DORx寄存器为准。" [+ ~( V" i) ]) a4 s 2、关于DMA配置有个地方也提醒下。用cubeMx配置时选择的内存数据宽度【BYTE/HALF WORD/WORD]注意要跟你实际定义内存数组的数据类型一致。不要DMA配置时MEMORY宽度选择WORD,而在定义内存数组数据类型时使用HALF WORD(uint16)类型。这个地方很容易出错,还很隐蔽。特作提醒。 |
微信公众号
手机版