打印

关于STM32的TIMx的更新周期计算问题请教。。。

[复制链接]
4882|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lixun00|  楼主 | 2008-3-27 00:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以TIM3为例,假如APB1CLK=36Mhz,
  TIM_TimeBaseStructure.TIM_Period = 8000;
  TIM_TimeBaseStructure.TIM_Prescaler = 17;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

则更新频率为:36000000/(17+1)/8000Hz?
但事实上测得的管脚频率为72000000/(17+1)/8000Hz
请问怎么理解?还是配置有问题?谢谢!
沙发
香水城| | 2008-3-27 08:29 | 只看该作者

你是如何设置APB1CLK=36Mhz?

是否APB1CLK配置错了?

使用特权

评论回复
板凳
lixun00|  楼主 | 2008-3-27 09:07 | 只看该作者

应该没错,TIM3的CC1的频率正确,代码如下

/* HCLK = SYSCLK ,AHB时钟=SYSCLK*/
RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);

/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);

/* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }

/* TIM2,3 clocks enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

使用特权

评论回复
地板
lixun00|  楼主 | 2008-3-27 09:10 | 只看该作者

如下,TIM3 cc1频率正确

/* only counter overflow/underflow generate U interrupt */

  TIM_UpdateRequestConfig(TIM3,TIM_UpdateSource_Regular);
  
  //Output Compare Timing Mode configuration: Channel1 
  //36Mhz/(17+1)/8000=250hz
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_Channel = TIM_Channel_1;
  TIM_OCInitStructure.TIM_Pulse = 8000;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInit(TIM3, &TIM_OCInitStructure);

  //TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
  
  //TIM IT enable 
  TIM_ITConfig(TIM3,TIM_IT_Update | TIM_IT_CC1, ENABLE);
  
  
  // TIM enable counter 
  TIM_Cmd(TIM3, ENABLE);

使用特权

评论回复
5
香水城| | 2008-3-27 11:12 | 只看该作者

APB1CLK配错了,应该设置PCLK1 = HCLK/4

请看下面这个帖子中的有关“输出定时器时钟之前有一个乘法器”的注释:

STM32F10xx时钟系统框图:时钟是整个系统的脉搏

使用特权

评论回复
6
lixun00|  楼主 | 2008-3-27 13:16 | 只看该作者

但为什么对应的CCx不受此影响呢?难道两者是分开的?

使用特权

评论回复
7
ST_ARM| | 2008-3-27 15:38 | 只看该作者

如何理解你的这句话?

“但为什么对应的CCx不受此影响”,是改为PCLK1 = HCLK/4后,什么都没有变吗?

使用特权

评论回复
8
lixun00|  楼主 | 2008-3-27 17:14 | 只看该作者

我的意思是这样的。。。

改为PCLK1 = HCLK/4这个后肯定变化,但计算公式还是有疑问。

接上面的程序示例。

CC1的频率观察IO电平发现计算公式为36Mhz/(17+1)/8000=250Hz,4ms翻转一次,正确。

但IT_Update 的计算公式为72Mhz/(17+1)/16000=250Hz,对应的IO 4ms翻转一次,这样也和观察的一致

这样一个为36Mhz,一个为72Mhz,不同!

使用特权

评论回复
9
ST_ARM| | 2008-3-27 17:52 | 只看该作者

这样一个为36Mhz,一个为72Mhz,不同?

IT_Update 的计算公式为72Mhz/(17+1)/16000=250Hz,首先,CLK不能为72MHz,再者,都是4ms翻转,有何不同?
36MHz/8000与72MHz/16000的值不一样?

使用特权

评论回复
10
香水城| | 2008-3-27 18:20 | 只看该作者

请问你在一楼的测试用的是哪个管脚?如何产生的输出?

4楼的测试用的是哪个管脚?如何产生的输出?

好像你是在中断中通过翻转I/O口产生的输出?

使用特权

评论回复
11
lixun00|  楼主 | 2008-3-27 19:03 | 只看该作者

晕,被你们搞糊涂了。。。

9楼我没说不同,但是总时钟不同啊?一个是用72Mhz作被除数,另一个为36Mhz。

1。9楼说“首先,CLK不能为72MHz”

2。手册上说APB1CLK,max 为 36Mhz

3。5楼又说:
  “输出定时器时钟之前有一个乘法器,它的操作不是由程序控制的,是由硬件根据前一级的APB预分频器的输出自动选择,当APB预分频器的分频因子为1时,这个乘法器无作用;当APB预分频器的分频因子大于1时,这个乘法器做倍频操作,即将APB预分频器输出的频率乘2,这样可以保证定时器可以得到最高的72MHz时钟脉冲。”

回10楼:

我用PC12,13,14,15,这个也有关系吗?

下面这个为示例程序:

/* Configure PC.12 -- PC.15 as Output push-pull  : COM1~4 */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

void TIM3_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_15) )
    {
      GPIO_ResetBits(GPIOC,GPIO_Pin_15);
    }
    else
    {
      GPIO_SetBits(GPIOC,GPIO_Pin_15);
    }
  }
}

其它的管脚翻转类似。

被这个问题困挠几天了。



使用特权

评论回复
12
lixun00|  楼主 | 2008-3-27 21:22 | 只看该作者

再看了下手册,发现俺搞错了,明天再看下

在p24:

   PC13, PC14 and PC15 are supplied through the power switch, and so their use in output mode is limited: 

they can be used only in output 2 MHz mode with a maximum load of 30 pF and only one pin can be put in output mode at a time.

使用特权

评论回复
13
lixun00|  楼主 | 2008-3-28 08:47 | 只看该作者

今天换成PB12,PB13,PB14,PB15,还是一样。。。

使用特权

评论回复
14
lixun00|  楼主 | 2008-3-28 15:41 | 只看该作者

晕,麻烦版主再看看,还是没解决。。。

为什么计算时一个为36Mhz,一个为72Mhz呢?

使用特权

评论回复
15
lut1lut| | 2008-3-28 17:29 | 只看该作者

lz的代码配置和所观察到的现象是可以解释的

1.TIM2的时钟是72M,经过prescaler(17),得到CK_INT=72MHz/(17+1)=4MHz 。

2. CK_INT=4MHZ的情况下,设置8000的reload,则每8000/4MHZ=2ms产生一次update中断
   在这个中断里,lz分别设置PC.15为高或者低电平。这样,这个PC.15上看到的方波的周期就是应该为4ms(高电平2ms,低电平2ms,如此交替下去)


3. TIM2作为输出比较,设置pulse为8000。当以CK_INT为基准频率计数到8000时,一方面产生了update中断,一方面,输出比较引脚toggle其电平。由此可知,这个引脚输出的方波的周期仍然是4ms。

使用特权

评论回复
16
lixun00|  楼主 | 2008-3-28 20:37 | 只看该作者

谢谢!观察到结果,那只能这样理解,我只是在。。。

看时钟分布图时和手册上完全没有这方面的说明,所以感觉有点郁闷。
其它方面,感觉手册上有的也说的含糊。

没有atmel的关于avr手册的好,个人认为。

使用特权

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

本版积分规则

56

主题

683

帖子

3

粉丝