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

基于STM32F1开发PWM DAC实验经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-14 17:40
STM32F1自带的DAC模块的使用。但有时候,可能两个DAC不够用,我们可以通过PWM+RC滤波来实现一个PWM DAC。本章将向大家介绍如何利用STM32的PWM来设计一个DAC。利用按键(USMART)控制STM32的PWM输出,从而控制PWM DAC的输出电压,通过ADC1的通道1采集PWM DAC的输出电压,并在LCD模块上面显示ADC获取到的电压值以及PWM DAC的设定输出电压值等信息。
* @( h6 [4 Q8 J, N' z
2 B- d# v; k: [) e& @1 K$ X
: ?$ d( `' s8 m, q  F+ [
20200514191553939.png
# S" d% `; a) B% k/ j! }
3 X/ {/ o; g: l! l
; F  ~. F0 p7 B, D
2020051419162562.png # G0 f" O+ q# j
2 @7 g9 x; H. w2 k+ y
/ y! c5 M: [. ?* b) b
20200514191652697.png # k5 b9 y1 \* m% U# B' b. Z

8 b* b. w9 c% U: M0 A* @: x

) L# c  ]% c* R- ?" \8 y! b 20200514191718963.png   j% f6 @/ X; m

& }% }1 M; c2 T7 d0 R

