你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F103DAC功能实现

[复制链接]
STMCU小助手 发布时间:2022-3-20 13:25
  所谓的DAC功能也就是将数字信号转换为模拟信号,一般情况下使用比较多的就是ADC功能,也就是将模拟信号转换为数字信号,多用于读取传感器的值。但是有时候需要控制某些传感器,需要用模拟信号控制,这就需要将数字信号转换为模拟信号了。; m! A, g9 ?% g' i

- @0 T. o8 D0 N1 S6 K! ^8 u  数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压V REF+ 以获得更精确的转换结果。
! E, N# u1 q/ S5 t
: i- `# B  ~' v1 dDAC 主要特征
* U% x  H/ q! H1 ~  }% U  _
2个DAC转换器:每个转换器对应1个输出通道7 X% [, X, e9 a8 y) E2 B/ F
8位或者12位单调输出, m0 \8 L& ~# M$ _" @/ w" _1 h5 a
12位模式下数据左对齐或者右对齐  j! N" F# P8 |9 q4 N
同步更新功能* q" R& N* g; z/ O. Q* _
噪声波形生成8 Q: {4 o' V  O+ O. n. C% T
三角波形生成1 o; b/ E3 Q3 B9 I% k5 ]
双DAC通道同时或者分别转换. G) s9 m- ^  u) |0 Q  a
每个通道都有DMA功能2 G* h8 i- n1 z* l1 x% h5 [; e
外部触发转换+ b; m# I) D7 D, \. I% m4 o% V7 G
输入参考电压V REF+
) h! i, E2 o# C) U8 h下面就通过代码来实现模拟信号输出。
# _6 P; ]) h: z4 v" i  Q  |4 c4 p$ k# D0 x8 i! _
  1. #include "dac.h"" s+ r% k1 q5 ^2 N, t( u; ?) Y; q

  2. 0 ^% m! Z4 [3 _/ p( P
  3. void DAC1_Init(void)
    ) z* |9 [: v9 o" t% Z3 D
  4. {
    % H! i1 t" E# n6 o+ {
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    " g- ~% D, ~' P3 ]% n7 r
  6.     DAC_InitTypeDef DAC_InitStructure;
    * j3 R2 [" C/ r' ?

  7. 1 b2 Y. U3 }4 I+ g+ \# E
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);. i& }0 U3 J1 l  C1 r" [
  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC , ENABLE);
    % O1 H. `1 G$ B4 b

  10. ) d/ ^* R6 J- N* S, w
  11.     //PA4设置为为模拟输入,使能DAC通道后,PA4会与DAC模拟输出相连,设置为输入为了避免了干扰
    6 h1 x% E) q0 ^- R/ z3 Q: ?# p
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    : r# k% t5 D" C$ J+ i6 l
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                                                                //设置为模拟输入. s" N- N2 d1 N) j9 m+ k* B
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;, ^. h' |- O4 N
  15.     GPIO_Init(GPIOA, &GPIO_InitStructure);
    # t: f+ Y3 h% i* p, \5 u) o
  16. 6 P! @5 q( C6 {* p  c) z/ a
  17.     DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;                                                         //不使用触发功能 TEN1=0; S+ ]0 [  p5 C& d# D% o& p) h
  18.     DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;                         //不使用波形发生
    % v9 n" z3 g2 ?3 ^, C& c, d% P
  19.     DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;         //屏蔽、幅值设置% F6 p7 `8 V8 e1 [
  20.     DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;                                //DAC1输出缓存关闭
    + M$ g+ G, a9 Q% A
  21.     DAC_Init(DAC_Channel_1, &DAC_InitStructure);                                                                 //初始化DAC通道1
    9 i# O% u! ~7 b9 }' `

  22. # X8 {+ W& _' `
  23.     DAC_Cmd(DAC_Channel_1, ENABLE);                                                                                         //使能DAC1/ v+ i6 ]- P- i
  24.     DAC_SetChannel1Data(DAC_Align_12b_R, 0);                                                                         //12位右对齐数据格式设置DAC值
    3 c% T  c0 S9 e) b$ Y
  25.         . B9 N9 Z5 r3 Y; C" B
  26. }% W: \9 S+ {$ m$ x
  27. //设置通道1输出电压
    ' m5 p9 c* s$ t+ u
  28. //vol:0--3300,代表0-3.3V
    2 S: y$ y' w( \
  29. void DAC1_Set_Vol(u16 vol). A0 E* p4 S# G& v0 Q% ?
  30. {
    8 @1 _) F4 F/ y0 N  ^
  31.     float temp = vol;. ?* \1 {0 ]: }9 a3 e+ [  u7 a" w  i
  32.     temp /= 1000;
    " i3 _  Y: H, O/ R; G9 J( m3 ~/ q
  33.     temp = temp * 4096 / 3.3;
    7 N! O9 V) d2 t5 h+ b. I* ?% D% t
  34. * ~3 z# i& v6 h; M4 [0 H
  35.     DAC_SetChannel1Data(DAC_Align_12b_R, temp);- ^7 @5 f3 k3 f4 O
  36. }
