PWM互补输出

标签: 

pwm互补输出

 

stm32高级定时器

 

stm32

 

带死区pwm输出

 

一,高级定时器功能框图

高级控制定时器(TIM1 和 TIM8)和通用定时器在基本定时器的基础上引入了外部引脚,可以实现输入捕获和输出比较功能。高级控制定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能都是针对工业电机控制方面。这几个功能在本书不做详细的介绍,主要介绍常用的输入捕获和输出比较功能。高级控制定时器时基单元包含一个 16 位自动重装载寄存器 ARR,一个 16 位的计数器CNT,可向上/下计数,一个 16位可编程预分频器 PSC,预分频器时钟源有多种可选,有内部的时钟、外部时钟。还有一个 8 位的重复计数器 RCR,这样最高可实现 40位的可编程定时。

高级定时器功能框图如下:

PWM互补输出_第1张图片

1.时基单元框图

高级控制定时器时基单元功能包括四个寄存器,分别是计数器寄存器(CNT)预分频器寄存器(PSC)自动重载寄存器(ARR)重复计数器寄存器(RCR)。其中重复计数器 RCR是高级定时器独有,通用和基本定时器没有。前面三个寄存器都是 16 位有效, TIMx_RCR寄存器是 8 位有效。

 

PWM互补输出_第2张图片

2.输入捕获功能框图

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

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

 

PWM互补输出_第3张图片

3.输出比较功能框图

输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变为有效电平、 PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器 CCMRx 的位 OCxM[2:0]配置。其中 PWM 模式是输出比较中的特例,使用的也最多。

 

PWM互补输出_第4张图片

二,输出比较应用

PWM就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装载寄存器ARR的值决定,信号占空比由比较寄存器CCR的值决定。

1. TIM_TimeBaseInitTypeDef

时基结构体 TIM_TimeBaseInitTypeDef用于定时器基础参数设置,与 TIM_TimeBaseInit函数配合使用完成配置。

代码清单 33-1                                     定时器基本初始化结构体

1 typedef struct {

2 uint16_t TIM_Prescaler;

 

// 预分频器

3 uint16_t TIM_CounterMode;

 

 // 计数模式

4 uint32_t TIM_Period;

 

// 定时器周期

5 uint16_t TIM_ClockDivision;

 

// 时钟分频

6 uint8_t TIM_RepetitionCounter;

 

// 重复计算器

7 } TIM_TimeBaseInitTypeDef;

2. TIM_OCInitTypeDef

输出比较结构体 TIM_OCInitTypeDef 用于输出比较模式,与 TIM_OCxInit 函数配合使用完成指定定时器输出通道初始化配置。高级控制定时器有四个定时器通道,使用时都必须单独设置。

代码清单 33-2                                   定时器比较输出初始化结构体

1 typedef struct {

2 uint16_t TIM_OCMode;

 

// 比较输出模式

3 uint16_t TIM_OutputState;

 

// 比较输出使能

4 uint16_t TIM_OutputNState;

 

// 比较互补输出使能

5 uint32_t TIM_Pulse;

 

// 脉冲宽度

6 uint16_t TIM_OCPolarity;

 

// 输出极性

7 uint16_t TIM_OCNPolarity;

 

// 互补输出极性

8 uint16_t TIM_OCIdleState;

 

// 空闲状态下比较输出状态

9 uint16_t TIM_OCNIdleState;

 

// 空闲状态下比较互补输出状态

10 } TIM_OCInitTypeDef;

3. TIM_ICInitTypeDef

输入捕获结构体 TIM_ICInitTypeDef 用于输入捕获模式,与 TIM_ICInit 函数配合使用完成定时器输入通道初始化配置。如果使用 PWM 输入模式需要与 TIM_PWMIConfig 函数配合使用完成定时器输入通道初始化配置。

代码清单 33-3                                  定时器输入捕获初始化结构体

1 typedef struct {

2 uint16_t TIM_Channel;

 

// 输入通道选择

3 uint16_t TIM_ICPolarity;

 

 // 输入捕获触发选择

4 uint16_t TIM_ICSelection;

 

 // 输入捕获选择

5 uint16_t TIM_ICPrescaler;

 

// 输入捕获预分频器

6 uint16_t TIM_ICFilter;

 

// 输入捕获滤波器

7 } TIM_ICInitTypeDef;

