首页 > 其他分享 >08_TIM输出比较

08_TIM输出比较

时间:2024-02-08 14:11:58浏览次数:24  
标签:输出 include 08 TIM Init GPIO PWM void

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);
	}
}

标签:输出,include,08,TIM,Init,GPIO,PWM,void
From: https://www.cnblogs.com/mzx233/p/18011765

相关文章

  • 07_TIM定时中断
    TIM定时中断TIM简介定时器类型基本定时器通用定时器高级定时器基本定时器仅支持向上计数:0->重装值->发起中断通用定时器和高级定时器支持向上计数,向下计数,中央对齐计数向下计数:重装值->0->发起中断中央对齐计数:0->重装值->发起中断->0->发起中断基本定时器只......
  • PAT乙级-1008(数组元素循环右移问题)
    一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A1⋯A**N−1)变换为(A**N−M⋯A**N−1A0A1⋯A**N−M−1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?输入格式:每个输入包......
  • LocalDateTime判断时间段归属
    //v2024-02-0207:52:572024-02-0214:39:14//DateinTime=Date.from(Instant.ofEpochMilli(1707150614000L));//LocalDateTimeinTimeLocalDateTime=DateUtil.dateToLocalDateTime(inTime);LocalDateTimeinTime=LocalDateTime.parse("2024-02-01......
  • golang定时器之timer+ticker
    转载: https://juejin.cn/post/7327157426298011663 Timer是一个一次性的定时器,用于在未来的某一时刻执行一次操作。基本使用创建Timer定时器的方式有两种:NewTimer(dDuration)*Timer:该函数接受一个time.Duration类型的参数d(时间间隔),表示定时器在过期之前等待的......
  • C#的timespan怎么使用
    https://www.yisu.com/ask/23316568.html1、TimeSpan类是用来表示时间间隔的,它提供了一些方法和属性来操作和获取时间间隔的信息。以下是一些常用的TimeSpan的用法示例:创建一个TimeSpan实例:TimeSpantimeSpan1=newTimeSpan(2,30,0);//2小时30分钟0秒TimeSpantim......
  • pandas.to_datetime datetime.combine 拼接日期时间
    在Python中,如果你想要使用datetime.date对象拼接时间,你需要先将datetime.date对象转换为datetime.datetime对象,然后再添加时间。(不转化也可以啊)importpandasaspdimportdatetimedefmain():date=pd.Timestamp.today().date()#将pd.Timestamp转为datetime.date类......
  • 使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab
    错误详情:使用IDEA直接连接数据库报错:Serverreturnsinvalidtimezone.Goto'Advanced'tabandset'serverTimezone'propertymanually.错误原因:MySQL驱动中默认时区是UTC,与本地时间有时差。解决方案:点开最右侧导航栏Advanced,找到serverTimezone,在value处填写GMT保存再......
  • datetime.date + datetime.timedelta 结果仍然是 datetime.date 因而不能与时间进行比
    importpandasaspdimportdatetimedefmain():foo=pd.Timestamp.now()bar=datetime.date.today()+datetime.timedelta(days=-1)res=bar+datetime.timedelta(hours=24)print(res,type(res))if__name__=='__main__':ma......
  • pandas.Timedelta(days=1) 可以 与 datetime.timedelta(days=1) 效果一致
    pandas.Timedelta(days=1)可以与datetime.timedelta(days=1)效果一致https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timedelta.html#pandas-timedelta但pandas.Timedelta可以有其他写法......
  • CF1408F Two Different 题解
    解题思路先考虑如何将一堆数变为相同的。显然,这里有一个条件\(n=2^k,k\in\mathbbZ\),证明如下:每次操作只能将两个数变为相同的,那么一个数在使得其他数变为相同数的操作中(我们不妨将所有数进行这种操作称为一轮操作),一个数最多被使用一次;按照错位操作,即第一轮\(1\)和\(2\)......