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

STM32 的 DAC 模块配置与使用

[复制链接]
STMCU-管管 发布时间:2021-5-20 16:57
STM32 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的DAC。+ q' x. v$ m' S+ p* r
DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。
0 A$ }* \" d# b( @: u* T# F0 hDAC工作在 12 位模式时,数据可以设置成左对齐或右对齐。
# i; w  X7 \  |; ^$ e1 }2 _3 P& hDAC 模块有 2 个输出通道,每个通道都有单独的转换器。8 g; E7 i5 ^8 u
在双DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。
8 ^  F. ]( t+ i4 K3 RDAC 可以通过引脚输入参考电压 VREF+以获得更精确的转换结果。' Y9 Z& c, C) p. m& K3 Y) }

0 x  m& G1 f2 g1 }/ x$ M: M! C+ a
! Z" L7 a8 x# Z9 X
STM32 的 DAC 模块主要特点有:
% j# f( x7 Z; M* d. V  s
0 a3 M- c$ u, b' `

- m1 r) W2 p$ f( @①  2 个 DAC 转换器:每个转换器对应 1 个输出通道 ! _- M8 x- u8 \- B$ G; D* z. Z  a
②  8 位或者 12 位单调输出 ; x7 m# M& L2 \) c! i
③  12 位模式下数据左对齐或者右对齐 , h1 z+ g' O. b" t3 A. {, I8 T( S
④  同步更新功能
+ K+ m1 g+ k; C, W- B, `⑤  噪声波形生成 ! E6 F+ s" D+ \& R
⑥  三角波形生成 % u: C5 U8 b, G6 e3 a8 Y
⑦  双 DAC 通道同时或者分别转换
3 {, G& J/ {' n& ?/ t% a+ `⑧  每个通道都有 DMA 功能 % k6 g; y+ l; Y( u
使用库函数的方法来设置 DAC 模块的通道 1 来输出模拟电压,其详细设置步骤如下:
" H: ]$ S7 j9 R# P& Y: }: h6 y: H* n3 S" k. g6 f1 a

' M; a9 F5 t  S/ t+ `& U( }' J  t7 Z/ g1 Y1)开启 PA 口时钟,设置 PA4 为模拟输入。
- S. p! p9 b2 M& {$ ?. Z: A5 A+ f. [. j- U6 }

% G  R+ I/ @+ `- a/ `& G' Y6 WSTM32F103ZET6 的 DAC 通道 1 在 PA4 上,所以,我们先要使能 PORTA 的时钟,然后设置 PA4 为模拟输入。DAC 本身是输出,但是为什么端口要设置为模拟输入模式呢?因为一但使能 DACx 通道之后,相应的 GPIO 引脚(PA4 或者 PA5)会自动与 DAC 的模拟输出相连,设置为输入,是为了避免额外的干扰。
# t, l) Z; k( c8 W% O& ?! Y$ ~. W1 J4 S  t

4 v. T( `# t. F$ d2 G( K使能 GPIOA 时钟:- m; m4 g' d, u( D( g5 Q3 y
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
    0 u! c7 d* w4 c5 r# \/ X) S
  2. //使能 PORTA 时钟
复制代码
设置 PA1 为模拟输入只需要设置初始化参数即可:: I$ Q5 M/ D. S6 t3 X
  1. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
      j1 ^7 _, R( z* G
  2. //模拟输入
复制代码
2)使能 DAC1 时钟。
5 T; j& [% c# b) J) _8 U+ i同其他外设一样,要想使用,必须先开启相应的时钟。STM32 的 DAC 模块时钟是由 APB1提供的,所以我们调用函数 RCC_APB1PeriphClockCmd()设置 DAC 模块的时钟使能。
# E! t; Y! T' @" n+ n# I/ l
  1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
    + S* v) U: z8 p8 H0 i- O
  2. //使能 DAC 通道时钟
复制代码
3)初始化 DAC,设置 DAC 的工作模式。1 A. O4 e5 X- m9 z% R& L- I# ]
该部分设置全部通过 DAC_CR 设置实现,包括:DAC 通道 1 使能、DAC 通道 1 输出缓存关闭、不使用触发、不使用波形发生器等设置。这里 DMA  初始化是通过函数 DAC_Init 完成的:9 g. a" Z2 u8 \* L9 D# l% e
4 N4 V3 N3 V0 R1 j
( ?# w; j) y/ t4 K
  1. void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
复制代码
参数设置结构体类型 DAC_InitTypeDef 的定义:/ G! d4 r0 V% c( g) ^8 h" `$ A2 r/ s! c
  1. typedef struct
    9 V/ s( S% P; d6 D5 E( I  p
  2. {0 O0 L: N( i5 J
  3. uint32_t DAC_Trigger;
    1 K- `6 w- l1 D$ h4 ?5 u, W1 g
  4. //设置是否使用触发功能
    . U& @, L. b3 O) H0 U' D7 y
  5. + B' m9 {2 w, f; s
  6. uint32_t DAC_WaveGeneration; ( ?$ ^, z8 J# F8 m" o
  7. //设置是否使用波形发生0 M" t0 J9 V5 O- Z8 i
  8. + u. X( u0 R6 H6 ^" _
  9. uint32_t DAC_LFSRUnmask_TriangleAmplitude;
    0 b2 Y5 K  B9 w6 k
  10. //设置屏蔽/幅值选择器,这个变量只在使用波形发生器的时候才有用. ?' \" a, j& a& }! |# Y7 I

  11. 2 ]" H$ Y) K2 C3 M! k$ `, x
  12. uint32_t DAC_OutputBuffer;  ! C  s8 r8 V; l$ o" |5 J2 I
  13. //设置输出缓存控制位
      ]5 g: e# P- B3 o# ^2 n
  14. }
    & _0 d1 D/ B( h1 o5 C+ e+ r' S
  15. DAC_InitTypeDef;
复制代码
实例代码:/ D/ j9 Z& l' l+ }# n: }2 ^

  1. 3 X) W" a; X5 \/ ~5 S: D* Y
  2. DAC_InitTypeDef DAC_InitType;, V0 x, t% f% a8 b* O+ P8 R
  3. DAC_InitType.DAC_Trigger = DAC_Trigger_None;    b1 A1 ?5 B; `7 a
  4. //不使用触发功能  TEN1=0
    ' n7 F$ i" F- N
  5.   C0 `& {- x, H* {/ x/ |
  6. DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;
    ; y5 ]) h3 E) k
  7. //不使用波形发生
    / N8 h$ y5 }/ `& c5 t& m
  8. ) t  z, w% [6 Y* B, N& Z* H- B6 h
  9. DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
    6 H- @3 _. E! e' i* y' w
  10. DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable ;  
    6 K) O: @- E/ M  y7 F; Y' V1 q
  11. //DAC1 输出缓存关闭 " x9 t+ y. l" L! u4 z% a$ t# g- o

  12. . l5 ?2 V5 Y" q: K8 I9 d1 @
  13. DAC_Init(DAC_Channel_1,&DAC_InitType);    8 Z) _% E1 G& I2 c
  14. //初始化 DAC 通道 1
复制代码
4)使能 DAC 转换通道
: H: S& K8 b2 C, |- y4 _初始化 DAC 之后,理所当然要使能 DAC 转换通道,库函数方法是:
; s) k: a+ T3 {! |/ f
1 q# t7 ~9 N4 N9 ~: v
  1. DAC_Cmd(DAC_Channel_1, ENABLE);$ s) Y9 U0 C7 p) b, S' Z( H2 ~3 X* L
  2. //使能 DAC1
复制代码
5)设置 DAC 的输出值。! V0 T( c2 V# h! I% z8 X* E
通过前面 4 个步骤的设置,DAC 就可以开始工作了,我们使用 12 位右对齐数据格式,所以我们通过设置 DHR12R1,就可以在 DAC 输出引脚(PA4)得到不同的电压值了。库函数的函数是:  E) D) Z" V; r0 _0 h2 O" K  s
- C. p9 X  X9 W0 Y  I: T( {
  1. DAC_SetChannel1Data(DAC_Align_12b_R, 0);
复制代码
第一个参数设置对齐方式,可以为 12 位右对齐 DAC_Align_12b_R,12 位左对齐DAC_Align_12b_L 以及 8 位右对齐 DAC_Align_8b_R 方式。第二个参数就是 DAC 的输入值了,这个很好理解,初始化设置为 0。1 K6 k) Q$ }  f% ~/ x7 L
这里,还可以读出 DAC 的数值,函数是:
# m' g) B. k2 p, j% u: B& r! I
7 ]. ^. R) k& e+ q9 [
  1. DAC_GetDataOutputValue(DAC_Channel_1);% O( N2 |1 ?* e+ ?- u& w1 S" u# X
复制代码
以下为代码:' O0 n1 a: D$ E7 [  _3 y) X
  1. 9 q3 \5 ]! O9 S* P7 S* W# W; r, ~8 q
  2. //DAC通道1输出初始化/ B- j0 \* P& {( k* y
  3. void Dac1_Init(void)( I* X0 L' c+ V) B
  4. {
    & n$ h0 i  x# N3 m8 @2 w
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    ( S6 e) ]( l; K0 g
  6.     DAC_InitTypeDef DAC_InitType;6 Z; t! u& D$ ?* C, H  ]
  7.    
    2 H' e* F& ?4 O: T
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );, V+ O$ U% c; R' b) C
  9.     //使能PORTA通道时钟  A6 ^4 M  L/ E* F/ h; J+ c
  10.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
    $ s; ~$ P6 |+ L3 j
  11.     //使能DAC通道时钟2 `, \8 j6 p4 a, B" h
  12.     4 e" h! _+ P5 T& Z& G1 @
  13.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    . \. [% K5 W8 @8 U* N, ]- [4 X
  14.     // 端口配置
    : T9 t7 \. y1 K* O  w8 }5 Q1 t& d
  15.      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;: n/ r; J/ o  \! {. ~; u& Y, p& C# M
  16.      //模拟输入
    3 t: ^5 g) E+ e5 q( _
  17.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;. |  l- o# X' p2 C# A& V
  18.      GPIO_Init(GPIOA, &GPIO_InitStructure);
    & D: m0 M9 m+ y3 Y5 \& P
  19.     GPIO_SetBits(GPIOA,GPIO_Pin_4);- W+ {: ~! z, z, a/ P- j; i
  20.     //PA.4 输出高
    - F# N; G% @. n
  21.    
    & y7 j2 O4 p1 @6 e( v- b( ~; R5 w
  22.     DAC_InitType.DAC_Trigger=DAC_Trigger_None;: i6 c* v* [4 a. D5 N
  23.     //不使用触发功能 TEN1=0
    0 w# ]8 Q4 ~" Y; @& L% Q
  24.     DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
    8 v$ @7 F" }$ ^9 ]/ N% `
  25.     //不使用波形发生
    8 ]" n. l$ m+ L. l# V
  26.     DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
    0 F3 W+ Z& K2 }0 H9 b( F8 S0 s# R
  27.     //屏蔽、幅值设置" R8 O4 x1 |' Q$ r. L
  28.     DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;
    ' {2 v9 M2 Y+ o! u/ M9 I0 Z
  29.     //DAC1输出缓存关闭 BOFF1=1, a% w+ G# ?# j8 y
  30.     DAC_Init(DAC_Channel_1,&DAC_InitType);
    7 O& ~( s4 E% G- w6 i; d, S
  31.     //初始化DAC通道18 _  {* f. t5 ?. k! M2 h( y( @, t1 h
  32.     7 s' J8 ^) L. u7 v7 c9 M: f- x
  33.     DAC_Cmd(DAC_Channel_1, ENABLE); 3 S$ i2 u) w7 M6 p1 G9 M  I) U
  34.     //使能DAC1& T! i* \/ \8 Q6 d# e
  35.     DAC_SetChannel1Data(DAC_Align_12b_R, 0);1 h& J8 O" N' \, m' y% |; ?" a$ q
  36.     //12位右对齐数据格式设置DAC值; D) W9 O  R% [: Z# l5 ]$ s
  37. }& ~( _# \; A7 J/ ?( `4 T
  38. //设置通道1输出电压# `( R2 S+ @) b8 A5 N* F# b
  39. //vol:0~3300,代表0~3.3V
    * c' I0 S! H' [9 c; p
  40. void Dac1_Set_Vol(u16 vol)1 S7 X, K7 n; x& l$ u
  41. {" [, r# h- e/ V8 ~6 }
  42.     float temp=vol;5 n( w/ x( e, j! l) o
  43.     temp/=1000;" W+ O7 n9 k0 d2 Q# ?6 [
  44.     temp=temp*4096/3.3;
    2 Y/ W- }1 }- L9 Z  }1 J& q1 e
  45.     DAC_SetChannel1Data(DAC_Align_12b_R,temp);" M! W) F8 }9 f5 O
  46.     //12位右对齐数据格式设置DAC值
    * Z; K! y8 j( Z' U* d' V5 C' w% I
  47. }
复制代码
在使用的过程中,只需要调用 DAC_SetChannel1Data(DAC_Align_12b_R,temp);该函数就可以随意设定需要输出的电压值。
$ m0 J, `+ H# b1 V! g
赞 收藏 评论0 发布时间:2021-5-20 16:57

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版