STM32之TIM 舵机控制PWM

2019-05-25来源: eefocus关键字:STM32  TIM  舵机控制  PWM

频率的计算为: 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,又存在高频的信号干扰,那么此时就很有必要进

[1] [2] [3]

关键字:STM32  TIM  舵机控制  PWM

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic462874.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32双缓冲机制初始化(使用STM32CubeMX)
下一篇:iar &stm32调试过程中遇到的问题记录

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8控制4位LED数码管显示数字

用4位LED显示数字 #define STB_H         GPIOC->ODR |= (uint8_t)(GPIO_PIN_2)#define STB_L         GPIOC->ODR &= (uint8_t)(~GPIO_PIN_2) #define DATA_H         GPIOE->ODR |=(uint8_t)( GPIO_PIN_5)#define DATA_L     
发表于 2019-09-21
STM8控制4位LED数码管显示数字

STM32中stm32f0xx_flash.icf文件的作用详解!

 添加额外的region   比如我要添加另一个名为ROM2的ROM区域,大小是256bytes,起始地址是0x80000.       define region ROM = Mem:[from 0x80000 size 0x100];2.2 教你怎样放置SECTION如果你要把你的只读常量放置在你指定的域而不是编译器默认的位置,你就得按如下操作了:define region CONST_region = Mem:[from 0x100 size 0x100];place in
发表于 2019-09-21
STM32中stm32f0xx_flash.icf文件的作用详解!

STM32 USART串口DMA 接收和发送的源码详解!

硬件平台:STM32F103ZET6; 开发环境:KEIL 4;先说说应用通讯模式,串口终端的工作方式和迪文屏差不多,终端被动接受MCU发的指令,终端会偶尔主动发送一些数据给MCU(像迪文屏的触摸信息上传)。串口DMA发送:发送数据的流程:前台程序中有数据要发送,则需要做如下几件事1.在数据发送缓冲区内放好要发送的数据,说明:此数据缓冲区的首地址必须要在DMA初始化的时候写入到DMA配置中去。2.将数据缓冲区内要发送的数据字节数赋值给发送DMA通道,(串口发送DMA和串口接收DAM不是同一个DMA通道)3.开启DMA,一旦开启,则DMA开始发送数据,说明一下:在KEIL调试好的时候,DMA和调试是不同步的,即不管Keil
发表于 2019-09-21

stm32上电自启动后运行不正常的故障排查分析

最近负责一个项目,用到stm32f4的一款高性能芯片。研发过程中遇到一个很诡异的现象,前前后后折腾了两三天,最后才搞定。由于是新手,经验不足,排故过程很纠结~~现象如下:采用JLINK下载程序后,断电让其上电重新启动,发现有时可以正常运行,有时候无法正常运行,大约每两、三次就有一次无法正常上电启动。2.通过JLINK调试程序,每次均正常运行。太诡异了!发现问题后开始定位原因。首先考虑是BOOT启动出问题了,stm32f4启动方式分三种:User FLash、SystemFlash和EmbeddedSRAM,通过BOOT0和BOOT1管脚配置。程序正常运行时从User FLash启动,如果BOOT0和BOOT1配置不正确,会导致无法
发表于 2019-09-21

STM32的时钟系统RCC详细整理

ate NewState);// 使能或者失能PLL//输入:ENABLE或者DISABLE#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div);//#endif#ifdef  STM32F10X_CL void RCC_PREDIV2Config(uint32
发表于 2019-09-21
STM32的时钟系统RCC详细整理

IAR EW6.30版本下建立STM32工程(芯片型号STM32F105VC)

=2blE__GxI1lmJglihBi5xJQPolza-NMxcZqGThxwysiY80ZOe6hLl5k6mowbTN2j30WsPftFZsBe1pRt8WlCDIT7Ce5EIReo4uGCEyegh7S(IAR 新建 STM32工程)        4,http://blog.sina.com.cn/s/blog_4c8287230100f0jw.html(IAR 新建 STM32工程)        5,http://blog.sina.com.cn/s/blog_4c8287230100eznh.html(IAR使用说明)        6,http://blog.sina.com.cn/s/blog_4c8287230100f2ah.html
发表于 2019-09-21
IAR EW6.30版本下建立STM32工程(芯片型号STM32F105VC)

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved