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

【经验分享】STM32 DAC程序示例

[复制链接]
STMCU小助手 发布时间:2022-3-28 10:12
01. DAC简介/ |, l( X! y7 H, s% x  z6 f
STM32F4的DAC模块(数字/模拟转换模块)是12位数字输入,电压输出型的DAC。DAC可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。DAC 可以通过引脚输入参考电压 Vref+(通 ADC 共用)以获得更精确的转换结果。' Y! Q0 Y9 i* d& o

$ i# _8 u: {) _8 V1 _STM32F4 的 DAC 模块主要特点有:8 Q1 a+ v# {' p+ Q& k; }9 w1 ^6 K; i, D
① 2 个 DAC 转换器:每个转换器对应 1 个输出通道
/ @* i0 v4 o3 s② 8 位或者 12 位单调输出
9 M) E) F7 t! ^1 d! \③ 12 位模式下数据左对齐或者右对齐  C$ z% J. w0 H7 m3 O8 i
④ 同步更新功能' c: T; j) G) d/ A/ z; N
⑤ 噪声波形生成
0 Q3 u  Y9 r. F' l! Z* F⑥ 三角波形生成* r. G9 ^5 R  c3 S
⑦ 双 DAC 通道同时或者分别转换
. G. x/ t  y  ~' Z+ ]⑧ 每个通道都有 DMA 功能
4 }5 r( K# K8 O  r% z
. Q' g8 p$ |4 N7 B  F+ `, U02. 硬件模块
+ w* c3 D5 b/ [: F' h) P1 P2 ]# x用到的硬件资源有:
! G2 M$ k# M& J, P( s1) 指示灯 DS0* d9 V, D; d. C$ S0 \: ^
2) KEY_UP 和 KEY1 按键- c' D: b% @' S$ B
3) 串口+ p: @1 j- I3 H- S
4) TFTLCD 模块, g; N; O& \6 X8 c& o& X
5) ADC1 s3 Y( A( j) `/ b0 n. J# L
6) DAC
1 ^" @" a# i5 z0 R1 u' ], \2 k8 X) A" q( U& c' f
03. 程序设计
) U) u. o8 r/ O" G! y2 udac.h文件7 j/ f1 A5 M) j+ T  p7 {: T
' K# v8 }% `( I: H7 R# A; h/ M
  1. #ifndef __DAC_H
    ( o! K- K* H" _' M. ~4 z
  2. #define __DAC_H         
    6 S( g* n# |* ^. e& w* s
  3. #include "sys.h"                                         + p! ~$ V+ S: w2 n$ b* l8 v

  4. + k" p: w0 k/ T$ G+ c
  5. void Dac1_Init(void);                //DAC通道1初始化                  $ m9 d% U* O' k7 o: |" a" V0 e
  6. void Dac1_Set_Vol(u16 vol);        //设置通道1输出电压$ ?: z% E( M1 e8 @
  7. #endif
复制代码
- l3 {2 E! F) ^
dac.c文件& ~: B7 M  U' D$ a  s4 `% C  N' j

, {. s! y0 ]% |8 v! p% ~
  1. #include "dac.h"9 D# }2 J: I, m2 A4 o5 t
  2. ( g4 o  [" y% ~) }/ ^! ]
  3. //DAC通道1输出初始化
    8 b+ P+ T4 E% E# T& O9 m
  4. void Dac1_Init(void)
      d' }% l( V; w+ d$ d4 r
  5. {  / H) ?+ ^# u3 H+ {
  6.   GPIO_InitTypeDef  GPIO_InitStructure;
    . [& \3 `$ {$ n2 q) B7 P' [5 D
  7.         DAC_InitTypeDef DAC_InitType;# F5 b! v0 Y' S1 ^
  8.         7 P0 p1 _/ k, Q& L% Q. v
  9.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
    : _! f. ~0 P! ?6 [7 M
  10.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
      v5 b. [7 M9 B' ?' F/ {2 e

  11. & L# A8 O& R8 ^9 z/ t; a3 x  q
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;2 C" Q5 v; M( w8 J0 }
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入$ C5 e: i/ N6 E5 `# b7 p) v
  14.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
    ' ?% w3 j8 S/ n, s; R+ @
  15.     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
    $ l8 N: _. N2 Y, R6 s; Q

  16. , X8 I/ Q" i5 z& {. s0 N
  17.         DAC_InitType.DAC_Trigger=DAC_Trigger_None;        //不使用触发功能 TEN1=0% `. |& x" i( {) s" W' }3 ^1 g9 s
  18.         DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
    8 m! P# `1 R9 i; R& u' J
  19.         DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置- ?% }, j, b- V6 A& v
  20.         DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;        //DAC1输出缓存关闭 BOFF1=1
    2 |' V- e; T! d! R
  21.   DAC_Init(DAC_Channel_1,&DAC_InitType);         //初始化DAC通道1
    & z% y* I  j; ^8 S
  22. ' o$ j9 `0 L$ r& C, ?7 @
  23.         DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC通道1
    : r$ r& A4 M$ {4 E$ o7 t
  24. 9 J! D* ]7 Y. ]1 m
  25.   DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值! E9 l! Z1 w9 T6 j
  26. }7 b8 P0 D6 C( E' H3 m
  27. //设置通道1输出电压. v9 Q3 |1 E8 J! I" l) N
  28. //vol:0~3300,代表0~3.3V
    - j7 E3 E3 B/ z
  29. void Dac1_Set_Vol(u16 vol): T6 N3 d1 W. h4 s
  30. {* N$ F; {* f0 r; O& F. `
  31.         double temp=vol;
    0 m' a* h- M' ^
  32.         temp/=1000;
    # I3 Z4 O7 U  \8 i/ p
  33.         temp=temp*4096/3.3;
    ( E2 b$ Q- Z: c. h: ?
  34.         DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
    , c: g, w: ^% T! ?+ t2 ~
  35. }
    5 {) F! B/ I4 t. i
复制代码

, E) r" f* j4 u! N' Dmain.c文件
; e9 S6 t3 O& O- X; p
! @4 U. ]* L- X) k, P
  1. int main(void)
      z& D' V5 ]  z5 p. t
  2. {
    5 Z) E4 \8 w2 O
  3.         u16 adcx;
    ; q9 M% r6 z: D1 D
  4.         float temp;
    9 z' y  ~4 B- e1 U
  5.          u8 t=0;         * Y) s8 ~  [0 z& e: C; w7 F
  6.         u16 dacval=0;6 F" C/ U" C: a
  7.         u8 key;        
    3 L" |' ~# ?9 K9 Y: l, ]% m6 u
  8.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2; X& F$ j: i5 r, A, z$ t
  9.         delay_init(168);      //初始化延时函数
      f" U% s$ V$ s' U" L
  10.         uart_init(115200);                //初始化串口波特率为115200; n) O% B) w3 t0 Z
  11.         
    ( J+ T0 `3 |/ I1 d% O
  12.         LED_Init();                                        //初始化LED / r- c( O- @8 f1 p
  13.          LCD_Init();                                        //LCD初始化
    , t1 R* i+ y& [& w
  14.         Adc_Init();                                 //adc初始化+ h# U6 C3 e7 ~0 c
  15.         KEY_Init();                                 //按键初始化
    6 G" J5 u; N- T) U
  16.         Dac1_Init();                                 //DAC通道1初始化        
    / C: i3 p9 |6 S7 w$ F
  17.         POINT_COLOR=RED;
      }1 n7 M! j( I% N
  18.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
    # K; q' q2 X" ?& Q2 {# M; r
  19.         LCD_ShowString(30,70,200,16,16,"DAC TEST");        ! }! h& j( S' B
  20.         LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
    ( [  M+ I2 `9 ^1 i# I" q/ C
  21.         LCD_ShowString(30,110,200,16,16,"2014/5/6");         
    4 Q, O$ a: M, Y  H4 {( `# ]. o; y% y1 Q1 d
  22.         LCD_ShowString(30,130,200,16,16,"WK_UP:+  KEY1:-");           v1 {) g5 d! z8 M( M8 B: n. Q- @# K
  23.         POINT_COLOR=BLUE;//设置字体为蓝色               
    ) D* M- H6 L( Q
  24.         LCD_ShowString(30,150,200,16,16,"DAC VAL:");              
    : E+ p) O) Y: G% b* J
  25.         LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V");              ; \+ Q) f; c7 W0 ~  k+ R6 f
  26.         LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V");3 s1 `3 Q" z, d, r% [
  27.          % J6 ~0 m' l. G( ~
  28.         DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0        $ t; C! Z! J' {8 N2 U8 t5 I
  29.         while(1)
    * B3 q  j' R8 C& @
  30.         {
    , D9 f& M% t% P, E% c7 g  F
  31.                 t++;
    / y, `! q+ S9 k$ p2 d- V' T
  32.                 key=KEY_Scan(0);                          
    ! b4 c! S/ v9 }) n$ _
  33.                 if(key==WKUP_PRES)
    0 \0 @6 r* ]) y3 N, o  }
  34.                 {                 
    $ r+ I4 t8 \* R/ S& F8 L% P7 S+ k
  35.                         if(dacval<4000)dacval+=200;
    - K" e7 c3 G3 [0 g; x% ^% Z
  36.                         DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值: [! I& m2 I! q$ q, w
  37.                 }else if(key==2)        
    8 O7 x' }. f5 Z1 ]# c
  38.                 {5 j# W0 C0 e6 r2 U8 j
  39.                         if(dacval>200)dacval-=200;
    6 J! x) I0 P3 ~) [7 X
  40.                         else dacval=0;
    2 J7 u) q( ]0 l; a
  41.                         DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
    7 t0 z6 X& ]. V1 Q! u
  42.                 }         7 T5 Y% k( Y& u- v
  43.                 if(t==10||key==KEY1_PRES||key==WKUP_PRES)         //WKUP/KEY1按下了,或者定时时间到了2 k5 r2 w! P/ O% G
  44.                 {         
    # g' b; u2 o, v: l
  45.                          adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值  M! S: l, H+ L2 M$ x
  46.                         LCD_ShowxNum(94,150,adcx,4,16,0);                //显示DAC寄存器值# J6 t0 [  o2 I! X6 t4 V5 l
  47.                         temp=(float)adcx*(3.3/4096);                                 //得到DAC电压值
    3 \  }& q% W9 l' o
  48.                         adcx=temp;' L0 m( u$ O; Z; o
  49.                          LCD_ShowxNum(94,170,temp,1,16,0);                //显示电压值整数部分
    2 E: S* V3 r- {
  50.                          temp-=adcx;
    - [+ F# e3 j+ z0 j9 w# M+ f- i
  51.                         temp*=1000;, m* q# K4 \. N, Q1 ~7 b) N+ F
  52.                         LCD_ShowxNum(110,170,temp,3,16,0X80);            //显示电压值的小数部分
    . t$ n  {5 `  y, U
  53.                          adcx=Get_Adc_Average(ADC_Channel_5,10);                //得到ADC转换值         
    - r5 U7 u1 U) a: _# V
  54.                         temp=(float)adcx*(3.3/4096);                                //得到ADC电压值
    $ f2 u* u5 x: V7 L" ?7 C
  55.                         adcx=temp;
    8 S' Y' l! f( ?
  56.                          LCD_ShowxNum(94,190,temp,1,16,0);               //显示电压值整数部分' k- Z  z4 v# E+ {6 ~2 p
  57.                          temp-=adcx;; y2 a3 U! b5 B8 ^3 Y1 Z7 a& j
  58.                         temp*=1000;$ |$ |9 E5 {, v; D
  59.                         LCD_ShowxNum(110,190,temp,3,16,0X80);           //显示电压值的小数部分& K0 o9 p& }8 I4 L# F- r) c
  60.                         LED0=!LED0;           
    & M/ H* i7 S8 S9 y  s. P
  61.                         t=0;8 b. V( q8 M3 U* C6 w5 }
  62.                 }            
    ! R+ Z1 ]1 T! ]" N0 o# w
  63.                 delay_ms(10);         
    . k& e9 v4 B2 {
  64.         }        
    2 \& ^8 P% v1 p2 _- s; c& G+ I
  65. }* x5 \9 `" M- H' ^8 H7 J" H
复制代码

0 n# H: p" C! M( V04. 结果验证. p% d3 O! G: {: M4 b+ G6 _
同时伴随 DS0 的不停闪烁,提示程序在运行。此时,我们通过按 KEY_UP 按键,可以看到输出电压增大,按 KEY1 则变小。" d- r. R; f6 g# d) h# v

6 g8 S. _7 J0 j2 a) @
0 V- P. B0 E! y: j& ?0 ]+ F7 J% E( x% {$ e( v: f
收藏 评论0 发布时间:2022-3-28 10:12

举报

0个回答

所属标签

相似分享

官网相关资源

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