4. TIM_BDTRInitTypeDef

断路和死区结构体 TIM_BDTRInitTypeDef 用于断路和死区参数的设置,属于高级定时器专用,用于配置断路时通道输出状态,以及死区时间。它与 TIM_BDTRConfig 函数配置使用完成参数配置。 这个结构体的成员只对应 BDTR 这个寄存器,有关成员的具体使用配置请参考手册 BDTR 寄存器的详细描述。

代码清单 33-4                                断路和死区初始化结构体

1 typedef struct {

2 uint16_t TIM_OSSRState;

 

// 运行模式下的关闭状态选择

3 uint16_t TIM_OSSIState;

 

 // 空闲模式下的关闭状态选择

4 uint16_t TIM_LOCKLevel;

 

// 锁定配置

5 uint16_t TIM_DeadTime;

 

// 死区时间

6 uint16_t TIM_Break;

 

 // 断路输入使能控制

7 uint16_t TIM_BreakPolarity;

 

// 断路输入极性

8 uint16_t TIM_AutomaticOutput;

 

// 自动输出使能

9 } TIM_BDTRInitTypeDef;

三,PWM 互补输出实验

1. 编程要点

(1) 定时器用到的 GP IO 初始化

(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化

(3) 定时器输出比较结构体 TIM_OCInitTypeDef 初始化

(4) 定时器刹车和死区结构体 TIM_BDTRInitTypeDef 初始化

2.Advance_timer.c源文件程序代码

#include "Advance_timer.h" 

 static void ADVANCE_TIM_GPIO_Config(void)

 {

GPIO_InitTypeDef GPIO_InitStructure;

 

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

RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK,ENABLE);

GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(ADVANCE_TIM_CH1_PORT, &GPIO_InitStructure);

 

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

RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1N_GPIO_CLK,ENABLE);

GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1N_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(ADVANCE_TIM_CH1N_PORT, &GPIO_InitStructure);        

 

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

RCC_APB2PeriphClockCmd(ADVANCE_TIM_BKIN_GPIO_CLK,ENABLE);

GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_BKIN_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(ADVANCE_TIM_BKIN_PORT, &GPIO_InitStructure);

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

GPIO_ResetBits(ADVANCE_TIM_BKIN_PORT,ADVANCE_TIM_BKIN_PIN);

 } 

 static void ADVANCE_TIM_NVIC_Config(void)

 {

NVIC_InitTypeDef NVIC_InitStructure;

  //设置中断组为0

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  //设置中断来源

NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQ;

  //设置抢占优先级

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  //设置子优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);                

 }

// ARR :自动重装载寄存器的值

// CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 72M/(psc+1)

// PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M

// 占空比P=CCR/(ARR+1)

  static void ADVANCE_TIM_MODE_Config(void)

  {

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;

TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

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

ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE); 

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

TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_PERIOD;

  //驱动CNT计数器的时钟 = Fck_int / (psc+1) = 72M/(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(ADVANCE_TIM, & TIM_TimeBaseStructure); 

  // 配置为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(ADVANCE_TIM, &TIM_OCInitStructure);

  //使能TIMx在CCR1上的预装载寄存器

TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);

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

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(ADVANCE_TIM, &TIM_BDTRInitStructure);

 

  // 使能计数器

TIM_Cmd(ADVANCE_TIM, ENABLE);        

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

TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);

}

 void ADVANCE_TIM_Init(void)

 {

ADVANCE_TIM_GPIO_Config();

ADVANCE_TIM_NVIC_Config();

ADVANCE_TIM_MODE_Config();

 }

分享:

1

喜欢

0

赠金笔

阅读(2812) 评论 (1) 收藏(0) 转载(0)  喜欢 打印举报/Report

前一篇:STM32学习总结-定时器PWM输入捕获测量脉冲的最小和最大频率计算公式

后一篇:STM32F10xx开发板学习笔记-MPU6050传感器实验

评论 重要提示:警惕虚假中奖信息

[发评论]

  • 东理电子科技协会

    内容还不够深入和全面。

    2017-4-27  16:15回复(0)

 

你可能感兴趣的:(stm32)