复制代码

8 o. X" c; r, o+ X$ @  x0 R在初始化的时候,要注意一个问题,STM32F103单片机的DAC输出通道有两个。  Q& i) r$ Q2 |, e5 O; c

" Y/ b7 ?) x* m S05HG]2@QIXUY6W@SR$IY_O.png 8 O) u' {  U# q

, \/ w4 l4 {  |" ^. PPA4和PA5,但是在初始化引脚的时候,要将PA4和PA5初始化为模拟输入功能。这个在官方文档上也有说明。; O: [2 n- |1 f6 T$ D

, m9 u% x* e, B/ P! x %NEMPB$XD{FGUJRE`}06FPW.png " |! ?0 K7 f- C8 e" B) p5 l/ Q
+ f1 w* p' v$ G; h1 h; l/ N7 Z
  内部自动就会将PA4和PA5与模拟输出引脚连接起来。所以在初始化的时候,虽然用的是输出功能,但是还是要将引脚设置为输入。
) v5 S* J/ \' ]6 _% p6 s
, Y" ^' n3 h! P- p  初始化引脚之后,接下来初始化DAC功能,在这里不使用触发功能,也不使用波形发生功能。直接通过软件来控制
# e0 m7 z: P; |( @! i) k7 ?% N# x! D4 f/ ~5 s7 X
  接下里通过一个函数将要输出的电压值换算为寄存器的设置值。DAC的转换为12位,所以最大值就是2^12,也就是4096,而stm32单片机的供电电压值3.3V,所以将要设置的电压值除以3.3,然后乘以4096就是DAC寄存器需要设置的值。/ g% U7 ^$ f, }$ x8 i1 Z+ _

3 s3 @- X3 _  [* i  j5 I6 _  如果要输出模拟电压值时,只需要在主函数中调用DAC1_Set_Vol()函数,并将要设置的电压值传递给这个函数就行了。
" M( |9 {# t, w, D* ?( c+ I6 c! z  L, Y8 S9 ~9 X: l
  1. int main(void)+ D+ S5 ]) h( h' ~/ d: ?
  2. {
    8 h1 e8 C8 ^% L- }1 ]2 d
  3.     u16 adcx;
    5 m  }, T; ?" c2 U4 f
  4.     float temp;
    7 ~+ |1 ^3 i6 h3 v1 W
  5.     u8 t = 0;
    9 ]2 g# n" ?7 i6 j( }7 Y& [, o. ^
  6.     u16 dacval = 0;
    & N" E* B9 J8 G$ O# r. h
  7.     u8 key;" _$ a) Z  x- I; E: a  L

  8. 7 f) A- o6 y0 p' a/ o* T
  9.     delay_init();
    7 p9 d9 b9 t+ b- |9 R1 W
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    $ t3 `% O5 V2 ~: k
  11.     uart_init(115200);& n6 j0 \' q0 U  o- ^( F8 b, u
  12.     LED_Init();
    0 Z6 n1 \/ K+ f& m1 E, M
  13.     DAC1_Init();   
    * g7 D: V  @( N1 B3 w3 ~
  14.     while(1)( {& l6 |1 x0 C2 y( Z2 G; Z
  15.     {+ T' M  I- k8 f! }# v% r- n. R
  16.         LED0 = !LED0;
    & c, x6 Y3 j  y- X* x! w/ k, S. n% Q
  17.         DAC1_Set_Vol(1000);" q$ s- F! Y3 L8 R1 T
  18.         delay_ms(100);' [. |# z0 H' i! |8 M7 i1 m, Q
  19.     }4 u2 ?0 w6 t1 D7 J  k
  20. }
复制代码
  Z! ^9 j9 e! L' {2 C2 [' V+ [* R0 X5 K
在主函数中设置DAC输出的电压值为1000,也就是1V。这时通过万用表就可以在stm32单片机的PA4引脚量到1V的电压值了。1 {0 g0 w1 F* F

2 g0 W% o4 N. M; K2 j: O  ^8 |
2 X3 W7 e: A. i/ h3 U6 e- V/ V/ H  R- J2 J& E
收藏 评论0 发布时间:2022-3-20 13:25

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版