单片机 > 单片机程序设计 > 详情

STM32之TIM 舵机控制PWM

发布时间:2021-07-15 发布时间:
|

频率的计算为: F = TIM_CLK/{(ARR+1)*(PSC+1)}


如果有中断函数就要配置中断通道中之类的


配置相应TIM通道的GPIO复用引脚


时基结构体配置


输出比较结构体配置(pwm输出时使用)


输出使能


 

/************高级定时器 TIM 参数定义,只限 TIM1 和 TIM8************/

/*************************************************************************************

PWM 信号的频率的计算为: F = TIM_CLK/{(ARR+1)*(PSC+1)}, 

其中 TIM_CLK 等于 72MHZ

TIM1 ch1输出比较通道

TIM1 chn1输出比较通道的互补通道

TIM1 输出比较通道的刹车通道

当使用不同的定时器的时候,对应的 GPIO 是不一样的,这点要注意

这里我们使用高级控制定时器 TIM1

************************************************************************************/

 

 

//定时器复用功能引脚初始化  

/* 使用TIM1 通道 ch1 PA8 ch1n PB13 */

static void TIM1_GPIO_CH12_Config(void)

{

      GPIO_InitTypeDef GPIO_InitStructure;

      // 输出比较通道 GPIO 初始化 

      // TIM1 输出比较通道

      // 输出比较通道 GPIO 初始化

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      // 输出比较通道互补通道 GPIO 初始化

      // TIM1 输出比较通道的互补通道

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 

      // 输出比较通道刹车通道 GPIO 初始化

      // TIM1 输出比较通道的刹车通道

/*      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_Init(GPIOB, &GPIO_InitStructure);

  

    // BKIN 引脚默认先输出低电平

      GPIO_ResetBits(GPIOB,GPIO_Pin_12);

*/

}

 

 

 

#define ADVANCE_TIM_PSC (720-1)           //周期 分频数PSC

#define ADVANCE_TIM_PERIOD (2000-1)        //计数个数ARR

#define ADVANCE_TIM_PULSE 150    //占空比  与ARR相比较

 

// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}

//定时器模式配置

static void TIM1_Mode_Config(void)

{

      // 开启定时器时钟,即内部时钟 CK_INT=72M

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);

      /*--------------------时基结构体初始化-------------------------*/

      TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

      // 自动重装载寄存器的值,累计 TIM_Period+1 个频率后产生一个更新或者中断

      TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_PERIOD;

      // 驱动 CNT 计数器的时钟 = Fck_int/(psc+1)

      TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_PSC;

      // 时钟分频因子 ,配置死区时间时需要用到

      TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

      // 计数器计数模式,设置为向上计数

      TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

      // 重复计数器的值,没用到不用管

      TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

      // 初始化定时器

      TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

      

      

      /*--------------------输出比较结构体初始化-------------------*/

      TIM_OCInitTypeDef TIM_OCInitStructure;

      // 配置为 PWM 模式 1

      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

      // 输出使能

      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

      // 互补输出使能

      TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

      // 设置占空比大小

      TIM_OCInitStructure.TIM_Pulse = ADVANCE_TIM_PULSE;

      // 输出通道电平极性配置

      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

      // 互补输出通道电平极性配置

      TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

      // 输出通道空闲电平极性配置

      TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

      // 互补输出通道空闲电平极性配置

      TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

 

      TIM_OC1Init( TIM1, &TIM_OCInitStructure);

 

      TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

      /*-------------------刹车和死区结构体初始化-------------------*/

      // 有关刹车和死区结构体的成员具体可参考 BDTR 寄存器的描述

 /*     TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

      TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;

      TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

      TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;

      // 输出比较信号死区时间配置,具体如何计算可参考 BDTR:UTG[7:0]的描述

      // 这里配置的死区时间为 152ns

      TIM_BDTRInitStructure.TIM_DeadTime = 11;

      TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;

      // 当 BKIN 引脚检测到高电平的时候,输出比较信号被禁止,就好像是刹车一样

      TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;

      TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

      TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

*/

      // 使能计数器

      TIM_Cmd(TIM1, ENABLE);

      // 主输出使能,当使用的是通用定时器时,这句不需要

      TIM_CtrlPWMOutputs(TIM1, ENABLE);

 

}

 

 

void Advance_TIM1_Init(void)

{

  TIM1_GPIO_CH12_Config();

  TIM1_Mode_Config();

  //外面使用这个控制函数控制占空比

//TIM_SetCompare1(TIM1 , 70);

}

基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定时,没有外部 IO。TIM_TimeBaseInitTypeDef 结构体里面有 5 个成员, TIM6 和 TIM7 的寄存器里面只有TIM_Prescaler 和 TIM_Period,另外三个成员基本定时器是没有的,所以使用 TIM6 和TIM7 的时候只需初始化这两个成员即可

通用定时器 TIM2/3/4/5 是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部 IO。


高级定时器 TIM1/8是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还

可以有三相电机互补输出信号,每个定时器有 8 个外部 IO。


 

STM32F103ZET6高级控制和通用定时器通道引脚分布


  高级定时器 通用定时器

  TIM1 TIM8 TIM2 TIM5 TIM3 TIM4

CH1 PA8/PE9 PC6 PA0/PA15 PA0 PA6/PC6/PB4 PB6/PD12

CH1N PB13/PA7/PE8 PA7

CH2 PA9/PE11 PC7 PA1/PB3 PA1 PA7/PC7/PB5 PB7/PD13

CH2N PB14/PB0/PE10 PB0

CH3 PA10/PE13 PC8 PA2/PB10 PA2 PB0/PC8 PB8/PD14

CH3N PB15/PB1/PE12 PB1

CH4 PA11/PE14 PC9 PA3/PB11 PA3 PB1/PC9 PB9/PD15

ETR PA12/PE7 PA0 PA0/PA15 PD2 PE0

BKIN PB12/PA6/PE15 PA6

其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出

高级控制定时器(TIM1 和 TIM8)和通用定时器在基本定时器的基础上引入了外部引脚,可以实现输入捕获和输出比较功能。高级控制定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能都是针对工业电机控制方面。


输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量 PWM 输入信号的频率和占空比这两种。

输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。



输入通道

需要被测量的信号从定时器的外部引脚 TIMx_CH1/2/3/4 进入,通常叫 TI1/2/3/4,在后面的捕获讲解中对于要被测量的信号我们都以 TIx 为标准叫法。



输入滤波器和边沿检测器

当输入的信号存在高频干扰的时候,我们需要对输入信号进行滤波,即进行重新采样,根据采样定律,采样的频率必须大于等于两倍的输入信号。比如输入的信号为 1M,又存在高频的信号干扰,那么此时就很有必要进。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
PIC单片机基础知识之二