Bootstrap

STM32F103定时器详解,本篇以TIM1(高级定时器)配置,编写用于输出PWM驱动模块,代码详解

定时器简介

1.TIM(Timer)定时器
2.定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
3.16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
4.不仅具备基本的定时中断功能,而且还包含内外时钟源选择输入捕获输出比较编码器接口主从触发模式等多种功能
5.根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

定时器类型

在这里插入图片描述
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

高级定时器框图

在这里插入图片描述

通用定时器框图

在这里插入图片描述

基本定时器框图

在这里插入图片描述

定时器中断基本结构

在这里插入图片描述

计数器频率

1.计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)
计数器计数频率 = 时钟源频率 / 预分频系数

2.计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
= CK_PSC / (PSC + 1) / (ARR + 1)
计数器溢出频率 = 时钟源频率 / 预分频系数 /自动重装载寄存器

RCC时钟树

在这里插入图片描述

输出比较简介

1.OC(Output Compare)输出比较
2.输出比较可以通过比较CNTCCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
3.每个高级定时器和通用定时器都拥有4个输出比较通道
4.高级定时器的前3个通道额外拥有死区生成和互补输出的功能

PWM简介

1.PWM(Pulse Width Modulation)脉冲宽度调制
2.在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
3.PWM参数:
频率 = 1 / 一个周期时间 占空比 = 高电平时间 / 一个周期时间 分辨率 = 占空比变化步距
在这里插入图片描述

输出比较模式

在这里插入图片描述

PWM基本结构

在这里插入图片描述

参数计算

在这里插入图片描述

以TIM1(高级定时器)配置,编写用于输出PWM驱动代码

pwm.c

#include "PWM.h"
/**
  * @brief 定时器1 
  * @param  PA8-通道1 PA11-通道4
  * @retval 用于输出PWM
  * @attention  TIM_CtrlPWMOutputs(TIM1,ENABLE);高级定时器专属--MOE主输出使能
  */
void TIM1_Init(u16 per,u16 psc)
{
	/******************************开启时钟*****************************/	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);	//开启定时器1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIO时钟
	/*****************************定义结构体变量******************************/	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	/****************************配置引脚的模式*******************************/	
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	/****************************配置时基单元*******************************/	
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//1/2/4分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;		//向上计数
	TIM_TimeBaseInitStructure.TIM_Period = per;		//ARR:自动重装载寄存器的值 Freq = CK_PSC/(PSC+1)/(ARR+1)
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;	//PSC:预分频系数,72MHz,那么可以给PSC=0,36MHz计数时,那么就给PSC=1
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//TIM_RepetitionCounter:重复计数,也就是重复多少次才发生计数溢出中断。官方注释里面这个数只与TIM1和TIM8有关
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
	
	TIM_CtrlPWMOutputs(TIM1,ENABLE);高级定时器专属--MOE主输出使能
	/******************************输出比较单元配置*****************************/		
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//比较输出模式选择
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//比较输出极性,可选为高电平有效或低电平有效
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0; //比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可设置范围为 0 至 65535。PWM占空比:Duty = CCR / (ARR + 1) = CCR / 100
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);//结构体初始化    
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);//结构体初始化
	
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能或者失能 TIMx 在 CCRx 上的预装载寄存器
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能或者失能 TIMx 在 CCRx 上的预装载寄存器
	TIM_Cmd(TIM1, ENABLE);//开启定时器
}


pwm.h

#ifndef __PWM_H
#define __PWM_H
#include "sys.h"

void TIM1_Init(u16 per,u16 psc);



#endif

;