STM32高级定时器-输出比较模式

一.输出比较原理

1.输出比较

通过定时器的外部引脚对外输出控制信号,将通道X(x=1,2,3,4)通常设置为PWM1、PWM2模式。

2.比较寄存器

当计数器CNT 和比较寄存器CCR 的值相等时,输出参考信号OCxREF的信号的极性发生改变,其中OCxREF=1(高电平)称为有效电平,OCxREF=0(低电平)称为无效电平,并且产生比较中断CCxI ,相应的标志位CCxIF会置位。

OCxREF再经过一系列的控制之后成为真正的输出信号OCx/OCxN

3.输出引脚

输出比较的输出信号最终通过定时器的外部IO输出,分别为CH1/2/3/4 ,以及互补输出通道CH1/2/3N

二.PWM输出模式

1.PWM输出

对外输出脉宽(即占空比)可调的方波信号。

2.信号频率

自动重装载寄存器ARR 的值决定,PWM频率 = TIM_CLK/{(PSC+1)(ARR+1)}

3.占空比

比较寄存器CCR 的值决定,占空比=CCR/(ARR+1)

4.常用的值

TIM_CLK:72MHZ;ARR:自动装载寄存器的值 ;CCR: 比较寄存器; PSC:计数器时钟分频因子。

5.PWM边沿对齐模式

在递增计数模式下,计数器从0计数到自动装载寄存器的值(ARR),然后重新从0开始计数并生成计数器上溢事件。

上图中,ARR=8,CCR=4,CNT从0开始计数,使用递增模式。
CNT<CCR 时,OCxREF为有效的高电平。
CCR=<CCR<=ARR 时,OCxREF为无效的低电平。

之后,CNT从0开始计数并生成计数器上溢事件,以此循环往复。

二.输出比较初始化结构体

c 复制代码
typedef struct {
	uint16_t TIM_OCMode; // 比较输出模式
	uint16_t TIM_OutputState; // 比较输出使能
	uint16_t TIM_OutputNState; // 比较互补输出使能
	uint32_t TIM_Pulse; // 脉冲宽度
	uint16_t TIM_OCPolarity; // 输出极性
	uint16_t TIM_OCNPolarity; // 互补输出极性
	uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态
	uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态
} TIM_OCInitTypeDef;;

(1)IM_OCMode :比较输出模式选择,总共有八种,常用的为 PWM1/PWM2,即TIM_OCMode_PWM1/TIM_OCMode_PWM2。

(2)TIM_OutputState :比较输出使能,决定最终的输出比较信号 OCx 是否通过外部引脚输出,即TIM_OutputState_Enable。

(3)TIM_OutputNState: 比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚输出。

(4)TIM_Pulse :比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度 。可设置范围为 0 至 65535。

(5)TIM_OCPolarity :比较输出极性,可选 OCx 为高电平有效或低电平有效,它决定着定时器通道有效电平。即:TIM_OCPolarity_High/TIM_OCPolarity_LOW

HIGH:CNT< CCR(比较寄存器) 时,定时器通道CH输出高电平;

LOW:CNT< CCR(比较寄存器) 时, 定时器通道CH输出低电平。

(6)TIM_OCNPolarity:比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。

(7)TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出 1 或输出 0。

(8)TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出 1 或输出 0

三.源代码

1.bsp_generalpwm.h

c 复制代码
#ifndef BSP_GENERAL_PWM_H
#define BSP_GENERAL_PWM_H

#include "stm32f10x.h"

void INIT_GENERAL_GPIO_CONFIG();
void INIT_GENERAL_PWM_CONFIG();

#endif

2.bsp_generalpwm.c

c 复制代码
#include "bsp_generalpwm.h"

//使用TIM3的 输出比较通道1,2,3,4 对应的GPIO初始化
void INIT_GENERAL_GPIO_CONFIG()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//PA6 PA7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推免输出模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PB0 PB1
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

/* ----------------   PWM信号 周期和占空比的计算--------------- */
// ARR :自动重装载寄存器的值
// CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 72M/(psc+1)
// PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M
// 占空比P=CCR/(ARR+1)

void INIT_GENERAL_PWM_CONFIG()
{
	//初始化 TIM_TimeBaseInitTypeDef
	//开启定时器时钟,即内部时钟CK_INT=72M
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;//72MHZ/((72-1)+1) = 1MHZ  分频因子
	TIM_TimeBaseInitStructure.TIM_Period = 9-1;//重载寄存器的值
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	//占空比设置
	uint8_t OC1_VALUE = 8;
	uint8_t OC2_VALUE = 5;
	uint8_t OC3_VALUE = 4;
	uint8_t OC4_VALUE = 2;
	//初始化 TIM_OCInitTypeDef
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//使用PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出通道电平极性 高电平有效;CNT<  CCR(比较寄存器) 时,定时器通道CH输出高电平;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
	TIM_OCInitStructure.TIM_Pulse = OC1_VALUE;//占空比:TIM_Pulse/(Period +1)
	TIM_OC1Init(TIM3,&TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OCInitStructure.TIM_Pulse = OC2_VALUE;
	TIM_OC2Init(TIM3,&TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OCInitStructure.TIM_Pulse = OC3_VALUE;
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_OCInitStructure.TIM_Pulse = OC4_VALUE;
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	//使能计数器
	TIM_Cmd(TIM3,ENABLE);
}

3.man.c

c 复制代码
#include "bsp_generalpwm.h"

int main(void)
{	
	INIT_GENERAL_GPIO_CONFIG();
	INIT_GENERAL_PWM_CONFIG();
	while(1)
	{
		
	}
}
相关推荐
李永奉2 小时前
51单片机-实现定时器模块教程
单片机·嵌入式硬件·51单片机
正在努力的小河4 小时前
GPIO子系统自主实现(简单版)
linux·单片机·嵌入式硬件
什么半岛铁盒4 小时前
处理端口和 IP 地址
网络·单片机·tcp/ip
国科安芯16 小时前
高速CANFD收发器ASM1042在割草机器人轮毂电机通信系统中的适配性研究
网络·单片机·嵌入式硬件·性能优化·机器人·硬件工程
CC呢16 小时前
基于单片机智能路灯控制
单片机·嵌入式硬件·智能路灯
DDUU__16 小时前
STM32低功耗模式
stm32·单片机·嵌入式硬件
小莞尔18 小时前
【51单片机】【protues仿真】基于51单片机宠物投食器系统
c语言·stm32·单片机·嵌入式硬件·51单片机·proteus
逼子格18 小时前
【Protues仿真】基于AT89C52单片机的数码管驱动事例
单片机·嵌入式硬件·硬件工程·硬件工程师·protues·数码管·电路仿真
風清掦18 小时前
零基础玩转STM32:深入理解ARM Cortex-M内核与寄存器编程
stm32·单片机·嵌入式硬件·mcu·物联网