08_TIM输出比较

TIM输出比较

输出比较简介

image-20240118163629261

CNT:计数器

CCR:捕获/比较寄存器

PWM简介

image-20240118164722506

输出比较通道(高级)

image-20240118230914228

输出比较通道(通用)

image-20240118230958288

输出比较模式

image-20240121181210631

PWM基本结构

image-20240121183809003

参数计算

image-20240121184111307

舵机简介

image-20240121184917739

舵机硬件电路

image-20240122125231461

直流电机及驱动简介

image-20240121184942791

硬件电路

image-20240122134426326

PWM驱动LED呼吸灯

接线图

image-20240123122225084

参数计算

产生一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形

代入公式:

image-20240124131438913

ARR+1=100

CCR=50

PSC+1=720

不使用重定义功能

image-20240124154443452

代码

PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	//产生一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//直接使用PA0接口对应TIM2_CH1_ETR
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_InternalClockConfig(TIM2); //配置内部时钟
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStruct.TIM_Period=100-1; //自动重装器 ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1; //预分频器 PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct); //配置时基单元
	
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct); //给结构体默认初始值
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //输出比较模式:PWM1
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //输出比较极性:高电平
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; //输出使能
	TIM_OCInitStruct.TIM_Pulse=0; //捕获比较寄存器 CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStruct); //TIM2的OC1通道初始化
	
	TIM_Cmd(TIM2,ENABLE); //启动定时器
}

/**
  * @brief 设置CCR的值(占空比)
  * @param Compare: uint16_t
  * @retval void
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

PWM.h

#ifndef __PWM_H__
#define __PWM_H__

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

#endif

main.c

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

uint8_t i;

int main(void)
{
	OLED_Init();
	PWM_Init();
	OLED_ShowString(1,1,"HelloWorld!");
	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);
		}
	}
}

使用重定义功能

image-20240124154654547

image-20240124155315056

image-20240124160654166

代码

xxxxxxxxxx #include "stm32f10x.h"                  // Device header#include "Delay.h"#include "OLED.h"#include "Timer.h"​uint16_t Num;​int main(void){ OLED_Init(); Timer_Init(); OLED_ShowString(1,1,"Num:"); OLED_ShowString(2,1,"CNT:"); while(1) { OLED_ShowNum(1,5,Num,5); OLED_ShowNum(2,5,Timer_GetCounter(),5); }}​void TIM2_IRQHandler(void){ if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET) { Num++; TIM_ClearITPendingBit(TIM2,TIM_IT_Update); }}c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	//产生一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//直接使用PA0接口对应TIM2_CH1_ETR
//	GPIO_InitTypeDef GPIO_InitStruct;
//	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
//	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
//	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//使用重定义功能将PA15映射给TIM2_CH1_ETR
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO
	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE); //引脚重映射配置 PA0->PA15
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //JTAG-DP Disabled and SW-DP Enabled,让PA15解除JTDI,变为正常的GPIO口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_15; //PA0->PA15
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_InternalClockConfig(TIM2); //配置内部时钟
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStruct.TIM_Period=100-1; //自动重装器 ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1; //预分频器 PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct); //配置时基单元
	
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct); //给结构体默认初始值
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //输出比较模式:PWM1
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //输出比较极性:高电平
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; //输出使能
	TIM_OCInitStruct.TIM_Pulse=0; //捕获比较寄存器 CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStruct); //TIM2的OC1通道初始化
	
	TIM_Cmd(TIM2,ENABLE); //启动定时器
}

/**
  * @brief 设置CCR的值(占空比)
  * @param Compare: uint16_t
  * @retval void
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

PWM驱动舵机

接线图

image-20240125123705940

参数计算

image-20240125131151507

image-20240125131027025

周期=20ms

频率=50Hz

PSC+1=72

ARR+1=20K

占空比=0.5/20=0.025

CCR/20K=0.025,CCR=500

代码

Servo.c

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

void Servo_Init(void)
{
	PWM_Init();
}

/**
  * @brief 设置舵机角度,范围(0°~180°)
  * @param Angle:角度值
  * @retval 无
  */
void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle*2000/180+500);
}

Servo.h

#ifndef __SERVO_H__
#define __SERVO_H__

void Servo_Init(void);
void Servo_SetAngle(float Angle);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "Key.h"

uint8_t KeyNum;
float Angle;

int main(void)
{
	OLED_Init();
	Servo_Init();
	Key_Init();
	OLED_ShowString(1,1,"Angle:");
	Servo_SetAngle(Angle);
	while(1)
	{
		KeyNum=Key_GetNum();
		if(KeyNum==1)
		{
			Angle+=30;
			if(Angle>180)
			{
				Angle=0;
			}
		}
		Servo_SetAngle(Angle);
		OLED_ShowNum(1,7,Angle,3);
	}
}

PWM驱动直流电机

接线图

image-20240130143224990

image-20240202214706610

代码

Motor.c

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

void Motor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	PWM_Init();
}

/**
  * @brief 设置电机速度
  * @param Speed >0 正转 <0 反转
  * @retval 无
  */
void Motor_SetSpeed(int8_t Speed)
{
	if(Speed>=0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		PWM_SetCompare3(Speed);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_4);
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
		PWM_SetCompare3(-Speed);
	}
}

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"

uint8_t KeyNum;
int8_t Speed;

int main(void)
{
	OLED_Init();
	Motor_Init();
	Key_Init();
	OLED_Init();
	OLED_ShowString(1,1,"Speed:");
	Motor_SetSpeed(Speed);
	while(1)
	{
		KeyNum = Key_GetNum();
		if(KeyNum == 1)
		{
			Speed+=20;
			if(Speed>100)
			{
				Speed=-100;
			}
		}
		Motor_SetSpeed(Speed);
		OLED_ShowSignedNum(1,7,Speed,3);
	}
}
posted @ 2024-02-08 14:04  爱吃冰激凌的黄某某  阅读(23)  评论(0编辑  收藏  举报