
STM32 F1系列 DAC的示例详解 9 r) w5 E9 ^& M$ n" Z1 [0 g# M" V 0 Z- ^3 k+ {; ^: S8 x* g前言 基于学习的目的,详细讲解关于Cube库中的DAC的功能。本次介绍DAC。2 \# F/ Q1 Z. g 7 m( }- h% a2 r' y/ |* H 一、示例详解 基于硬件平台:STM32F10C-EVAL,MCU的型号是STM32F107VCT6。/ e$ Y7 ~* y# P 软件则是其Cube库,路径:STM32Cube\Repository\STM32Cube_FW_F1_V1.3.0\Projects\STM3210C_EVAL\Examples\DAC\DAC_SignalsGeneration。 1、主程序 软件配置,运行程序可以发现,系统时钟设置为72MHz,定时器使用到的是TIM6; ![]() ![]() 根据时钟树的图谱及其程序, 该示例选择的是内部时钟源作为定时器的时钟源;TIM6的时钟源来自APB1的分频。 ![]() ![]() ![]() AHB 时钟 (HCLK)在RCC_CFGR寄存器中的分频系数HPRE的值为0,即SYSCLK not divided,即/1,所以HCLK就是72MHz; APB1的prescaler的系数是PPRE1:0x4,HCLK divided 2,即/2,APB1CLK为36MHz;由于APB1的prescaler系数部分频,即/4,所以倍频器起作用,即为上图中的TIMxCLK = 72Mhz。# m4 B+ u& @; x8 E: \$ d$ ~ 2、 定时器Tim6 ![]() ![]() 设置的是向上计数,周期是0x7FF(2047),从0开始计数到2047,所以该定时器的更新周期:(2047+1)/72 = 28us, ![]() 所以传输的6个数值:. U0 ?1 H* Y( Q4 }- B' p2 H ![]() 对于8位的DAC,程序中设定的是右对齐, ![]() 所以,对应的DOR分别为# L. A- V1 S9 k2 G' D- q 0x000(0), 0x330(816), 0x660(1632), 0x990(2448), 0xCC0(3264), 0xFF0(4080) ;, ^, w- n( w9 P- r. S& @ 而Vref = 3.3V, 所以:6 _9 N, N' L w; c9 } Vdac 分别等于:也是约在0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V之间; 3、阶梯波形 ![]() ![]() 对于阶梯波形比较简单: 就是上述的6个数值每个28us触发DMA传输一次到DOR的寄存器;5 T5 X' {' h* J4 M, z$ l 所以测得的实际波形(6个梯阶,电压分别0V; 0.66V; 1.32V; 1.98V; 2.64V; 3.3V; 周期28*6 = 168us);. p' ~0 k! X/ p5 F- C& k 验证的波形如下: ![]() 对于阶梯波形的产生,WAVE设置的是0x00;即:wave generation disable; ![]() 4、三角波 ![]() 产生三角波的主要代码如上,其实也就是下面的这一段代码: 9 C6 g' }5 I5 c- c0 p ![]() 其实也就是设置下面的寄存器的比特位; ![]() 最大的振幅是3.3V,即对应的是4095, 软件里面设置的2047,所以振幅是大约1.65V ![]() 该三角波的产生是由单片机的硬件产生的,软件控制的是:振幅和周期;1 `" M1 f( }/ X 振幅通过上述寄存器中的MAMP1来控制;: T/ X1 @* Y) q7 q 周期则是定时器Tim6的触发事件? 但是这里的周期并不是128us啊? 改变幅值也会改变三角波的周期的, 那么这幅值和周期以及定时器之间三者的关系如何呢?; k. Z' z% c9 Y% l7 e9 G 答案: ![]() ![]() 符合推论。' d. Q. v6 ~5 t% C 设置的波形控制模式:WAVE1 = 0x02,即产生三角波;8 f# Z6 D7 D4 h5 N, _0 Z: D ![]() 对于三角波的产生器,还有一段函数代码的作用是什么意思呢? ![]() ![]() 即其中的代码: p$ o" j1 b* q4 X, s ![]() 是什么作用呢? t# x- `5 |2 H. k' p7 o 产生的波形:" C% x* P: O2 o. L* o ![]() ![]() 在加了函数之后: Z/ M" F1 C( C2 w7 R& d; } ![]() ![]() 从波形上来看,当参数数值不为0时,波形更像三角波, 那这个参数影响的是什么呢?/ l1 C. a# A1 u1 p$ J1 s ![]() 参数的tmp的值,位于0x200004A4处,初始值为0,运行到:1 N; h* S( ~' s2 G9 ~8 R ![]() 后tmp的值为0x40007400,该值是解释得通的:DAC外设的基地址(0x40007400) ![]() 执行完语句之后:由于传递的参数是#define DAC_ALIGN_12B_R ((uint32_t)0x00000000) # B, `9 `# W4 o _' E) Y ![]() 得到的结果是(注意上图中虽然断点停在了DAC_DHR12R2_ALIGNMENT处,但是程序是DAC_CHANNEL_1,所以最终执行的还是下面的语句) ![]() 所以最终产生的效果就是: ![]() 地址为0x40007408的寄存器赋值,即下面寄存器赋值:& N; k" b( h8 ?4 d0 t ![]() 但是这寄存器的作用是什么呢?holding data? Holding data寄存器,可以简单的理解为: 设置影响DAC的直流分量(直流分量还是根据下面的公式计算出来的):9 d9 G* `0 {1 s ![]() 当传递的参数设置为0是,DACoutput即三角波的最低电平为0: 当传递的参数设置为2047,DACoutput即三角波的最低电平为1.65V( ]( t/ j% _( P. j- V( | ![]() 如果传递的参数设置为1024,DACoutput即三角波的最低电平为0.82V; ![]() 如果传递的参数设置为3000,DACoutput即三角波的最低电平为2.42V;, l- i2 \+ `3 ~! u ![]() ![]() 5、噪声产生器; g- u X. i* ^9 l 主要函数的代码如下:! j S. k C0 a G ![]() ![]() + `( G9 ?) Y- T5 q! I 由于一般的认为噪声是随机性的,所以可以认为只是修改幅值,对于其周期不可控 $ a8 E1 ^4 h+ a 3 Q1 M1 e6 e4 ~$ Q4 P I 文档下载地址: https://www.stmcu.org.cn/document/detail/index/id-217139- I* } P+ w& m5 L- A" R 7 ], m- M/ \7 R 实战经验汇总:' w7 K) Z& Z1 f P$ O0 F1 U% D https://www.stmcu.org.cn/module/forum/thread-576401-1-1.html4 b) |# s+ c5 n |
学习学习 |
![]() |
学习学习 |
![]() |
谢谢,学习一下! |
谢谢发帖,辛苦!辛苦! |