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

MCU实战经验+关于PWM模式

[复制链接]
刘斐 发布时间:2014-4-2 09:18
 首先,本人虽然初学STM32但极力反对一种误人子弟的观点:“对于STM32这样级别的MCU,有库函数就不用去看寄存器怎么操作的了!”
$ W+ h$ |! V/ t+ J好了,言归正传,最近总看到很多朋友对于PWM这个实验有很多的疑惑,所以我打算写这么一篇文字来阐述一下我个人对STM32的PWM的理解。
) f+ Y8 D: m0 _: ?4 n首先来说,你要使用PWM模式你得先选择用那个定时器来输出PWM吧!除了TIM6、TIM7这两个普通的定时器无法输出PWM外,其余的定时器都可以输出PWM,每个通用定时器可以输出4路PWM,高级定时器TIM1、TIM8每个可输出7路PWM,这里为了方便起见,我们选择与实验相同的TIM3的通道2来说明。选好定时器及通道后,下一步就是要使能定时器的时钟,根据需要看看是否需要重映射IO,然后就是配置输出PWM的IO及定时器,到这里原子的视频及例程都有详细的介绍,这里只需要提一点有些网友疑惑的TIM_TimeBaseStructure.TIM_ClockDivision = 0;这句话是什么作用?其实仔细看过技术手册后发现这句话与PWM输出实验其实是没关系的,这句话是设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的。至于其余部分,我就不再赘述。做完这些准备工作后,我就针对大多数朋友疑惑的地方——PWM模式的初始化设置做一个详细的阐述:先贴代码
2 S0 r% T5 B- m 
5 Q9 U* b- P. D) U1 Z     1       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
' g/ x& U# Q. A7 d. ]2 C6 j  x     2       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
# Q" Q% ~& T& A& D$ m     3       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
) K$ \5 v' A) B8 x; w$ i: p9 ]& {6 b     4       TIM_OC2Init(TIM3, &TIM_OCInitStructure);   //根据T指定的参数初始化外设TIM3 OC2
! J0 {/ x1 A/ [8 b  b1 {1 u& B     5       TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器,即TIM3_CCR2的预装载值在更新事件到来时才能被传送至当前寄存器中。2 D/ a# N  u+ E  F
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器,即TIM3_CCR2的预装载值在更新事件到来时才能被传送至当前寄存器中。; R0 r/ B6 u- C
这句话是说,CCR2中的预装载值何时被传送到当前的CNT寄存器中,这里我们选择的是当更新事件到来的时候才装载,追踪寄存器的设置可知,原来设置的是CCMR1的OC2PE,其实还有一种方式是立即装载看手册:
6 U. z$ _; _! k: i) POC1PE:输出比较1预装载使能(Output compare 1 preload enable)  位3 , i$ C. f( u+ t. ?5 T$ w" Z& u
0:禁止TIMx_CCR1寄存器的预装载功能,可随时写入TIMx_CCR1寄存器,并且新写入的数' I" H' @4 b( e# c: e0 w- v
值立即起作用。
  n9 v+ F+ u  q6 z& K) m1:开启TIMx_CCR1寄存器的预装载功能,读写操作仅对预装载寄存器操作,TIMx_CCR1的
4 e( n) B9 F4 a) g9 G" M( e4 J$ S预装载值在更新事件到来时被传送至当前寄存器中。5 z$ V% j  e; ?7 d' d

  j2 \+ x& z& G8 W% \# H     6       TIM_Cmd(TIM3, ENABLE);  //使能TIM3; }5 Y* G* Y# o* n! |# B0 |
这6句话就把PWM的通道配置好了,一句句来解释:
( w7 s5 Z: L, e% D7 f% f+ b8 O这里原子选择的PWM2模式,为什么选择的是PWM2模式呢?为什么不选择PWM1模式呢?两者又有什么区别呢?下面我们就一探究竟,PWM1和PWM2模式是由CCMR1的OC1M和OC2M来决定的,因为我们选择的是是通道2,所以设置的是OC2M,再看相关介绍
& V, r$ z1 ^: {4 s  bOC1M[2:0]:输出比较1模式(Output compare 1 enable)
; Q" V8 m. k8 M' W # Y. [( Z) f, e0 P0 K8 j/ L  l. e
110:PWM模式1- 在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否
8 [; E: {9 ]# s' {4 e则为有效电平(OC1REF=1)。
4 I% ?: U2 N2 ]  |4 Y+ ^9 k111:PWM模式2- 在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电* i1 Y" S( F3 o. M7 Q! e
平。
3 \+ o  S. {) i5 w0 i0 t/ J 
4 u% H4 L! |/ j8 T( |, t( K5 o8 R4 {* h 看到红色的“有效电平”了吧,那么这又是谁定义的呢?别急,再看手册,可知它是由CCER这个寄存器的CCxP来决定的这里是通道2,所以是CC2P,继续看介绍
+ m8 s4 ~( I1 x! X* y; S& vCC1P:输入/捕获1输出极性(Capture/Compare 1 output polarity)  位1 
' s* M& m5 w& a; bCC1通道配置为输出:( C! W8 e& b" T! V1 O
0:OC1高电平有效
& v# D) v  A1 p+ O9 W7 g( j3 F1:OC1低电平有效; \( o1 q  z& K$ a
现在很清楚了吧,又因为第3句,TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高,所以这里我们设置的CC2P是0,也就是默认的OC2高电平有效。这样第3句话也捎带着解释了,哈哈!由于我们的战舰板的LED是低电平亮,而刚开始的给CC2P用来设置占空比的led0pwmval为0它是小于等于TIM3_CNT的,也就符合TIMx_CNT>=TIMx_CCR1时通道2输出有效电平,也就是高电平,所以你把原子的例程原封不动的Down到板子里,会看到刚上电,LED灯是不亮的。现在这块明白了吧!若你觉得还是不爽,我就非得用PWM1模式,那也可以,就像有个网友说“我拿原子的PWM Code就改了一个PWM1模式,按原子讲的PWM1和PWM2的输出是相反的啊,可是我上电发现LED是常亮的啊?怎么回事啊,求解释啊。。。”我们来分析一下这位朋友的代码,他把PWM2改成了PWM1,别的什么都没动,那么现在符合“PWM模式1- 在向上计数时,一旦TIMx_CNT
收藏 1 评论0 发布时间:2014-4-2 09:18

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版