千家信息网

stm32通用定时器怎么使用

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,本篇文章为大家展示了stm32通用定时器怎么使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。stm32的定时器又多又复杂,但复杂意味着强大吧。我用的是stm
千家信息网最后更新 2025年01月31日stm32通用定时器怎么使用

本篇文章为大家展示了stm32通用定时器怎么使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

stm32的定时器又多又复杂,但复杂意味着强大吧。我用的是stm32f103ZET6,有2个基本定时器TIM6和TIM7可以用来触发DAC,4个通用定时器TIM2,TIM3,TIM4,TIM5,两个高级定时器TIM1和TIM8,还有两个专用定时器SysTick和RTC。

TIM2,3,4,5,6挂在APB1总线上,TIM1,8挂在APB2总线上,V3.5固件库默认时钟为APB1=36MHz,APB2=72MHz。不过由于对于定时器来说APB1预分频系数为1时频率*2,所以定时器计数时钟TIMXCLK都为72MHz。

通用定时器功能:1、基本时基功能计时。2、输入捕获(可用于测量脉冲周期和占空比)。3、输出比较(四个通道可以当做四个定时器使用)。4、PWM功能。5、正交编码器。

基本定时器:首先也是最重要的当然是定时器的时钟配置了,如果TIMXCLK是72MHz,根据你的需要对时钟进行分频,分频就是对结构体中的两个成员进行赋值,

.TIM_Prescaler  //这个成员是预分频,对应一个16位的分频寄存器,也就是说你可以进行1-65536分频。这个分频一般都能满足需求。.TIM_ClockDivision //这个是分频可能会对,定时器外部计数时的滤波器有影响,所以不用它就行,直接赋值为TIM_CKD_DIV1一分频,就是不分频。因为.TIM_Prescaler这个分频就够用了。

简单定时功能配置方式如下:

void tim2Config(void)          //简单定时功能{        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;        NVIC_InitTypeDef NVIC_InitStructure;                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  //使能时钟        TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);                                         TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;               //向上计数        TIM_TimeBaseInitStructure.TIM_Prescaler = 71;         //71+1分频,1MHz周期1us        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;//时钟不分频        TIM_TimeBaseInitStructure.TIM_Period = 1000-1;                //溢出周期1000      =  1ms                TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);            TIM_ClearFlag(TIM2, TIM_FLAG_Update);              TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);    //开启溢出中断计数到TIM_Period时,发生中断                                     TIM_Cmd(TIM2, ENABLE);                     //使能TIM2                        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);         //配置中断向量        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        NVIC_Init(&NVIC_InitStructure);}

关于中断向量可以看一下这个博客:http://www.cnblogs.com/dyllove98/archive/2013/08/01/3230973.html

中断函数:

void TIM2_IRQHandler(void){                    if( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) //是否为溢出中断    {                                                 TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); //清除中断挂起位               }}

这里注意一定要清除中断挂起位,不然会一直中断。

2、PWM模式:

PWM模式理解起来简单其实就是有两个寄存器,一个是周期寄存器,另一个是比较寄存器。周期寄存器控制周期,比较寄存器控制有效电平(是高电平还是低电平由.TIM_OCPolarity_High的值决定)时间。假如向上计数时,计数器寄存器从零计数,计数到达比较寄存器中的值之前一直为有效电平,之后为另一个电平。计数到周期寄存器中的值时,一个周期完成。这样就成了PWM了。

1、配置GPIO模式。2、配置TIM_TimeBaseInitTypeDef结构体。3、配置TIM_OCInitTypeDef结构体。

static void TIM3_GPIO_Config(void) {  GPIO_InitTypeDef GPIO_InitStructure;        /* TIM3 clock enable */        //PCLK1经过2倍频后作为TIM3的时钟源等于72MHz  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   /* GPIOA and GPIOB clock enable */  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);   /*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull */  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               // 复用推挽输出  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_Init(GPIOA, &GPIO_InitStructure);  /*GPIOB Configuration: TIM3 channel 3 and 4 as alternate function push-pull */  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;  GPIO_Init(GPIOB, &GPIO_InitStructure);}/* * 函数名:TIM3_Mode_Config * 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、占空比 * 输入  :无 * 输出  :无 * 调用  :内部调用 */static void TIM3_Mode_Config(void){        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;        TIM_OCInitTypeDef  TIM_OCInitStructure;        /* PWM信号电平跳变值 */        u16 CCR1_Val = 500;                u16 CCR2_Val = 375;        u16 CCR3_Val = 250;        u16 CCR4_Val = 125;/* -----------------------------------------------------------------------    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:    TIM3CLK = 72 MHz, Prescaler = 0x0, TIM3 counter clock = 72 MHz    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)    TIM3 Frequency = 72 KHz.    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%  ----------------------------------------------------------------------- */  /* Time base configuration */              TIM_TimeBaseStructure.TIM_Period = 999;       //当定时器从0计数到999,即为1000次,为一个定时周期  TIM_TimeBaseStructure.TIM_Prescaler = 71;     //设置预分频:不预分频,即为72MHz  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;     //设置时钟分频系数:不分频  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  /* PWM1 Mode configuration: Channel1 */  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;     //配置为PWM模式1  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;       TIM_OCInitStructure.TIM_Pulse = CCR1_Val;    //设置跳变值,当计数器计数到这个值时,电平发生跳变  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平  TIM_OC1Init(TIM3, &TIM_OCInitStructure);    //使能通道1  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  /* PWM1 Mode configuration: Channel2 */  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;   //设置通道2的电平跳变值,输出另外一个占空比的PWM  TIM_OC2Init(TIM3, &TIM_OCInitStructure);     //使能通道2  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  /* PWM1 Mode configuration: Channel3 */  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  TIM_OCInitStructure.TIM_Pulse = CCR3_Val; //设置通道3的电平跳变值,输出另外一个占空比的PWM  TIM_OC3Init(TIM3, &TIM_OCInitStructure);    //使能通道3  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  /* PWM1 Mode configuration: Channel4 */  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  TIM_OCInitStructure.TIM_Pulse = CCR4_Val; //设置通道4的电平跳变值,输出另外一个占空比的PWM  TIM_OC4Init(TIM3, &TIM_OCInitStructure);   //使能通道4  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  TIM_ARRPreloadConfig(TIM3, ENABLE);                     // 使能TIM3重载寄存器ARR  /* TIM3 enable counter */  TIM_Cmd(TIM3, ENABLE);                   //使能定时器3       }/* * 函数名:TIM3_PWM_Init * 描述  :TIM3 输出PWM信号初始化,只要调用这个函数 *         TIM3的四个通道就会有PWM信号输出 * 输入  :无 * 输出  :无 * 调用  :外部调用 */void TIM3_PWM_Init(void){        TIM3_GPIO_Config();        TIM3_Mode_Config();     }

改变PWM占空比,即是改变比较寄存器的值。使用这个函数

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

使用方法简单例如要改变,TIM3通道1的占空比就这样,TIM_SetCompare1(TIM3, 900); 900为新的比较寄存器的值。

上述内容就是stm32通用定时器怎么使用,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

0