STM32 定时器(一)——定时器时间的计算 STM32的定时器是灰常NB的,也是灰常让人头晕的(当然是对于白菜来说的)。 STM32中的定时器有很多用法: (一)系统时钟(SysTick) 设置非常简单,以下是产生1ms中断的设置,和产生10ms延时的函数: - <div align="left">void RCC_Configuration(void)
- {
- RCC_ClocksTypeDef RCC_ClockFreq;
- SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置.
- RCC_GetClocksFreq(&RCC_ClockFreq);</div><div align="left">//SYSTICK分频--1ms的系统时钟中断
- if (SysTick_Config(SystemFrequency / 1000))
- {
- while (1); // Capture error
- }
- }</div><div align="left">void SysTick_Handler(void)//在中断处理函数中的程序
- {
- while(tim)
- {
- tim--;
- }
- }</div><div align="left">//调用程序:
- Delay_Ms(10);</div>
复制代码
当然,前提是要设置好,变量tim要设置成volatile类型的。 (二)第二种涉及到定时器计数时间(TIMx) - /*TIM3时钟配置*/
- TIM_TimeBaseStructure.TIM_Prescaler = 2; //预分频(时钟分频)72M/(2+1)=24M
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
- TIM_TimeBaseStructure.TIM_Period = 65535; //装载值18k/144=125hz
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
复制代码
定时时间计算:
- TIM_TimeBaseStructure.TIM_Prescaler = 2;
- //分频2 72M/(2+1)/2=24MHz
- TIM_TimeBaseStructure.TIM_Period = 65535; //计数值65535
- ((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+2)/72M)*(1+65535)=0.00273秒=366.2Hz */
复制代码
注意两点(来自大虾网,未经检验)
(1)TIMx(1-8),在库设置默认的情况下,都是72M的时钟;
(2)TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
是重复计数,就是重复溢出多少次才给你来一个溢出中断,
它对应的寄存器叫TIM1 RCR.
如果这个值不配置,上电的时候寄存器值可是随机的,本来1秒中断一次,可能变成N 秒中断一次,让你超级头大! STM32 定时器用于外部脉冲计数 因为用stm32f103c8作主控制器,来控制小车,小车的转速由两路光电编码盘输入(左右各一路).因此想到外部时钟触发模式(TIM——ETRClockMode2Config)。 可以试好好久,发现TIM1不能计数,到网上查了很久,也没有找到相关的文章,开始怀疑TIM1是不是需要特殊设置。经过很久的纠结,终于找到了问题——其实是我自己在GPIO设置的时候,后面的不小心覆盖了前面的了——没想到自己也会犯这么SB的事情。 现总结程序如下: 第一步,设置GPIO - <div align="left">GPIO_InitTypeDef GPIO_InitStructure;</div><div align="left">/* PA0,PA12-> 左右脉冲输入 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_12;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
- GPIO_Init(GPIOA, &GPIO_InitStructure);</div>
复制代码
注意:(1)stm32f103c8只有TIM1_ETR(PA12,Pin33),和TIM2_CH1_ETR(PA0,Pin10)两个可以用。其它更多管脚的芯片,有更多的可以输入(如100管脚的有4个可以输入的);(2)外部时钟输入与中断无关;(3)stm32f103c8的这个两个应用中,不需要重映射。 对于哪些需要重映射,参考数据手册。 第二步:设置RCC - <div align="left">RCC_ClocksTypeDef RCC_ClockFreq;</div><div align="left">SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置.
- RCC_GetClocksFreq(&RCC_ClockFreq);</div><div align="left">RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);</div>
复制代码
第三步,设置定时器模式 - <div align="left">void TIM1_Configuration(void) //只用一个外部脉冲端口
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;</div><div align="left">
- //配置TIMER1作为计数器
- TIM_DeInit(TIM1);</div><div align="left"> TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
- TIM_TimeBaseStructure.TIM_Prescaler = 0x00;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Time base configuration
- TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);</div><div align="left">TIM_SetCounter(TIM1, 0);
- TIM_Cmd(TIM1, ENABLE);
- }
- void TIM2_Configuration(void) //只用一个外部脉冲端口
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;</div><div align="left">
- //配置TIMER2作为计数器
- TIM_DeInit(TIM2);</div><div align="left"> TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
- TIM_TimeBaseStructure.TIM_Prescaler = 0x00;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Time base configuration
- TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);</div><div align="left">TIM_SetCounter(TIM2, 0);
- TIM_Cmd(TIM2, ENABLE);
- }</div>
复制代码
第四步,可以在主函数中读取计数器的值,其它的应用,就看具体的情况了。 - <div align="left">u16 COUN1=0;
- u16 COUN2=0;</div><div align="left">int main(void)
- {
- ChipHalInit();
- ChipOutHalInit();</div><div align="left">while(1)
- {
- COUN1=TIM1->CNT;
- COUN2=TIM2->CNT;
- }</div><div align="left">}</div>
复制代码
|