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

【经验分享】STM32F103DAC功能实现

[复制链接]
STMCU小助手 发布时间:2022-3-20 13:25
  所谓的DAC功能也就是将数字信号转换为模拟信号,一般情况下使用比较多的就是ADC功能,也就是将模拟信号转换为数字信号,多用于读取传感器的值。但是有时候需要控制某些传感器,需要用模拟信号控制,这就需要将数字信号转换为模拟信号了。
' c  L9 O$ c! _4 `2 k
9 y3 O; F5 Q5 a) X: e7 y  数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压V REF+ 以获得更精确的转换结果。& x. `+ j+ `' [! ?  ]) q4 b
( u/ i" f7 F5 L/ T( H) c: _
DAC 主要特征

) d) p1 |+ Q( {& `# Z2个DAC转换器:每个转换器对应1个输出通道  S4 {$ z; _* _4 Z; u5 O
8位或者12位单调输出
4 F5 z; k- S) y! J, ?12位模式下数据左对齐或者右对齐5 R9 d9 D0 @# W" b, q9 @; ?
同步更新功能
6 M5 G" T7 W- S/ m$ j噪声波形生成
8 d5 ^0 t" q9 I/ ]0 P0 V三角波形生成/ K% j) s- S) W+ l5 o  l# k7 `$ j- w
双DAC通道同时或者分别转换' U. Z9 D7 R8 \- M* p  [+ M
每个通道都有DMA功能4 @' f6 f) V  l) y! {. e8 P5 m! A$ l) N
外部触发转换
1 K; ]/ U" [6 W8 p& W: ^/ ]输入参考电压V REF+% P7 y( J: g* Q& B# _
下面就通过代码来实现模拟信号输出。$ N+ H, w4 V* V- g( R9 Z% Q
! k: ]' L" |, ~5 d" B
  1. #include "dac.h"/ Y- l. W  K  y% H
  2. 8 x+ c3 I9 i& H4 O+ y% L# A
  3. void DAC1_Init(void)
    0 b8 c2 Q7 T  n' S
  4. {. j. v6 o/ P( f+ p
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    2 o( e; |3 P! h6 U8 N1 a
  6.     DAC_InitTypeDef DAC_InitStructure;* {) V4 P/ s/ d- l# B, E8 ]
  7. : c* @0 }& M0 d( Z  L
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);2 \  S* d4 Y" M# a3 L
  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC , ENABLE);$ ^2 j- [/ d+ s

  10. * S& V% X: V; @! t; H5 Y. W* ]7 N
  11.     //PA4设置为为模拟输入,使能DAC通道后,PA4会与DAC模拟输出相连,设置为输入为了避免了干扰
    ; G  a5 O" X0 t8 f  |9 [
  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    ' m* y) o4 _/ M* |5 Y9 @* u
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                                                                //设置为模拟输入. L5 |. W/ P% r+ K+ }0 P$ g) E
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/ Y6 Q5 B' l0 T3 p
  15.     GPIO_Init(GPIOA, &GPIO_InitStructure);, `* m' n8 q7 M+ k) z! n

  16. . |! Z# R% f. K: j, x
  17.     DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;                                                         //不使用触发功能 TEN1=0
    9 R! v" J( F0 p* L0 X
  18.     DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;                         //不使用波形发生
    # L5 K, W- Q/ q+ z$ ]
  19.     DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;         //屏蔽、幅值设置* D% F0 m0 i. v5 V
  20.     DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;                                //DAC1输出缓存关闭
    ' P' c; L. i" u9 J9 [" [
  21.     DAC_Init(DAC_Channel_1, &DAC_InitStructure);                                                                 //初始化DAC通道13 |) Q( v$ \2 y) `7 F, W' }' D
  22.   G. \; Y# H* j! J4 p: _
  23.     DAC_Cmd(DAC_Channel_1, ENABLE);                                                                                         //使能DAC1
    0 m! Z5 g8 d) @- v. B
  24.     DAC_SetChannel1Data(DAC_Align_12b_R, 0);                                                                         //12位右对齐数据格式设置DAC值3 |+ ~" c4 o, f' ]- o, y3 A* Y& I& k! L
  25.         $ [3 k. R8 W8 i* K& }$ q! G3 ?: M1 C9 U
  26. }( Y/ C# K. E! @
  27. //设置通道1输出电压
    0 C0 p: g6 N# R1 _+ U$ v
  28. //vol:0--3300,代表0-3.3V( `2 X; v1 E# v, K8 `3 u
  29. void DAC1_Set_Vol(u16 vol)
    ( ~4 o' m; E7 Q* v$ ^; z) G1 E
  30. {
    1 o/ \7 K3 T% z! I" \: l2 ]9 e
  31.     float temp = vol;
    - F6 {+ n7 ?9 Z3 _& T* E
  32.     temp /= 1000;) a! p& Y% u6 y+ o5 O+ b
  33.     temp = temp * 4096 / 3.3;
    ) L) E  j3 P- I* Y, D5 o0 v" `2 M
  34. + ]1 v2 B+ @- ^- J( B0 [
  35.     DAC_SetChannel1Data(DAC_Align_12b_R, temp);
    7 c' |1 A: |) e1 E
  36. }
复制代码

- K3 l& b1 F( L6 a在初始化的时候,要注意一个问题,STM32F103单片机的DAC输出通道有两个。
* b7 |- P/ C7 i# H2 ~
6 ?( u( y( N+ T S05HG]2@QIXUY6W@SR$IY_O.png
2 h  c+ S& Q6 K! ]4 }0 U5 P. @
$ S$ ~& x# y$ T. ~: t8 v6 D- `PA4和PA5,但是在初始化引脚的时候,要将PA4和PA5初始化为模拟输入功能。这个在官方文档上也有说明。
5 p  X& w5 D2 s( Y  |0 w+ Q& o0 G
%NEMPB$XD{FGUJRE`}06FPW.png
0 @( A+ [! ~4 j3 p3 J8 w, M' e, b. d) a# O. \! O: h; }
  内部自动就会将PA4和PA5与模拟输出引脚连接起来。所以在初始化的时候,虽然用的是输出功能,但是还是要将引脚设置为输入。/ B& M/ \- d0 `- f

/ E* h& W: I* F/ [6 {: v$ k  初始化引脚之后,接下来初始化DAC功能,在这里不使用触发功能,也不使用波形发生功能。直接通过软件来控制3 V) c" u3 i8 O7 V

  ]6 f. n% T+ H7 F  接下里通过一个函数将要输出的电压值换算为寄存器的设置值。DAC的转换为12位,所以最大值就是2^12,也就是4096,而stm32单片机的供电电压值3.3V,所以将要设置的电压值除以3.3,然后乘以4096就是DAC寄存器需要设置的值。
* i+ L: a) f; q, L% g
, m9 k' J6 i$ _! r  如果要输出模拟电压值时,只需要在主函数中调用DAC1_Set_Vol()函数,并将要设置的电压值传递给这个函数就行了。
7 p2 Q. c4 f- P! C% n: ~; x" w5 h7 R0 X. F
  1. int main(void)3 o* @1 P8 z, P+ p/ Y; y0 a2 W
  2. {# g) v3 \! |# y
  3.     u16 adcx;4 C" u; P' F& H' k: K
  4.     float temp;! v' z. x/ F2 {$ K8 y0 w, g
  5.     u8 t = 0;" n3 u& Z- h% e1 C1 \+ U  O' I! B
  6.     u16 dacval = 0;$ f; W( E# |  [  i- z
  7.     u8 key;
    1 @7 u7 M# p. ~3 W/ q% s

  8. ; j/ M: o$ h& \
  9.     delay_init();: O. j1 x; e# N9 x  ?/ ?2 D
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);' D# k  {7 w+ N% E
  11.     uart_init(115200);6 O; s9 a  ^) G* @/ h' m( v
  12.     LED_Init();2 `# T. d( t' B6 e7 _- A
  13.     DAC1_Init();   
    , [6 J5 S1 s3 t; D5 t$ u. ^! K) `
  14.     while(1)
    - I4 J) t' L& W1 x
  15.     {
    % L' S7 S8 q% j$ l+ [
  16.         LED0 = !LED0;
    ' R9 W9 v3 x* f8 W+ Q0 L
  17.         DAC1_Set_Vol(1000);
    1 ~) z6 @8 M6 O" N! B
  18.         delay_ms(100);
    2 t5 e( d# @% r) o7 f
  19.     }
    2 @8 ]2 [( J) d. p" u0 [
  20. }
复制代码

" G6 \! P  w; T+ w  p在主函数中设置DAC输出的电压值为1000,也就是1V。这时通过万用表就可以在stm32单片机的PA4引脚量到1V的电压值了。; c. Z# S! ^+ F* p+ P

: r* }5 v- J0 |8 M. L0 I- C) A
) A( B  H. ?* E; |- R2 U
4 n4 C3 }' ~$ Q4 ]* l
赞 收藏 评论0 发布时间:2022-3-20 13:25

举报

0个回答

所属标签

相似技术帖

官网相关资源

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