本帖最后由 springvirus 于 2017-11-23 15:21 编辑
本例中使用的207具体型号和链接如下:
http://www.st.com/content/st_com ... x7/stm32f207zg.html
对于STM32F207的timer,如何对定时器进行初始化配置,以得到想要的定时时间?
首先先来看看系统的几个重要时钟的频率值 经调用RCC_GetClocksFreq(&RCC_Clocks); 仿真后,看到系统时钟为
SYSCLK_Frequency 120 000000
HCLK_Frequency 120 000000
PCLK1_Frequency 30 000000
PCLK2_Frequency 60 000000
可以看到AHB(HCLK)为120MHz,APB1(PCLK1)为30MHz,APB2(PCLK2)为60MHz
问题来了, 这些时钟是从哪里来的,为什么是这些值? 在Reference Manual的P85上,有Figure9. Clock tree 可以看到,HSE OSC(高速外部时钟晶振)从OSC_OUT和OSC_IN引入,此例中接入25MHz时钟晶振。 之后到达PLL模块,通过对其分频因子M N P Q进行配置以得到不同频率的时钟。
在启动文件中的汇编代码的Reset_Handler段可以看到,系统重启后,调用了SystemInit函数 (此函数位于System_tm32f2xx.c中),其中有4个函数调用,分别为
RCC_HCLKConfig(RCC_SYSCLK_Div1); //不分频
RCC_PCLK1Config(RCC_HCLK_Div4); //4分频
RCC_PCLK2Config(RCC_HCLK_Div2); //2分频
RCC_PLLConfig(RCC_PLLSource_HSE, PLL_M, PLL_N, PLL_P, PLL_Q);
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
#define PLL_N 240
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
通过这样的配置后
SYSCLK = (25/25)*240/2 = 120MHz
HCLK = 120MHz
PCLK1 = 30MHz
PCLK2 = 60MHz
TIM2到TIM7的时钟都源自APB1,现以TIM3举例 从时钟树可以看到,从APB1到TIMER CLK中间还有个倍频器,
if(APBx presc = 1)
*1
else
*2
这里APB1 CLK对HCLK进行了4分频,所以倍频器对TIMER的输入时钟进行了2倍倍频,输入 Ftimer = 60MHz的时钟
对定时器配置时涉及到Prescaler Register(TIMx_PSC)和Auto-Reload Register(TIMx_ARR) 这里依旧有分频器和重载计数器
定时器计数一次的频率为(Ftimer)/(PSC),时间为(PSC)/(Ftimer)
定时器定时时长为 (ARR)*(PSC)/(Ftimer)
所以这里若需定时1ms,定时器的配置为
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
void TIM3_Int_Init(u16 arr,u16 psc)
主程序调用以下函数,就可实现定时1ms
TIM3_Int_Init(399,149);
思路清楚后,写程序就轻松了 (^_^)
|