微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STM32定时器中断

STM32定时器中断

时间:10-02 整理:3721RD 点击:
STM32的定时器是个强大的模块,定时器使用的频率也是很高的,定时器可以做一些基本的定时,还可以做PWM输出或者输入捕获功能。

        先看个图:


        上图说明了,STM32中相关模块的总线结构,而这里用于测试的TIM3是接在了APB1上,APB1最大频率是36MHz,是算个低速的总线。

        当APB1 的预分频系数为1 时,这个倍频器不起作用,定时器的时钟频率等于APB1 的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8 或16)时,这个倍频器起作用,定时器的时钟频率等于APB1 的频率两倍。

        也就是,当APB1不分频,TIM3的时钟速度为36MHz,当2分频是,APB1变成18MHz,但是TIM又会倍频,即TIM时钟等于18*2=36MHz。

        好了,参考编程一般步骤:

        1.系统初始化,主要初始化时钟等。

        2.GPIO初始化,用于LED,有了灯就便于观察了。

        3.TIM3的配置。

        4.NVIC的配置。

        5.编写中断服务函数。

        首先,系统初始化直接使用SystemInit()函数即可,但是分析汇编启动代码,发现已经做了初始化了!所以就不去瞎凑热闹了。可以省去。

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
     IMPORT  __main
     IMPORT  SystemInit
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

        当然别忘记了先把GPIO和TIM模块的时钟给使能了!TIM3在APB1上,GPIO在APB2上。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

        第二步就是编写GPIO了,参考前面的点灯文章就明白了。代码如下:

/**led**/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);

        第三步,编写TIM3的配置。这里说一下定时频率的计算方法:Frequency=(SYSCLK/(Prescaler+1)) /(Period+1);

        SYSCLK即为系统时钟,这里使用72MHz,Prescaler为时钟预分频数,Period即为计数器值。

        所以要得到1S的定时,即1Hz的频率,Period=1999,Prescaler= 35999,计算得出正好是1Hz,当然这里的配置关系不是随便来的。

/**tim3**/
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Period=1999;    //自动重装载寄存器的值
TIM_TimeBaseStructure.TIM_Prescaler= 35999;   //时钟预分频数
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_div1; //采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除溢出中断标志
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3, ENABLE); //开启时钟

        第四步,配置NVIC。

/*nvic*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //通道TIM2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

        最后呢编写个终端服务函数,每一次中断就变换一次LED的电平,也就是亮灭,这里用软件仿真一下看看LED端口波形即可。

void TIM3_IRQHandler(void)
{
         static u8 sign = 1;
         if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) == SET)
         {
                  TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);
                  if(sign)
                  {
                           sign = 0;
                           GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);
                  }
                  else
                  {
                           sign = 1;        
                           GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);
                  }
         }
}

        实际,仿真波形如下:


顶顶顶顶顶顶顶顶顶顶顶顶

顶顶顶顶顶顶顶顶顶顶顶顶

顶,学习中,希望能迎头赶上!

顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

1. #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
2. #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
3. #define PERIPH_BASE ((uint32_t)0x40000000)

学习学习
学习学习

顶一个,,,,,,,,,,,,,,,,,,,,,,,,

支持~~~~~~~~~~~~~~~~~~~~~~~~

看看,看看,看看上。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top