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

基于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的设定输出电压值等信息。
8 N( @1 L6 p7 w  ^2 ^9 z1 L. y! y2 z# }5 `, K( M

) T# x( o# H; s+ u/ P+ e! d 20200514191553939.png
5 p$ h: E% D; u0 r: Z- h* [7 M: m; @( r+ `

' U; n. B, C: i: u* R6 R8 ` 2020051419162562.png / {7 W5 _! ^+ _. a3 j- ?

$ v+ q: L9 p4 f* U3 G4 |

" [) K* r8 Q2 s 20200514191652697.png
$ P* j' O& e! o
: W! c4 @6 K2 B! O1 k
/ G. ]8 q$ ^. a4 ]
20200514191718963.png $ _- _- N9 u* R7 p5 A( U
9 [, O- g# S; G5 z5 L/ {) Q

/ g+ N/ p& w6 f4 K( _) }- z 20200514191746367.png : J( K! x- V" g- c& d$ C

9 T, j; c/ H* s5 t; U6 Z0 Dmain函数
  y, z7 [2 A) K2 w- f. f! }5 e5 J
  1. #include "led.h"! R) k/ l8 e' p5 R
  2. #include "delay.h"9 A2 A& n0 D/ N4 g6 H% E
  3. #include "key.h"
    8 U/ G5 g9 `2 f3 T' c# ^
  4. #include "sys.h"
    . |- f. k  |5 |( O" A+ T6 S' Q  ?
  5. #include "lcd.h"
    * Q( c* r0 C/ l7 Y: ]& X0 U
  6. #include "usart.h"         1 Q) L- E: M% x0 t3 \* ~, v; U9 C
  7. #include "rtc.h"
    # _  T, t5 y+ ?& p. i
  8. #include "wkup.h"* S6 A! I  h9 N1 s- A* k8 K. m" b
  9. #include "adc.h"         
    5 Q- ~; {, R! q$ H5 \% {) R
  10. #include "dac.h"
    $ W) B) t+ ~8 _5 r+ [
  11. #include "timer.h"
    . |7 `8 b) Z; n+ O# X
  12. #include "usmart.h"! `' G! W' {6 x9 n
  13. + ~' {6 d/ ]6 O8 W/ c2 G7 v% a
  14. //设置输出电压3 J( g+ I0 G! d/ b, x! T9 E" i' K
  15. //vol:0~330,代表0~3.3V6 E- ?) ]5 V; r) {+ y; V8 Q
  16. void PWM_DAC_Set(u16 vol)
    " K6 @! ?: `9 w+ S5 S; U) q, s
  17. {- ^1 ~1 N' I+ n& \
  18.         float temp=vol;! X+ h- _, q) f" ]8 I- E" n: j, ^
  19.         temp/=100;
    ' y9 b9 m8 U! s: a/ Y
  20.         temp=temp*256/3.3;9 e3 s" i& m3 y
  21.         TIM_SetCompare1(TIM1,temp);
    0 ^& x4 a: B, B6 P8 M4 b8 _
  22. }
    9 }' \1 Z' z4 \' s, k

  23. 3 |4 l9 R% D3 I: X  }6 _
  24. int main(void)
    6 ]( @  E& X6 \6 a
  25. {         
    + T6 F9 x6 B- Z: h
  26.         u16 adcx;1 i+ X" _; e) I; L. J) O6 A* Z# M+ U
  27.         float temp;3 n  B, l9 a) V0 @
  28.         u8 t=0;         + v! C8 ]1 O, j
  29.         u16 pwmval=0;! X+ f" Z3 I' B! Y% [
  30.         u8 key;" K" o" e& K$ J- d
  31.         ! n; d( W/ ]* K0 L/ j
  32.         delay_init();                     //延时函数初始化          & @1 C! a4 d* a! U1 E+ }& e
  33.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级( p0 k2 F$ `$ U/ A! j
  34.         uart_init(115200);                 //串口初始化为115200# \+ J  Q8 `/ f. O  M! T, _
  35.         KEY_Init();                                  //KEY初始化. n) D; P+ l! q: q$ {
  36.         LED_Init();                             //LED端口初始化
    % o9 ^! W9 F  `! H
  37.         usmart_dev.init(72);        //初始化USMART       
    + q+ A2 H% I7 K. c
  38.         LCD_Init();                                  //LCD初始化
    " @4 x% j$ E' z0 X& a
  39.         Adc_Init();                                  //ADC初始化! P9 h* i4 `3 i0 f- i
  40.        
    $ l2 d0 R/ s; [7 c, ^
  41.         TIM1_PWM_Init(255,0);        //TIM1 PWM初始化,计数周期为256,Fpwm=72M/256=281.25Khz.8 n8 z% E8 H& n  J' p
  42.         TIM_SetCompare1(TIM1,100);//初始值为0       
    # d* {/ B: w7 T6 j* r: u
  43.              
    2 u4 f! K8 T! [! k# v6 K
  44.         POINT_COLOR=RED;//设置字体为红色
    & n' Q/ Z* G1 e9 z* @# T
  45.         LCD_ShowString(60,50,200,16,16,"WarShip STM32");       
    ( ~: Y  s$ w0 N& B; v- S3 O9 _
  46.         LCD_ShowString(60,70,200,16,16,"PWM DAC TEST");       
    1 H5 N9 ^3 B. N% e' J. }
  47.         LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
    ; o2 \5 A) D1 b, T5 K
  48.         LCD_ShowString(60,110,200,16,16,"2015/1/15");          H( F' m! K$ n2 N
  49.         LCD_ShowString(60,130,200,16,16,"WK_UP:+  KEY1:-");       
    0 i! R+ G7 Y  i5 ]! g6 l
  50.         //显示提示信息                                                                                              + b" x. K, k$ r% T
  51.         POINT_COLOR=BLUE;//设置字体为蓝色# K  G* j, X2 `1 C' ^
  52.         LCD_ShowString(60,150,200,16,16,"PWM VAL:");              , k5 |' d( ~6 P+ N* D4 B
  53.         LCD_ShowString(60,170,200,16,16,"DAC VOL:0.000V");             
    : e# D0 J, A; |* a8 ]) D  E
  54.         LCD_ShowString(60,190,200,16,16,"ADC VOL:0.000V");$ Q. y1 @/ y8 G0 P
  55.         9 L7 V+ M# M+ @' k8 F5 M
  56.         TIM_SetCompare1(TIM1,pwmval);//初始值                          : w2 s. f! z! ]  {
  57.         while(1)! ]# @1 D! p6 ]2 J
  58.         {7 ]- l3 Z4 V; `% @8 |
  59.                 t++;9 u* \& t4 z" `: t
  60.                 key=KEY_Scan(0);                          
    4 R! \+ u3 ]  d6 a& c
  61.                 if(key==WKUP_PRES)
      B4 P5 _0 G. w
  62.                 {                 - ]6 k* e0 N, b% C/ S$ w
  63.                         if(pwmval<250)pwmval+=10;( S/ I& ?  ^- ?" L
  64.                         TIM_SetCompare1(TIM1,pwmval);                 //输出& h7 C' L. h1 i' G% p1 h
  65.                 }else if(key==KEY1_PRES)       
    7 q, O5 B: I! @' r) v( J) e% x  c
  66.                 {
    1 Y/ I0 d* n  y
  67.                         if(pwmval>10)pwmval-=10;& _/ b  T: Q( u2 b. t# A: h8 T) l/ j
  68.                         else pwmval=0;
    5 }) }% I$ a$ V
  69.                         TIM_SetCompare1(TIM1,pwmval);                 //输出& ?# ]2 @  L4 h) Z; B' j
  70.                 }         
    3 ?3 L" ?" f  \  s( g
  71.                
    " e% Q7 v. r2 n3 B  T, H; S
  72.                 if(t==10||key==KEY1_PRES||key==WKUP_PRES)                 //WKUP/KEY1按下了,或者定时时间到了) q+ O/ f  R% F, t5 \+ R9 q& Q
  73.                 {            G0 e! f( B, ?
  74.                         adcx=TIM_GetCapture1(TIM1);! M( n( ]: q: r- o" J1 e
  75.                         LCD_ShowxNum(124,150,adcx,4,16,0);             //显示DAC寄存器值* _- l9 s9 J( D/ W' |# y8 t
  76.                         temp=(float)adcx*(3.3/256);                                //得到DAC电压值
    & e  N0 r7 z) O+ A
  77.                         adcx=temp;
    5 X3 Y' Y  m! e
  78.                         LCD_ShowxNum(124,170,temp,1,16,0);             //显示电压值整数部分
    7 u" ?; g) L, M8 P; w1 }: T$ a
  79.                         temp-=adcx;% t' @5 |+ n8 d8 J: q
  80.                         temp*=1000;
    4 q( q) x1 t1 i7 l
  81.                         LCD_ShowxNum(140,170,temp,3,16,0x80);         //显示电压值的小数部分
    2 W5 R  e3 w6 t. g5 v7 ?, ]
  82.                        
    / z0 m/ \) T' `6 u) ]6 b7 ^8 E
  83.                         adcx=Get_Adc_Average(ADC_Channel_1,20); //得到ADC转换值          3 t7 m) q$ H& y  t# p
  84.                         temp=(float)adcx*(3.3/4096);                        //得到ADC电压值/ U2 z+ s# {5 N- g1 F4 T7 X
  85.                         adcx=temp;8 g/ C) W/ T" l
  86.                         LCD_ShowxNum(124,190,temp,1,16,0);             //显示电压值整数部分
    8 ?% \, B; s  Q- ]
  87.                         temp-=adcx;( Q3 J* }& d$ m+ R5 g  I
  88.                         temp*=1000;
      N' G! h* v1 L2 q
  89.                         LCD_ShowxNum(140,190,temp,3,16,0x80);         //显示电压值的小数部分
    9 \' @2 ^- |4 |, A0 R4 x1 H: o
  90.                         t=0;
    4 o0 @- b8 b, G! T9 U) E
  91.                         LED0=!LED0;           - p# I+ M2 `6 J1 R' Q5 [) S
  92.                 }            / m; x8 j  s$ n+ o5 z
  93.                 delay_ms(10);        7 R3 ?7 a! u4 P( f# R4 L7 ?0 T
  94.         }* z  z- U& h. ]1 b" g' p0 `
  95. }# [; D' t; y6 n- Z* U' ]* P