/ E. x' ?# z# O 20200514191746367.png
! x. T8 X8 @1 m- ~2 F
$ x% K9 T$ Q5 E% m3 L; [6 omain函数5 u6 M. V! Z2 K4 A
  1. #include "led.h"
    ! C* v3 G7 d, P. t
  2. #include "delay.h"0 n% I* O. h1 y5 X7 r) V
  3. #include "key.h"  k  `& b3 k, N, v
  4. #include "sys.h"
      R" B( t# ^" n' x" B
  5. #include "lcd.h"
    + `9 @4 U$ P8 x/ v
  6. #include "usart.h"         : ], g8 x' z" ]0 n9 l* I
  7. #include "rtc.h"
    5 G2 j3 y9 s4 t# p/ \
  8. #include "wkup.h"8 b2 ]# o% H+ H+ k2 m$ D! d/ y
  9. #include "adc.h"         
    - {5 D2 ~% s5 {8 B: P2 @9 A3 s
  10. #include "dac.h"
    ! \, @2 _! I( `7 U' ?- {
  11. #include "timer.h"$ D: {6 d3 ]: Q/ e" C) ^
  12. #include "usmart.h"
    - X6 b% W2 F% e: t1 R
  13. ! _& x  c0 H1 u% P; v& k
  14. //设置输出电压* q. W+ ]" E$ t* [9 n
  15. //vol:0~330,代表0~3.3V9 O- |5 R9 ?$ Q9 y! R! ~! d# B
  16. void PWM_DAC_Set(u16 vol)
    , t  x4 c! @; R2 \/ Z
  17. {
    ( k+ V  @& j# X3 \7 j% o
  18.         float temp=vol;
    : h% h+ N$ Z. Z8 j# @& J9 M5 f
  19.         temp/=100;
    . r$ D5 G( R( r8 `; n" t* M+ y
  20.         temp=temp*256/3.3;3 F; T. o& h  m' i) e( j5 i
  21.         TIM_SetCompare1(TIM1,temp);2 J. T/ d3 n' {% W6 }+ f
  22. }+ R; Y, Q, [  t- t; I$ S* `+ ?

  23. - h0 j& m: m& c: v/ e2 p
  24. int main(void)
    & z5 y# T! `7 }$ H6 R) y- x
  25. {         9 G3 D/ L8 y: U: Y# y
  26.         u16 adcx;
    # O1 K8 O. ]# `% ]- f
  27.         float temp;
    4 ]* L$ v+ o- j) X6 f$ y
  28.         u8 t=0;         + ?, T0 z1 G4 z7 P/ F
  29.         u16 pwmval=0;
    # w0 n* L$ O( s7 g, K& y2 G
  30.         u8 key;1 e+ g  D: @9 l
  31.         4 l& _8 y" q2 x. H7 L7 D6 s5 ^
  32.         delay_init();                     //延时函数初始化          
    ; h. d) Q# t* w0 v) c! z2 L8 S0 k
  33.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    ( S' o3 J+ K7 \
  34.         uart_init(115200);                 //串口初始化为115200/ f5 {6 W2 w9 z
  35.         KEY_Init();                                  //KEY初始化/ P, f* N4 U2 X/ s
  36.         LED_Init();                             //LED端口初始化
    ! `" q. k; W) u5 J) ^+ N
  37.         usmart_dev.init(72);        //初始化USMART        " O( J; w, V& C2 C" Z
  38.         LCD_Init();                                  //LCD初始化
    0 Q( x; Q1 G* a' M
  39.         Adc_Init();                                  //ADC初始化3 R, R7 g1 L9 t8 D1 U9 _
  40.         / ?, m& ~7 e5 q( ^% e# {# e) W
  41.         TIM1_PWM_Init(255,0);        //TIM1 PWM初始化,计数周期为256,Fpwm=72M/256=281.25Khz.
    8 m  n  h( A, L( K5 }
  42.         TIM_SetCompare1(TIM1,100);//初始值为0       
    " m0 H; t1 o9 W5 U6 d# Y
  43.              ! S. g/ Z: Q3 T; O( |+ K& I+ G
  44.         POINT_COLOR=RED;//设置字体为红色
    5 K: m$ C5 o: ^4 b
  45.         LCD_ShowString(60,50,200,16,16,"WarShip STM32");        ! K  T- L) L+ |0 c+ O& H) \) {
  46.         LCD_ShowString(60,70,200,16,16,"PWM DAC TEST");       
    4 ?0 l( \0 S  X2 ~4 ]" G- o/ d1 ?
  47.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
    ( |. v1 C6 T) n3 t+ X8 o
  48.         LCD_ShowString(60,110,200,16,16,"2015/1/15");       
    ) D- G3 W: H, w3 q. i- _, j  |
  49.         LCD_ShowString(60,130,200,16,16,"WK_UP:+  KEY1:-");       
    ! z/ E( Z4 h. ?
  50.         //显示提示信息                                                                                             
    / B; ~: f; t* H: e: T) v# O
  51.         POINT_COLOR=BLUE;//设置字体为蓝色
    0 e) t( [4 G0 v- v( E
  52.         LCD_ShowString(60,150,200,16,16,"PWM VAL:");             
    : X' z  ?+ e: k' ~( }' u& }; n
  53.         LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V");              ; m1 b; q) o1 s4 [, X
  54.         LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");
    - G/ W$ ]0 S/ y; F  Z& w5 ?
  55.         - N, L, i  L8 c1 Q/ g: f
  56.         TIM_SetCompare1(TIM1,pwmval);//初始值                         
    6 _' ?7 S% U$ L9 p0 ~
  57.         while(1)
    + e' S" o. d% x( C% g  S9 [% A) Y4 H
  58.         {* e* j$ d9 `8 w1 o1 L4 p
  59.                 t++;
    & h: x$ t& s3 P: ~" S- P9 l
  60.                 key=KEY_Scan(0);                          
    ) N7 O! W/ X3 l: d- c7 o
  61.                 if(key==WKUP_PRES)' k% X# x7 z/ a, s. M# e- E
  62.                 {                 
    & g3 ?3 |1 d6 f3 l  J+ o
  63.                         if(pwmval<250)pwmval+=10;
      |- z, C) a4 z" v9 P+ s3 m
  64.                         TIM_SetCompare1(TIM1,pwmval);                 //输出" }7 R- n3 y' i; [( [: j
  65.                 }else if(key==KEY1_PRES)        ! k  a: |4 Q1 g" P: N1 Y' C
  66.                 {- _* |5 g- C$ K7 T/ P% @
  67.                         if(pwmval>10)pwmval-=10;# T* a( O8 z0 C% x5 U  p1 G$ v
  68.                         else pwmval=0;) P# a0 `2 S- ]! O# D$ ^
  69.                         TIM_SetCompare1(TIM1,pwmval);                 //输出- u6 S6 _2 ]* s8 `# J1 P  T+ O4 t
  70.                 }         
    . f# x& d8 \  `" F
  71.                 " P' m; }& ~9 c+ R* m! z
  72.                 if(t==10||key==KEY1_PRES||key==WKUP_PRES)                 //WKUP/KEY1按下了,或者定时时间到了) c9 }; h: J+ k3 c4 k
  73.                 {          
    2 @1 q5 D+ C) X5 V2 L& V' i4 Y0 N
  74.                         adcx=TIM_GetCapture1(TIM1);, l4 F8 h" q+ m( d' v6 }2 t
  75.                         LCD_ShowxNum(124,150,adcx,4,16,0);             //显示DAC寄存器值
    ( [" i" t* p$ r# Z' q
  76.                         temp=(float)adcx*(3.3/256);                                //得到DAC电压值
    # ^5 b5 _7 g$ d9 ^- c
  77.                         adcx=temp;4 m8 P3 M- J, v' Y  _9 \! z
  78.                         LCD_ShowxNum(124,170,temp,1,16,0);             //显示电压值整数部分9 g6 U0 l  R+ ~9 B: F
  79.                         temp-=adcx;2 s( L+ [* v0 |% h* l3 d1 m+ |
  80.                         temp*=1000;
    $ a& C5 P' {) Y0 ?9 l, \
  81.                         LCD_ShowxNum(140,170,temp,3,16,0x80);         //显示电压值的小数部分  `) k  F/ |! y/ B9 S% J7 ?- o
  82.                         , Q6 @0 v  W- \" m. S
  83.                         adcx=Get_Adc_Average(ADC_Channel_1,20); //得到ADC转换值          
    + N" a* L* Q4 C; u( s) v
  84.                         temp=(float)adcx*(3.3/4096);                        //得到ADC电压值) l0 r" p1 h! [7 r% U' r
  85.                         adcx=temp;
    - f0 k& C% N' x5 E3 p* F
  86.                         LCD_ShowxNum(124,190,temp,1,16,0);             //显示电压值整数部分
    8 r$ g" @  V0 n+ r3 O* W* _
  87.                         temp-=adcx;9 H/ |5 x2 K: k# |+ _
  88.                         temp*=1000;
    8 z! {- K8 G  d1 b
  89.                         LCD_ShowxNum(140,190,temp,3,16,0x80);         //显示电压值的小数部分  N2 o; z! g* Z: e5 Q5 P
  90.                         t=0;# _) x) L# v4 _# V$ f$ w% g& e% d
  91.                         LED0=!LED0;           5 ^6 P; G: o7 d6 f
  92.                 }            
    ( @. p# @8 n7 t% m
  93.                 delay_ms(10);        " F4 n" Y! B2 y- N5 G
  94.         }$ \8 ?2 h: w% _  f5 |# F- i9 O
  95. }3 ]+ |) q9 e+ b
复制代码
2 R- l; ~7 G: N! Q
+ ~! v$ F! Q7 f- A
pwm_dac.c函数: k; W, A2 b1 d( k9 C1 w4 @- k
  1. //TIM1 CH1 PWM输出设置
    9 S8 ^# x& G9 Q; J
  2. //PWM输出初始化6 Y4 D. \% ^, y; n3 V3 S
  3. //arr:自动重装值
    1 K8 @$ k0 o, y4 ]2 d+ @6 K' }
  4. //psc:时钟预分频数
    & x1 G' I& Q, b( }$ ^( l
  5. void TIM1_PWM_Init(u16 arr,u16 psc)6 G% u3 t* I% A4 u# i5 V
  6. {                                                                  ; y3 _0 r8 h0 |, G1 q
  7.         GPIO_InitTypeDef GPIO_InitStructure;7 n  K; T! F: F; l& G4 u" O- k
  8.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    # P& U$ o, g( c, z+ f
  9.         TIM_OCInitTypeDef  TIM_OCInitStructure;6 e3 f* J2 o! k6 k! a) a) Y; R
  10.         1 h* W, H1 @8 h( P9 h6 i5 ^
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能TIMx外设5 S# B9 {, H5 E; R- x
  12.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA外设时钟使能# l, A; v  X# K" K$ I) Q3 u9 L
  13.          + b% j) l  x3 n. w5 l; u- s. K
  14.   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
    ; D# @" e  u  k' x
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM1_CH1! W2 D0 M+ l* `3 p0 y, K, f8 U3 E( Y
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出/ H& ^4 l, T7 |
  17.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 p. P) H2 i" L9 ]7 X
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO% w. _( m- _( T' a+ F+ T5 u

  19. , w7 u% |; [$ x
  20.         TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载周期值" w  ^& @5 A  W& [  N
  21.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 不分频
    % W7 W0 C* v9 m( o. S# `
  22.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  k2 E4 ~" K  I
  23.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    % ]7 O0 w0 `2 ^6 t* b1 J
  24.         TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
    - J6 c/ b  q7 y& n
  25.                  9 B6 I- n, n  m4 j& n8 \
  26.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
    + X5 R  V. _" }3 B0 J9 a' Z
  27.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能% w- o% ]; \# _  g( `/ a0 s
  28.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值, Y3 _" g6 J% R3 z. r2 I' V' m
  29.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
    2 E, I* P2 ^$ M! i
  30.         TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx% o. P+ P9 S8 ~& T

  31. 6 c! n, Y& u& }' c: h, Y( ]
  32.         TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1 预装载使能
    , B: p. K( e# _5 ~& h
  33.           c/ K6 s/ o2 i- u* S
  34.         TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
    - y" H: j7 Q# T6 J% J9 D% X# {
  35.        
    / \: {6 d+ M$ n1 q( m8 l
  36.         TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个
    0 ]6 W$ q6 v  A5 j1 f9 X
  37.         / g! _; n2 G7 M! w8 i) K( {
  38.         TIM_Cmd(TIM1, ENABLE);  //使能TIMx                                                                                             
    $ \/ V, m0 {% f5 Z4 C" ?, ~* u
  39. } & P( F, R& R* C+ `- z! a
复制代码
' V+ u# {# @5 I- a6 N) |9 n. N

& }; H5 f8 Q; `" \6 f6 {————————————————/ E$ J7 O( p7 y2 f
版权声明:_Amen9 \8 [. H( P7 P, |; v- l
如有侵权请联系删除9 [/ K' ^  T; I7 Y) G8 M! j& V  [# q

0 p( u, k& a+ b
" u$ Q5 t6 d% z- i
赞 收藏 评论0 发布时间:2023-5-14 17:40

举报

0个回答

所属标签

相似技术帖

官网相关资源

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