【STM32】通用定时器TIM(输出比较)

本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发

目录

前言

输出比较简介

PWM简介

输出比较配置

初始化IO口

输出比较初始化

输出比较代码

PWM.h

PWM.c

main.c 

应用案例 


前言

建议先阅读这篇博客,理解时基单元的配置

【STM32】通用定时器TIM(时钟源选择与更新中断)-CSDN博客

输出比较简介

OC(Output Compare)输出比较,可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形

STM32F10xxx通用定时器为TIM2TIM3TIM4TIM5,每个通用定时器都拥有4个输出比较通道和4个输入捕获通道

输出比较和输入捕获的共用一个通用定时器的4个通道,一个定时器使用了其中一个功能,另一个就不能用了。

                                                               输出比较框图
 

cf787f9232404f31ab0c7b76deb0db04.png

定时器的PSC预分频器,自动重装载寄存器,捕获/比较寄存器下面都有黑色影子,这些寄存器可选择寄存器值在更新事件装入或者即时装入

高级定时器 

  • 每个高级定时器也拥有4个输出比较通道
  • 高级定时器的前3个通道额外拥有死区生成和互补输出的功能

c4552d3bd2394739a02a6e4d81d2545f.png

高级定时器不是本博客学习内容,了解即可

PWM简介

PWM(Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

                               将数字量等效为模拟量

a775b880453b412a9d79a14d5f8ee9b6.png

PWM参数含义
频率 1/T_S
占空比T_ON/T_S
分辨率占空比变化步距

                                                        图解 

a34df789bdca4dd78d327f49d7b7204a.png

输出比较配置

PWM频率Freq= CK_PSC/(PSC + 1)/(ARR + 1)
PWM占空比:Duty = CCR/(ARR + 1)
PWM分辨率:Reso =1/(ARR + 1)

395655d1e36e48c2971a13b9ec2638ce.png

初始化IO口

GPIO的其它参数的理解可以阅读下方博客,这里不再赘述。

【STM32】GPIO和AFIO标准库使用框架_gpio afio-CSDN博客

查找引脚定义表,将通用定时器2的输出比较通道1(PA0)配置为复用推挽输出,由定时器输出至GPIO。

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

输出比较初始化

输出比较框图

	/*输出比较初始化*/
	TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值
																	//则最好执行此函数,给结构体所有成员都赋一个默认值
																	//避免结构体初值不确定的问题
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//输出比较模式,选择PWM模式1
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//输出极性,选择为高,若选择极性为低,则输出高低电平取反
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//输出使能
	TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1

参数TIM_OCMode: 

 输出比较模式9ae14131e7ec467089d8aed601bc012f.png

 参数TIM_OCPolarity

输出比较代码

PWM.h

#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
void PWM_SetPrescaler(uint16_t Prescaler);

#endif

PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	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
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

/**
  * 函    数:PWM设置CCR1
  * 参    数:Compare 要写入的CCR的值,范围:0~100
  * 返 回 值:无
  * 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比
  *           占空比Duty = CCR / (ARR + 1)
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);		
}

/**
  * 函    数:PWM设置PSC
  * 参    数:Prescaler 要写入的PSC的值,范围:0~65535
  * 返 回 值:无
  * 注意事项:PSC和ARR共同决定频率,此函数仅设置PSC的值,并不直接是频率
  *           频率Freq = CK_PSC / (PSC + 1) / (ARR + 1)
  */
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);		//设置PSC的值
}

main.c 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "PWM.h"

uint8_t i;

int main(void)
{
	PWM_Init();
	
	while (1)
	{
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
		for (i = 0; i <= 100; i++)
		{
			PWM_SetCompare1(100 - i);
			Delay_ms(10);
		}
	}
}

应用案例 

呼吸灯

LED-STM32单片机驱动单色LED和RGB全彩LED亮灭与呼吸灯代码_rgb led驱动代码-CSDN博客

舵机 

SG90舵机介绍与PWM驱动代码_sg90是数字舵机还是模拟舵机-CSDN博客

电机 

TB6612FNG电机驱动模块(控制电机转向和转速)-CSDN博客

无源蜂鸣器 

蜂鸣器—STM32驱动有源与无源蜂鸣器的介绍与代码示例_tmb12a05驱动电路-CSDN博客

  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值