复制代码
: w% M7 {9 V! f5 J. ~% E
1 t2 c/ e! A9 x  |$ ?- _
pwm_dac.c函数" ^0 S  u: q$ C: F( U% N9 D: n
  1. //TIM1 CH1 PWM输出设置 ( U5 w3 F8 J& }4 ]
  2. //PWM输出初始化/ ?2 f) I) N# e' @; F9 V+ O: w
  3. //arr:自动重装值
    1 a3 B' F+ \8 y7 h! b9 H/ n
  4. //psc:时钟预分频数
    " ^+ n( R6 w7 I( _7 Z
  5. void TIM1_PWM_Init(u16 arr,u16 psc)
    # S& Z4 v5 h' b4 y/ A
  6. {                                                                 
    0 A$ j( ?4 O# b
  7.         GPIO_InitTypeDef GPIO_InitStructure;4 h3 ^, I9 W2 I3 M1 a3 Z
  8.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;4 h! f/ c; C: Y: M% P
  9.         TIM_OCInitTypeDef  TIM_OCInitStructure;
    4 n, U4 F6 `9 ?" K% e' E8 b: X
  10.         ( t' Z: ^* O" s# Q3 A8 o' }, J. P
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能TIMx外设
    6 H9 C" l8 w% F! t
  12.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA外设时钟使能# _9 z* w( b7 r: ]
  13.          ! N2 D5 K7 s( K
  14.   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
    * Z4 U; X! C, T- ~8 i( r6 L# M
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM1_CH1
    9 h. y. M- C9 _' Z: c. R4 x5 c
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出
    + s* z7 v/ r4 W$ b9 w$ e; ?+ }" K
  17.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    % O) H* w; G% L: U
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO# T5 R/ W0 v, L- l. @: j

  19. 4 M0 ?- [/ R0 a0 _5 E, ?5 F+ m
  20.         TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载周期值
    5 m% I* _: C- M7 [/ M) A
  21.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 不分频
    1 d: s5 o. Q/ M: A" k4 D
  22.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim" h: _  x" J9 M+ L( Z
  23.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式8 T( w3 C) q  }/ C8 O
  24.         TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
    4 v$ e* ]6 @4 t" x' K, ^
  25.                  5 o# P0 y7 G4 d
  26.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
    - t' l5 Y, t3 w& e
  27.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    7 [( Y2 g7 o# V( u6 b$ v
  28.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值( O/ B% _) |7 y# I
  29.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
    # b9 l3 ?: Q7 ^" t' o* N1 Z
  30.         TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx
    " j+ H# C$ k7 t! k
  31. # K  N: E& `( S& k" {6 Q* i
  32.         TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1 预装载使能
    ' }; \7 T  j) ?
  33.        
    6 C8 R( [" }( R" r) a
  34.         TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器5 S) k# ?/ `: C, @) J! W; I% v
  35.        
    / K5 G9 S' g; c- y* a
  36.         TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个
      L, V+ [7 @/ V- I2 W2 W0 p9 H
  37.        
    . R) ~& w; }& K: l8 n4 N
  38.         TIM_Cmd(TIM1, ENABLE);  //使能TIMx                                                                                             " I# _+ X. e" N& j  i7 ]" @
  39. }   D, c4 {2 f: z, F4 _+ H! p7 h
复制代码

2 `! E& k6 n9 v# z3 Q: H/ P. o4 p, ^& p) p2 u/ s: E# |/ o  y
————————————————
) \) t* i% n. x. F, a: d- b! Y- x版权声明:_Amen
3 V4 Z* c6 i/ V7 P. t+ Y如有侵权请联系删除
) D, M4 P6 ?% X- X
6 X( {, D% F, u
; k9 o4 B1 b# e+ r3 x2 s1 K
收藏 评论0 发布时间:2023-5-14 17:40

举报

0个回答

所属标签

相似技术帖

官网相关资源

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