datasheet

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

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

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

推荐阅读

学习STM32CubeMX与HAL库吐槽

最近因为一个小项目(智能穿戴),用到了STM32L0(低功耗 Cortex M0)系列的MCU,查了官网,居然没有提供固件库,只有HAL库,于是STM32CubeMX生成了HAL库的工程,学习HAL的使用:STM32CubeMX与HAL库的优点:1、降低了使用外设的门槛,所有时钟设置等一目了然。2、统一了代码的架构、风格,让源代码的可读性“保底线“提高。吐槽如下:1、工程的架构很死了,只能在框框条条里填写内容,这完全违背了C程序员们的习惯。例如,要自己加上OS,代码结构会很难看。2、但一但遇上了坑,就无法解决。3、依赖性更高了,而且这工具有BUG,例如:在生成代码时,终止STM32CubeMX,所有源代码会全部消失,自己写的代码
发表于 2019-06-18

STM32CubeMx(Keil5)开发之路——1配置第一个项目

运行环境Windows10STM32CubeMX___Version 5.0.0Keil5(MDK5)___Version 5.15简介本例程主要搭建第一个项目,并且完成最基本的项目所需配置,后续的教程都基于这篇教程。STM32CubeMx配置新建项目搜索自己芯片的型号点击选择封装形式选择外部晶振可以根据需求调节各个总线的时钟频率(就具体情况而定)DEBUG选项选择"Serial Wire"(4线烧录,CLK,DIO,VCC,GND)你会看到芯片引脚会占用这几个引脚,就是烧录用的CLK和DIO点击"Project Manager"修改项目名称修改项目保存路径选择编写工具(我使用Keil5
发表于 2019-06-18
STM32CubeMx(Keil5)开发之路——1配置第一个项目

STM32CubeMX(Keil5)开发之路——9设置微秒级别的延时

运行环境Windows10STM32CubeMX___Version 5.0.0Keil5(MDK5)___Version 5.15简介本例程主要讲解如何对芯片内的Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是STM32F103ZET6,512K大小的Flash。STM32CubeMx基本配置基础配置过程请参考 STM32CubeMx(Keil5)开发之路—配置第一个项目printf重定向例程请参考 STM32CubeMx(Keil5)开发之路——3发送USART数据和printf重定向STM32CubeMx PWM配置1——点击TIM3进行设置2——选择
发表于 2019-06-18
STM32CubeMX(Keil5)开发之路——9设置微秒级别的延时

STM32CubeMX(Keil5)开发之路——7输出PWM

运行环境Windows10STM32CubeMX___Version 5.0.0Keil5(MDK5)___Version 5.15简介本例程主要讲解如何设置PWM这只输出4路PWM信号STM32CubeMx基本配置基础配置过程请参考 STM32CubeMx(Keil5)开发之路—配置第一个项目STM32CubeMx PWM配置1——点击TIM2进行设置2——4个Channel都选择 “PWM Generation CHx” 选项3——预分频值填72-1即714——自动重装载值设置为100-1也就是995——会看到相应的输出管脚PA0——PA3就是PWM的输出管脚讲解:PWM波的频率=时钟频率/(预分频+1)/(自动重装载值
发表于 2019-06-18
STM32CubeMX(Keil5)开发之路——7输出PWM

关于STM32像EPROM一样可以单字节写内部Flash的理解

都有说STM32的内部Flash可以像EPROM一样操作,单个字节单个字节的写入。根据本人的拙见,其实也就仅仅是“像”而已。原因有以下几点:1.首先Flash这种东西,其写入数据的原理是便是将1变成0,所以你的某地址Flash一旦已经写过数据而且不为0,则当你再次需要向该地址写数据时,必须要先擦除,即把该地址先全部变成1,否则你将数据写入该地址后,基本上该地址里面的值已经不是你写入的值了。2.STM32对内部Flash有页(1k或者2K)擦除指令,也就是STM32不能单独对某一个或者某几个字节进行擦除。而擦除操作并不需要大量内存。3.如果要像EPROM一样操作Flash,其原理是先把该一页里面的数据全部读到一个buf里面,如果
发表于 2019-06-18

STM32的ISP升级详解

最近在做一个给STM32用ISP升级的项目,接触到STM32厂家烧录的Bootloader工作流程,具体官方文档稍后上传供大家参考,也可去ST官网下载文档。接下来针对文档中部分内容分析其工作过程:一、要进入该模式,需把STM32硬件上的BOOT0引脚拉高(置1),BOOT1拉低(置0),对此部分不明白的可以查阅STM32BOOT引脚的资料(网上一搜一大堆),不过多阐述。两个引脚配置好对STM32复位,其在4个时钟周期内会自动检测BOOT引脚相应的配置情况,进入相应模式(原厂Bootloader模式)下工作,此时已经到达此次旅行的起点——USART Bootloader 模式此处要特别注意的是硬件上一定要用原厂规定的串口才能完成
发表于 2019-06-18
STM32的ISP升级详解

小广播

何立民专栏

单片机及嵌入式宝典

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

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