关于STM32的TIMx的更新周期计算问题请教。。。
以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
请问怎么理解?还是配置有问题?谢谢!
你是如何设置APB1CLK=36Mhz?
是否APB1CLK配置错了?
应该没错,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);
如下,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);
APB1CLK配错了,应该设置PCLK1 = HCLK/4
请看下面这个帖子中的有关“输出定时器时钟之前有一个乘法器”的注释:
STM32F10xx时钟系统框图:时钟是整个系统的脉搏
但为什么对应的CCx不受此影响呢?难道两者是分开的?
如何理解你的这句话?
“但为什么对应的CCx不受此影响”,是改为PCLK1 = HCLK/4后,什么都没有变吗?
我的意思是这样的。。。
改为PCLK1 = HCLK/4这个后肯定变化,但计算公式还是有疑问。
接上面的程序示例。
CC1的频率观察IO电平发现计算公式为36Mhz/(17+1)/8000=250Hz,4ms翻转一次,正确。
但IT_Update 的计算公式为72Mhz/(17+1)/16000=250Hz,对应的IO 4ms翻转一次,这样也和观察的一致
这样一个为36Mhz,一个为72Mhz,不同!
这样一个为36Mhz,一个为72Mhz,不同?
IT_Update 的计算公式为72Mhz/(17+1)/16000=250Hz,首先,CLK不能为72MHz,再者,都是4ms翻转,有何不同?
36MHz/8000与72MHz/16000的值不一样?
请问你在一楼的测试用的是哪个管脚?如何产生的输出?
4楼的测试用的是哪个管脚?如何产生的输出?
好像你是在中断中通过翻转I/O口产生的输出?
晕,被你们搞糊涂了。。。
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);
}
}
}
其它的管脚翻转类似。
被这个问题困挠几天了。
再看了下手册,发现俺搞错了,明天再看下
在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.
今天换成PB12,PB13,PB14,PB15,还是一样。。。
晕,麻烦版主再看看,还是没解决。。。
为什么计算时一个为36Mhz,一个为72Mhz呢?
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。
谢谢!观察到结果,那只能这样理解,我只是在。。。
看时钟分布图时和手册上完全没有这方面的说明,所以感觉有点郁闷。
其它方面,感觉手册上有的也说的含糊。
没有atmel的关于avr手册的好,个人认为。
APB1为36MHz 是AHB2分频得来的 即分频系数不是1 那么tim的时钟频率就变成APB1的2倍 只有在分频系数为1时tim的时钟频率才等于APH1的 你可以去看看时钟树