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

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

[复制链接]
firstlege 发布时间:2015-1-21 15:15
本帖最后由 firstlege 于 2015-1-21 16:40 编辑

在用STM32f103zet6时用了外部内存 启用了FSMC,结果TIM4的channel2就不能输出PWM了  头疼!怎么办呢?
想了一天有了点思路 并完成实现 这个方法也可以让任何一个IO口成为了PWM的输出口

1、思路原理:PWM无非是将一个引脚设置为输出高或低,输出高或低的时间是由比较器作出的,counter的值高于比较器的值引脚输出一个电平,counter的值低于比较器的值引脚输出一个电平,输出什么电平由你的设置决定。
2、实现必要:在STM32中可以设置比较器中断,这是最关键的。这也让实现成为可能。
说到这大家应该知道我想怎么做了吧 , 对,就是复用比较器的中断来实现。
3、具体实现:
3.1首先配置好TIM4  采用了中央计数模式 其它的简单设置一下,主要是设置开启中断。 如果你想要其它的设置 再看参考手册吧。
void TIM4_PWM_Cfg(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  
    TIM_DeInit (TIM4);
    TIM_TimeBaseInitStruct.TIM_Period = 3999;//计数值  这个数值与中断中对应。
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned3;  
    TIM_TimeBaseInitStruct.TIM_Prescaler = 17;//18预分频 主频72M
    TIM_TimeBaseInitStruct.TIM_ClockDivision  = TIM_CKD_DIV1;// 时钟不分频
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
    TIM_SetCounter(TIM4,0x0);
  
    TIM_ITConfig(TIM4,TIM_IT_CC2,ENABLE);//设置2channel中断

    //初始化TIM4 Channel1 PWM模式     
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
   
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC1
//  TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC2'
  TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC3
  TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4OC4
  
//  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; //比较输出使能
//  TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2'
  
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR1上的预装载寄存器  
//    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR2上的预装载寄存器
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR3上的预装载寄存器  
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR4上的预装载寄存器   
  TIM_Cmd(TIM4,ENABLE);
   
}
3.2   中断中要做的事 注意的是:如果比较器值设置高于cnt的最大值时 溢出时也会中断, PWM是输出的是设定的电平 我这里采取了不改变操作
void TIM4_Interrupt(void)
{
  extern CPU_INT16U CompreValue;//   用这个函数设置的比较值 TIM_SetCompare2(TIM4,CompreValue);  
  CPU_INT16U Tcounter ;
  Tcounter = TIM_GetCounter(TIM4);
  if((TIM_GetITStatus(TIM4,TIM_IT_CC2) == SET) )
  {
    if(LED_CompreValue[1] < 3900  ) // 4000 - 100
    {
      if(Tcounter > LED_CompreValue[1])
      {
         LED_ON;//设置引脚高电平
      }
      else
      {
        LED_OFF;
      }
    }
  }
    TIM_ClearITPendingBit(TIM4,TIM_IT_CC2);
    TIM_ClearFlag(TIM4,TIM_FLAG_CC2);
  
}
这里是祥实现的一个方法 50是当你设置为3950到4000时这个时候就会有溢出了中断产生了 在溢出中断时 我需要保持原来的电平
希望大家有更好的设置方法

4、最后 希望大家能多给的意见 怎么实现理简单



收藏 评论1 发布时间:2015-1-21 15:15

举报

1个回答
党国特派员 回答时间:2015-1-22 11:14:30
1.png

所属标签

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