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

提高stm32f103c8t6的PWM精度

[复制链接]
xiongjx 发布时间:2020-8-16 19:05
刚从51转过来,不想投入太多的资金,选择某宝的小蓝板(bluePill),这个板可能是最便宜的了(7.6元包邮)。初步测试一下时钟,定时器,中断,DMA什么的。到ADC还比较满意,DAC就晕了(这个芯片没有DAC)。于是采用PWM出模拟值。先初始化;
+ x. [# G" a  R5 [2 H4 g+ e' ~3 u3 q9 [  M; h- E4 V0 y5 @
void TIM1_PWM_Init(u16 arr,u16 psc)2 ?2 z. [' I9 J4 O
{  / {% t/ o! e* s" c8 l( y! T0 ]
        GPIO_InitTypeDef GPIO_InitStructure;                              
$ s# _4 X* P9 d        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;4 c2 o2 d9 ~. e" g/ h3 x3 j3 T) X4 M
        TIM_OCInitTypeDef  TIM_OCInitStructure;% m' M- a  r5 i3 R* Y
; c6 r: L9 y/ @, x5 J/ ?
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);     //
( j% c7 m# G# L8 f3 t- q         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能
% S. U2 j0 H( ^; Z& q. f8 j# z7 o# ?" {9 I& p9 b5 H6 h" k% V1 p
   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
& E. P# J7 P  l  N* B8 `        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1         //PA8是PWM输出
2 f- v/ F! K: P! G/ u, K( d* _6 K        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;            //复用推挽输出
9 g8 `# I( M/ }$ [9 u# G        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
* M. p3 Z; a5 b+ U, d        GPIO_Init(GPIOA, &GPIO_InitStructure);
% W+ I# _2 l/ s1 I7 N5 ^, {5 O3 U   //定时器初始化        9 @: g! K9 X2 p! x5 l1 b/ ^; n  L- O
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值6 L0 P- w* s5 ^1 H
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 ' C' p* J* w" `8 P6 t
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
- V, g  N' F; B# c9 z" h        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式2 g& [; o3 h3 |- B( Y
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位1 L, v) `0 y( C; E( f
   //初始化输出比较参数2 Y, B6 f* [8 _' N0 U. t. f
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
% R( m( _' Q. e6 l1 H        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能5 S; }# [/ H4 q$ b
        TIM_OCInitStructure.TIM_Pulse = 1350; //设置待装入捕获比较寄存器的脉冲值 1350--Low  200--High! E  J3 e3 c2 ?5 M+ Z. }
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
. r' r/ E8 r  D5 F- X- J        TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx3 a! z2 C! }6 O4 D
          //使能预装载寄存器, O$ P. L4 _' Q) U
  TIM_CtrlPWMOutputs(TIM1,ENABLE);            //MOE 主输出使能。该函数操作的是TIM1 刹车和死区寄存器该函数并不是适合所有定时器的,
* i8 b0 U( L. H4 |                                        //只有部分定时器可以使用,例如,在stm32f0中,可用于TIM1, TIM15, TIM16以及TIM17,; m$ Q8 X7 M5 K: H8 W: i! Q) F- D
                                        //在stm32f1中可用于TIM1, TIM8,TIM15, TIM16以及TIM17,如果在其它定时器中使用,
9 d1 Z! J8 r$ e$ m3 ]                                        //可能会使STM32停留在某一处而无法继续执行下面的任务8 ]0 S( r& P, D+ G: b
        TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);  //CH1预装载使能         , K2 h7 i' X( x$ |
  TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器# ?) ~6 H* E# f  {
        TIM_Cmd(TIM1,ENABLE);  //使能TIM15 ?3 @$ T& `  t; t
1 n$ b; s1 P8 B( w6 G& O
}
' V" E0 {. X3 w& @. p" L
; Q5 u/ A3 v: ^! k9 N+ K4 Z5 M3 D# v# G! D) \6 i8 Z

/ z( U, C6 n2 B4 C& [然后在MAIN()中:4 @3 ?4 k  t) Q( j" }# P3 H, x; g  a
int main()' q% ~0 M% u9 J& B: h  G8 `( \' n
{0 V4 L3 q5 c/ H3 I) a" y
TIM_SetCompare1(TIM1,1500);  //占空比=1000 / (2999+1)*100% = 50%7 T! R1 V0 H& ]( n0 _& P! x$ O1 x
while(1)
& Z( L  y+ b1 {, r6 m9 [{
1 k. o4 z7 ?6 q; u* V: ^   ;
/ P8 a3 n+ H0 T6 X9 l}
$ P; a- u2 P7 T& ~! @2 m! Y}
" W' K' D+ t( H: M0 L$ |% p可以在PA8看到PWM波形。一顿操作:
2 k2 q) y9 F- T! o9 U# @ 1.jpg
" H" L" Y- E3 {2 U. \) z$ s+ V9 b发现DAC输出精度,线性都不好。也不知道是运放的问题还是其他。网上一顿搂,改进PWM输出模拟量。
0 X6 I: d% M6 J# S# j( l 2.jpg 6 o* U6 g0 Y, o
效果好了不少。线性还是不好。
, t9 ]' Y( c' z于是将DAC又返回ADC采集加数字闭环。
' a' g! @0 O- @) d$ q5 \dac_d是期望输出的值,dac_out是送去PWM转换的值,vi是从DACOUT那里取出的电压ADC值。下面程序是数字反馈% I; y' i3 _. u" S
void dac_auto(void)
- g7 f- y4 S2 }. f# F0 x{
4 f9 V" a+ A- X9 _$ I7 ]        u16 tmp;4 S3 R3 W" u. h8 f/ l4 V
       if((short int)vi>(dac_d+1))- X$ L/ y6 L8 E2 l+ L( v& O
            {. ~! k4 Z2 J' J" E+ ]
                tmp=(short int)vi-dac_d;: J$ G, x7 J9 i1 f
                if(tmp>=220)dac_out-=170;# H: p; P! C$ Q/ e
                else if(tmp>=100)dac_out-=80;
( e* G7 f+ s2 h; e                else if(tmp>=50)dac_out-=45;9 C7 p0 r( g( i+ y
                else if(tmp>=10)dac_out-=6;
8 C; c, i# u, l4 F: r0 J                else if(tmp>=5)dac_out-=2;; R5 N% R' q( m) {0 j* R
                else dac_out-=1;' N! Z! d8 D1 B
             }5 D  A; p6 l/ C* \# m6 u
        else if((short int)vi<(dac_d-1))' Y* W8 Q, o: M% `7 _1 c
            {6 `3 y3 L9 n5 t$ ~+ ^7 j
                tmp=dac_d-(short int)vi;
8 {9 b% \+ m. K$ k                if(tmp>=220)dac_out+=110;, P" I$ p- Q2 s4 a5 C, F
                else if(tmp>=100)dac_out+=55;) `+ Q! o* p. B
                else if(tmp>=50)dac_out+=35;$ T; ~" }0 x0 u- T- H
                else if(tmp>=10)dac_out+=7;
, |$ [' L) o! W  p! Y! n* h                else if(tmp>=5)dac_out+=3;
. L' m0 `( g+ |3 Y5 l+ ]$ w                else dac_out+=1;
+ R5 c4 |: I$ j' J            }
. ?' C0 o8 P' D0 L7 _. v                if(dac_out>=2999)dac_out=2999;
7 J: R; V7 N* D8 y                if(dac_out<=1)dac_out=1;
  U. P! W5 O; S( d9 h9 a2 Y                TIM_SetCompare1(TIM1,dac_out);" S+ N" j, r5 c* a# G8 f0 l, Z# O4 t
        filter();
: Z: R# W' h9 @}
, c. c- g" z# }1 |) i0 Z- F8 C
3 E1 p' O# E  F9 {. R" e* [经过处理,PWM输出的最终电压值波动小于1毫伏。1 s  @4 j! {! b4 ]5 X% m+ `! j" K0 H
收藏 评论0 发布时间:2020-8-16 19:05

举报

0个回答

所属标签

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