打印

定时器不同通道工作于不同方式的疑问

[复制链接]
3047|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
a1z26|  楼主 | 2009-4-14 11:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


官方发布的例程都是一个定时器只工作于一种方式的,我现在让TIM2的两个通道分别工作于不同的方式,得到的实际结果与用两个定时器工作于这两种方式得到的结果有差别,我没有找到相关的解释,请香版主指教。

以下为代码和相关说明。

/* TIM2CLK = 36 MHz, Prescaler = 0x0, TIM2 counter clock = 36 MHz */

/* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

  /* Output Compare Toggle Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;  
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

  TIM_OC2Init(TIM2, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);

  TIM_ARRPreloadConfig(TIM2, ENABLE);
                                 
  /* TIM IT enable */
  TIM_ITConfig(TIM2,TIM_IT_CC2, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM2, ENABLE);

通道一工作于PWM方式,输出频率应该是 TIM2 counter clock/TIM_Period =549.316 Hz

通道二工作于输出比较方式,输出频率应该是TIM2 counter clock/CCR2_Val =4394.53 Hz

实测的结果:通道一输出频率没错,但是通道二输出频率却是2197.37 Hz,少了一半,不知道这个2197.37是怎么得到的? 
沙发
香水城| | 2009-4-14 12:01 | 只看该作者

你的计算好像有问题

通道二的输出频率也应该是TIM2 counter clock/TIM_Period/2 = 274.658Hz才对。

你选择的是输出比较,并在比较成功后翻转输出。

计数器是循环地从0计数至65535,当计数至CCR2_Val时输出翻转,经过65536次计数后,下次计数至CCR2_Val时再次翻转输出,既半周期为65536/36MHz。

不知道你的理解是否如此?

使用特权

评论回复
板凳
a1z26|  楼主 | 2009-4-14 13:15 | 只看该作者

问题已解决,多谢

香主,是你的计算出问题了。

工作于PWM方式时,计数到CCR1_Val时输出翻转一次,计数到65535时再翻转一次,形成一个完整的周期。频率为 TIM2 counter clock/65535 = 549.316 Hz


我的问题也解决了。工作于输出比较方式是有中断的。程序如下。第一次计数到CCR2_Val输出翻转,第二次是计数到 (CCR2_Val+CCR2_Val)时翻转,两次翻转为一个完整周期。频率为 TIM2 counter clock/CCR2_Val/2 = 2197.37 Hz.

  if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
  {
     TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
     capture = TIM_GetCapture2(TIM2);
     TIM_SetCompare2(TIM2, capture + CCR2_Val);
  }    

使用特权

评论回复
地板
香水城| | 2009-4-14 15:04 | 只看该作者

哈哈,关键是这个中断处理

我在2楼说的是工作于输出比较方式的通道2,并且没有这个中断处理的情况。

问题解决了就好。

使用特权

评论回复
5
leon0001| | 2009-4-23 17:28 | 只看该作者

的确是

没有使能中断时,应该是counter clock/TIM_Period 
使能时,为 counter clock/TIM_Period/2

使用特权

评论回复
6
渤海三叠浪| | 2009-5-7 17:24 | 只看该作者

关于3楼输出比较方式toggle

3楼说:工作于输出比较方式是有中断的。程序如下。第一次计数到CCR2_Val输出翻转,第二次是计数到 (CCR2_Val+CCR2_Val)时翻转,两次翻转为一个完整周期。频率为 TIM2 counter clock/CCR2_Val/2 = 2197.37 Hz.
----------------------------------------------------------

在使能中断时,我想:“第一次计数到CCR2_Val输出翻转”的时刻发生中断的了!那么“第二次是计数到 (CCR2_Val+CCR2_Val)时翻转”也发生中断了么?

还有:计数器是什么时候停止的?是计数到65535才停止的么?

65535与CCR2_Val的关系是什么?比如说是不是65535>2倍的CCR2_Val

有时候 如果不取65535这个值时,运行几个周期后,电平就一直为高 或 一直为低!

使用特权

评论回复
7
Tiger5| | 2009-5-7 17:31 | 只看该作者

为什么呢?

有时候 如果不取65535这个值时,运行几个周期后,电平就一直为高 或 一直为低!

使用特权

评论回复
8
渤海三叠浪| | 2009-5-7 17:35 | 只看该作者

回楼上 不清楚!!!

使能中断时候,

比如TIM_Period = 60000
CCR1_Val = 30000

则出现6个高电平后 然后 一直为高 !!! 这6个高电平还不一样宽!!!原因不清楚!!!

使用特权

评论回复
9
渤海三叠浪| | 2009-5-7 17:43 | 只看该作者

禁止中断的情况我可能有点清楚!!!

输出比较方式toggle ,禁止中断时:
计数到Period则重新计数,每计数到CRR1_Val则翻转,周期为2Period/TIM2 counter Clock.




crr1_VAL只需要<=Period<=65535都是这个周期。








==========================================

那么输出比较方式toggle ,使能中断时是怎么个情况呢??
谁能说下!!!!???

使用特权

评论回复
10
a1z26|  楼主 | 2009-5-8 08:52 | 只看该作者

如下

使能中断就是在中断里重新设置下次的触发值

使用特权

评论回复
11
渤海三叠浪| | 2009-5-8 12:20 | 只看该作者

输出比较方式toggle 不禁止中断 我也有点懂了!!!

我在8楼说:
------------------------
使能中断时候,

比如TIM_Period = 60000
CCR1_Val = 30000

则出现6个高电平后 然后 一直为高 !!! 这6个高电平还不一样宽!!!原因不清楚!!!
-----------------------------

这个例子有点难!!!


弄个简单点的例子解释一下!!
如果 比如TIM_Period = 59999
CCR1_Val = 30000

那么就是ARR=59999 也就是说计数器最大只能计数到59999,达不到30000+30000, 于是只能出现一个高电平了

============所以最好将period设置为65535 ,如果设置为别的值,就得在中断程序的TIM_SetCompare1(TIM2, capture + CCR1_Val );之前添个语句

===============我说的对不对啊???

使用特权

评论回复
12
渤海三叠浪| | 2009-5-8 17:35 | 只看该作者

恩 楼上说的对

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

214

帖子

0

粉丝