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

定时器TIM4PWM 2channel被FSMC复用后 模拟出PWM

[复制链接]
firstlege 发布时间:2015-1-21 15:15
本帖最后由 firstlege 于 2015-1-21 16:40 编辑
& T8 V2 c' A' ?& W0 ]7 ]9 \5 X7 p& D$ e" j1 ?
在用STM32f103zet6时用了外部内存 启用了FSMC,结果TIM4的channel2就不能输出PWM了  头疼!怎么办呢?
' A3 k( ~/ U& Z$ s想了一天有了点思路 并完成实现 这个方法也可以让任何一个IO口成为了PWM的输出口
+ {. b* N( d8 \
- G7 I! a2 W( c3 t4 O0 i1、思路原理:PWM无非是将一个引脚设置为输出高或低,输出高或低的时间是由比较器作出的,counter的值高于比较器的值引脚输出一个电平,counter的值低于比较器的值引脚输出一个电平,输出什么电平由你的设置决定。1 J* B* Q# T( g2 d9 [
2、实现必要:在STM32中可以设置比较器中断,这是最关键的。这也让实现成为可能。/ v2 q+ e/ L2 a# ^& p) i
说到这大家应该知道我想怎么做了吧 , 对,就是复用比较器的中断来实现。
) V. Q# ?; R' j1 ^) G, g$ m3、具体实现:
9 P( z5 v' N4 \6 \# Q3.1首先配置好TIM4  采用了中央计数模式 其它的简单设置一下,主要是设置开启中断。 如果你想要其它的设置 再看参考手册吧。
- c+ p& C5 k+ kvoid TIM4_PWM_Cfg(void)& K7 [/ [/ j( i9 x+ [$ T" n
{2 W) d* H$ Y" n# H! T9 P# k* I/ V
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;0 [* w, b" F$ s- v: E# _
    TIM_OCInitTypeDef  TIM_OCInitStructure;* w* h9 c5 {$ r5 f7 o
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);3 O4 F. E" L2 `
  
. O  l8 ^/ d$ R' S    TIM_DeInit (TIM4);2 S% m! @6 d" f) U% O5 k
    TIM_TimeBaseInitStruct.TIM_Period = 3999;//计数值  这个数值与中断中对应。- B, t" g$ z1 W5 r8 j! r$ ?9 \9 W
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned3;  ; g$ C& A: r# x0 s/ D8 N5 B
    TIM_TimeBaseInitStruct.TIM_Prescaler = 17;//18预分频 主频72M( f! _9 U. Y3 `9 `6 G6 e& n
    TIM_TimeBaseInitStruct.TIM_ClockDivision  = TIM_CKD_DIV1;// 时钟不分频
$ z2 r* h9 s; d8 w: Y; ~! q    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
. x+ W5 O3 s+ l: \    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
, u4 ?& y; O  c' z1 B    TIM_SetCounter(TIM4,0x0);* A8 w$ Q2 C1 o# j
  
0 E% _9 o/ x$ T    TIM_ITConfig(TIM4,TIM_IT_CC2,ENABLE);//设置2channel中断
9 `- r1 a) t9 ^, g& j' i5 m  [8 Y* ]8 F5 w0 C) n, m
    //初始化TIM4 Channel1 PWM模式     
( f7 p, E6 l" z    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式23 u' ?1 Z& X0 Y! f4 N  u+ X
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能9 p7 ?. L: T  t2 l; U5 s+ |
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
5 [7 a. y5 m: D/ }/ i! j   
9 C: Q# R1 j8 X3 b% ^0 N. ]) y    TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC1# u1 |9 b+ J' y4 |6 P3 e
//  TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC2'! |  T, i, D# @  z" T
  TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC3
# S' l0 i. s- m' x" G4 p  TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4OC4
% V' B/ L& [4 X8 L2 i  
: f* ^. V8 w5 J' N6 V3 t# L//  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; //比较输出使能
# k$ L3 M" \# s" K' o( y- {//  TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2'
/ s% w5 k6 ~8 v2 t7 v1 @5 y( f! O7 K  5 ~4 D* d: M0 ?
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR1上的预装载寄存器  
6 Q- Q, f( |! p1 Y* e7 m: _6 K( i, M//    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR2上的预装载寄存器
  q) k, G% F4 C4 U/ e6 J7 {5 T$ S% ~    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR3上的预装载寄存器  
- O; @4 ]" z8 I& e0 ?3 g) G    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR4上的预装载寄存器   
+ H! n3 {! s- Q) [3 g, f% D  TIM_Cmd(TIM4,ENABLE);/ M4 J) S; K8 j. t( R6 f
    8 r; f& E6 Z9 j; @  j) F
}! t* e- `% F, e1 e8 i% c
3.2   中断中要做的事 注意的是:如果比较器值设置高于cnt的最大值时 溢出时也会中断, PWM是输出的是设定的电平 我这里采取了不改变操作* d0 M5 F3 B% |4 S! G7 y# m* D
void TIM4_Interrupt(void)+ E( C6 h5 |: T) _: v
{
7 T# @% T4 h* }6 Z  c" I8 j  extern CPU_INT16U CompreValue;//   用这个函数设置的比较值 TIM_SetCompare2(TIM4,CompreValue);  
2 z# p. \; I' i! z2 J  CPU_INT16U Tcounter ;$ H) K8 V* A4 \  P. Z1 r
  Tcounter = TIM_GetCounter(TIM4);
# P& |) \6 F7 f+ i  if((TIM_GetITStatus(TIM4,TIM_IT_CC2) == SET) )+ e2 G9 }8 @( Y8 m; {* O
  {
5 r# h+ T3 u9 F0 `- p; \7 m1 P+ q    if(LED_CompreValue[1] < 3900  ) // 4000 - 100
: d( g( f  D9 q    {
) ~& q8 G) _, K# ^+ Z1 ?# j: r      if(Tcounter > LED_CompreValue[1]) . a  R/ |: }" \0 }, p
      {
# g" G+ k: n. j1 ~6 o( R         LED_ON;//设置引脚高电平5 }5 m" D% b7 W2 F' |; E
      }
6 h/ W7 B1 U2 U9 D" W! I      else
) H; y# z9 W8 f/ A+ i      {& U  U" ?$ [4 {' k  n1 {% i
        LED_OFF;2 |: x4 `8 c  D/ V% d9 _3 I4 ^; ~
      }
0 M! w: J9 X8 A/ d$ z% `2 S  o" L    }
. }0 }4 y( B! ~; S( ~( @1 F* {% ]  }
2 p6 D/ o. \6 x' f* `7 Y5 d    TIM_ClearITPendingBit(TIM4,TIM_IT_CC2);
/ a3 I+ K/ n( v1 k7 b$ \9 b    TIM_ClearFlag(TIM4,TIM_FLAG_CC2);! M+ e( f: L: m* F. v  j7 J5 E
  
! _' O# r2 U% q1 k; j) V}
5 X6 d, G6 c. a$ A' w. d: P2 L这里是祥实现的一个方法 50是当你设置为3950到4000时这个时候就会有溢出了中断产生了 在溢出中断时 我需要保持原来的电平
4 c+ x, }4 F* L& E! Z希望大家有更好的设置方法
; O/ z& E2 O" r) w3 o: u
( M) ?7 |# r  @! {4 }5 ]0 @; O5 r4、最后 希望大家能多给的意见 怎么实现理简单
" {, N; Y; U3 H2 {# `6 ~. q. U9 n+ A: U7 g2 g  j: Z1 Q
. i. i% U) \" j: m
1 n' c+ o+ D8 [
赞 收藏 评论1 发布时间:2015-1-21 15:15

举报

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