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

基于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的设定输出电压值等信息。' d  R0 B) e" m8 W# E7 P5 x% W" \% u
/ p( q/ I6 V" L9 a4 |: s' p

# F) D4 q4 ]1 Z5 [1 r- M 20200514191553939.png
5 E1 K# h: E5 f  B1 y% M# @/ O9 q9 c6 G
$ h( C$ M0 [0 L- g7 R8 g
2020051419162562.png $ z: G& [! _8 Q+ Y9 k0 f) {/ O
% f& i% I( d6 L8 D
* `' J2 b. I1 Z( W3 A5 T  o
20200514191652697.png
* d4 `% o% X" ]! E. `$ s0 ]2 i1 |( p1 u. G  X5 I& g* w! C4 x4 R7 u

: p1 d" f2 {7 e! S: T* q 20200514191718963.png ) x" D4 N# N  g0 ?8 Z

) @  \% L  U# ]7 c

8 S+ N/ d! U3 J$ c2 v) M8 @, m 20200514191746367.png 9 ~/ o# y: m0 ~9 P6 ]
" ~1 ^7 f2 g+ r. P  N) Q3 |3 ^6 a5 k$ m
main函数5 u! q1 T; N( N, K2 U' k
  1. #include "led.h"
    0 X& p* `2 N6 G1 G7 h- U3 V
  2. #include "delay.h"' t4 \& O9 }0 Y
  3. #include "key.h"
    ' c0 O4 k- F. h+ L! P4 H* ?  Q% ^  g
  4. #include "sys.h"
    9 Y7 Z1 g+ X) d% \
  5. #include "lcd.h"
    ) C" k: l1 W. O) q/ [+ I+ u9 s
  6. #include "usart.h"         
    + H% y4 A2 a  ^8 z. e3 u
  7. #include "rtc.h" ; v( {) X+ y* M' k, p0 B
  8. #include "wkup.h"3 [" {. l* h/ K  B( u
  9. #include "adc.h"         
    9 H) G) x- P2 o7 k" v" X% C5 b$ @
  10. #include "dac.h"; L$ w0 b" t/ R5 I4 z6 I% M
  11. #include "timer.h"
    - O! `% V$ h3 A5 ~6 E. B# n
  12. #include "usmart.h"
    4 Y3 |" X9 ^0 v/ @0 E- q
  13. . Z$ c+ l3 W% C3 [/ j* j
  14. //设置输出电压
    2 g8 }- M$ r$ U1 m( _$ {
  15. //vol:0~330,代表0~3.3V
    * x, o( H# q5 @' W0 D4 x7 Y
  16. void PWM_DAC_Set(u16 vol)' ^$ ^$ g$ z5 \& F! W
  17. {
      T. V0 {, ?* A+ Q/ P0 ~9 D  v% r
  18.         float temp=vol;+ l, D0 W& v5 |  ~8 K# A0 D
  19.         temp/=100;
    . X+ l% r$ T8 g4 w" R
  20.         temp=temp*256/3.3;1 k- N& V5 {/ k1 V& @7 u; W
  21.         TIM_SetCompare1(TIM1,temp);
    5 u, y$ ]1 b0 f9 p- ?! E9 O; E
  22. }
    # }8 |) q' _: Z6 W. k1 U: O
  23. , M4 Z2 \& b  _4 a
  24. int main(void)
    $ r& g! J4 e5 ^2 E6 T3 F) z
  25. {         
    & ^3 r! @" T8 K, `6 U* O
  26.         u16 adcx;% U: i' k: _. h; v
  27.         float temp;% R) z  r# ]% H6 m
  28.         u8 t=0;         
    1 _7 O. Z1 }' s2 b* b
  29.         u16 pwmval=0;) `; c; x5 [5 ]0 a5 n, x! J$ T
  30.         u8 key;
    + Y- H: K/ \/ i3 d: v0 V
  31.        
    3 \+ P7 {8 W9 M, W
  32.         delay_init();                     //延时函数初始化          # w, q$ W( D2 L* e% j
  33.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    3 F" B. `# Y% `0 F) O, w/ H
  34.         uart_init(115200);                 //串口初始化为115200% S$ ~" G" o& a/ [1 b
  35.         KEY_Init();                                  //KEY初始化
    5 ], H- `. G9 M6 W
  36.         LED_Init();                             //LED端口初始化
    . P" v) N6 C9 v7 G' {, x
  37.         usmart_dev.init(72);        //初始化USMART       
    3 W( K) A  y2 c- {: t
  38.         LCD_Init();                                  //LCD初始化4 O8 T6 Q( |& ^0 L3 y
  39.         Adc_Init();                                  //ADC初始化5 A' y) h% @# U0 D9 C( Q; I: W
  40.        
    & L& O. J& x* m1 t4 \& g
  41.         TIM1_PWM_Init(255,0);        //TIM1 PWM初始化,计数周期为256,Fpwm=72M/256=281.25Khz.
    2 L1 a0 U4 E  H! `  ]- S: a, L7 e
  42.         TIM_SetCompare1(TIM1,100);//初始值为0        8 d. q. [! z5 x, ], w5 t; q
  43.              
    4 ^8 [# g" E3 _! q9 |3 {. s
  44.         POINT_COLOR=RED;//设置字体为红色
    ; i/ H* b9 E7 G4 _
  45.         LCD_ShowString(60,50,200,16,16,"WarShip STM32");        , M# p* T0 q& T1 k7 [
  46.         LCD_ShowString(60,70,200,16,16,"PWM DAC TEST");       
    7 Z9 v# m/ }. W1 M! D) F# \$ I
  47.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
    + }1 I% w, ~+ |. W' [
  48.         LCD_ShowString(60,110,200,16,16,"2015/1/15");       
    5 N& T5 N2 a! K) D2 l, P/ |# F
  49.         LCD_ShowString(60,130,200,16,16,"WK_UP:+  KEY1:-");       
    " `+ p4 d3 _+ F" J
  50.         //显示提示信息                                                                                             
    . N2 s# ~7 `% U  v  p, D- R7 D# A
  51.         POINT_COLOR=BLUE;//设置字体为蓝色' }# N; g" [* f/ G) e+ f5 r$ M# X
  52.         LCD_ShowString(60,150,200,16,16,"PWM VAL:");             
    ) A' G/ D0 r  H4 @( o
  53.         LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V");              ! C6 P1 W' Q+ \" P) R0 z/ F; S
  54.         LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");6 s/ ?" a3 F& ]# ~
  55.         # n5 B+ U% e# [4 a. \- L
  56.         TIM_SetCompare1(TIM1,pwmval);//初始值                          3 }! q; v8 E! q) e/ X0 T# J, Q
  57.         while(1)# [* J+ X9 P4 v8 j) M
  58.         {
    # A- U+ Q- d' d2 U
  59.                 t++;
    9 y6 y4 |7 G. y6 A$ c
  60.                 key=KEY_Scan(0);                          ; A* t3 g" p, B2 o' ^
  61.                 if(key==WKUP_PRES)/ }( O0 u! R0 j" K/ C) O1 Y
  62.                 {                 $ D* }% p: m% [4 P/ M1 G
  63.                         if(pwmval<250)pwmval+=10;2 m! l+ [' H1 A
  64.                         TIM_SetCompare1(TIM1,pwmval);                 //输出
    4 I2 C4 C9 L, b9 T- ^" H/ T% b
  65.                 }else if(key==KEY1_PRES)          c  R# [! y  {
  66.                 {
    . F6 z0 |. z) M/ d0 d6 k
  67.                         if(pwmval>10)pwmval-=10;  T$ U4 @3 ^. r
  68.                         else pwmval=0;
    ( ~9 W: f0 Y5 f! S7 w# ~
  69.                         TIM_SetCompare1(TIM1,pwmval);                 //输出
    8 T: f$ j7 {( g. r1 T
  70.                 }         1 o% ?2 A/ H# Y: w
  71.                
    $ [3 m- @: Z: `" F
  72.                 if(t==10||key==KEY1_PRES||key==WKUP_PRES)                 //WKUP/KEY1按下了,或者定时时间到了
    ' i9 Y$ e  ?" |+ B: V
  73.                 {          
    & z) A3 ~7 |% ~- B3 i- v1 E  K
  74.                         adcx=TIM_GetCapture1(TIM1);$ ^: G2 G) ~' A# d- `
  75.                         LCD_ShowxNum(124,150,adcx,4,16,0);             //显示DAC寄存器值0 H" J/ V' k4 |, Q9 s* W' p8 R4 f
  76.                         temp=(float)adcx*(3.3/256);                                //得到DAC电压值
    9 e- S; z* u" s4 x" A. S
  77.                         adcx=temp;6 _* o* a- w% ^% H% Z. c' f+ R" s
  78.                         LCD_ShowxNum(124,170,temp,1,16,0);             //显示电压值整数部分
    . h2 R' h2 |) _% d
  79.                         temp-=adcx;+ N* E; R7 C3 N
  80.                         temp*=1000;2 E: H; U7 P. O  s! x# {6 a
  81.                         LCD_ShowxNum(140,170,temp,3,16,0x80);         //显示电压值的小数部分
    ! t8 Q: p) d0 a7 O
  82.                        
    ; J$ p2 Y1 G! H4 ?/ N& G3 N! t
  83.                         adcx=Get_Adc_Average(ADC_Channel_1,20); //得到ADC转换值          
    6 P1 f1 I- e+ q5 y3 v
  84.                         temp=(float)adcx*(3.3/4096);                        //得到ADC电压值
    - m4 A, C: M8 {" m0 F
  85.                         adcx=temp;& C  L2 \" C) |7 P
  86.                         LCD_ShowxNum(124,190,temp,1,16,0);             //显示电压值整数部分1 x5 A% j& E% V) J
  87.                         temp-=adcx;
    , J  `& @+ H& ?& K# I" c4 N
  88.                         temp*=1000;
    , _9 U7 Q1 ~% E/ F  a
  89.                         LCD_ShowxNum(140,190,temp,3,16,0x80);         //显示电压值的小数部分. G* r) [  Q9 H- ~
  90.                         t=0;( q& A+ h* ?8 \$ r7 u2 {
  91.                         LED0=!LED0;           4 a9 |  H: w# }" y. G" b
  92.                 }            
    " O- S6 t2 u4 J( |% M, [& R
  93.                 delay_ms(10);        # |% ]* `. E5 o: p+ o7 |
  94.         }. Y& `1 T' w5 ]  r* B) I
  95. }" _/ e+ [8 u; n8 M8 y( t
复制代码

3 s. I, Y1 o/ a% _  t
" e4 m5 h+ ?( l: T( g
pwm_dac.c函数- T$ T4 z) k' {; n
  1. //TIM1 CH1 PWM输出设置
    % L/ r1 B% C7 b" _1 U7 t* `* U$ K
  2. //PWM输出初始化* w( ^7 i  h% m9 |
  3. //arr:自动重装值+ Z+ v; n/ X% |3 O
  4. //psc:时钟预分频数
    ( i2 Z$ h+ o+ [# A; |6 L, j8 ^" m+ ]
  5. void TIM1_PWM_Init(u16 arr,u16 psc)) b" J# |5 h( U) H
  6. {                                                                  - V4 B- f2 r5 F* m
  7.         GPIO_InitTypeDef GPIO_InitStructure;
    6 x+ q; p/ D( r1 R  _* P
  8.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    & i+ r* j+ A, s* D  O) F
  9.         TIM_OCInitTypeDef  TIM_OCInitStructure;
    $ m' _* u. a% t7 h& b7 B2 A
  10.        
    & J! K$ [8 e4 n
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能TIMx外设, e# U2 u) S, \3 Q- E  F2 o& [
  12.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA外设时钟使能9 l( {1 O; k/ W( B! d" X
  13.          7 y0 _" H. c) v8 c$ g. Y
  14.   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
    6 D. q7 Y8 u: U0 z6 f2 N; Y
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM1_CH1& X( ]3 d; S( M# k
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出2 Q9 T( Q: t' O, I, W
  17.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;8 N/ z2 V% ~* H3 t' i
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO/ x2 V, Z& a$ p& a6 O
  19. + W9 I$ c$ k  q, t) D
  20.         TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载周期值: B/ \2 T0 M% G0 ?
  21.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 不分频) j" k/ J- s9 S' h) ?) K# P
  22.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim( y& Q2 \, e% u5 a+ ]& M
  23.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式% j. t! t, R8 O; {' t; z! j4 g7 D# D! H# F
  24.         TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
    - m' x0 X  G& r
  25.                  : \  t! `. b( x+ g6 Q5 G
  26.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式        - s0 K/ P' b- o# k& n. A, \& x
  27.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    2 p8 ]( i* G  D& r
  28.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值9 M1 |1 t# h+ Q* y
  29.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效 ! O6 l# n2 t) T7 E/ Z- F
  30.         TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx% d  ~6 `) y( j: d$ }

  31. $ ]" e! ?! n7 q5 l! ], o4 o  Q. L. s
  32.         TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1 预装载使能( z5 q( F4 |. W' j# V
  33.        
    * G% \" P1 l: w! l
  34.         TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器8 T7 ]( x% I7 x6 @2 S  D* @$ ^2 R
  35.         " f6 v" g1 _- V; T8 ~5 R  p/ w
  36.         TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个 4 A# \! ^- a7 N9 E. _! A; g
  37.        
    " `! L( x8 n8 B+ O& R
  38.         TIM_Cmd(TIM1, ENABLE);  //使能TIMx                                                                                             * |7 S3 B2 ~5 E) H/ n! }
  39. } 0 B3 M* {6 @4 g
复制代码
7 ^$ F/ {' Q- p' ~

  L1 h+ \$ c* F3 [$ r————————————————
& c& I) b% n: R9 i5 _9 r( k版权声明:_Amen- Z4 g& P! ~  w. X; {
如有侵权请联系删除
# p6 ]: m) r( b
& M1 U  u: D4 h
4 q/ h+ ]" X1 X! g* N# e( ~& E. X
收藏 评论0 发布时间:2023-5-14 17:40

举报

0个回答

所属标签

相似技术帖

官网相关资源

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