STM学习——TIM输出比较

一、OC(Output Compare)输出比较

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

每个高级定时器和通用定时器都拥有4个输出比较通道

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

PWM简介

PWM(Pulse Width Modulation)

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

PWM参数:      频率 = 1 / TS            占空比 = TON / TS           分辨率 = 占空比变化步距

 通过占空比的大小改变模拟电压的大小。

通用定时器输出结构

 输出比较模式

 主要使用PWM模式1,向上计数。

PWM基本结构

参数计算 舵机简介

 

直流电机简介

二、代码部分

1、呼吸灯

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

 

设置CCR值 

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}

 

通过设置CCR的值来改变PWM波的占空比/ 

 使用重映射功能改变输出引脚

//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能AFIO时钟以进行重映射
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);//将所要使用的引脚重映射
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//解除调试功能,将对应引脚改为默认的I/O口

GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)

Changes the mapping of the specified pin.

2、PWM驱动舵机

void PWM_SetCompare2(uint16_t Compare)//设置CCR的值
{
	TIM_SetCompare2(TIM2, Compare);
}

void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle / 180 * 2000 + 500);
}

 通过角度与CCR值的关系直接设置CCR值。

#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:");
	
	while (1)
	{
		KeyNum = Key_GetNum();
		if (KeyNum == 1)
		{
			Angle += 30;
			if (Angle > 180)
			{
				Angle = 0;
			}
		}
		Servo_SetAngle(Angle);
		OLED_ShowNum(1, 7, Angle, 3);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果您的STM32单片机屏幕一直闪烁,可能是因为您的程序中使用了循环延时的方式,导致CPU一直忙碌而无法及时刷新屏幕。为了解决这个问题,可以使用STM32的定时器中断来实现LED的闪烁,从而释放CPU资源,让它能够及时地刷新屏幕。 以下是使用TIM中断方式实现LED闪烁的示例代码: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) // 定时器2中断服务函数 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // 检查是否发生了更新事件 { static uint8_t led_state = 0; if (led_state == 0) { GPIO_SetBits(GPIOC, GPIO_Pin_13); // PC13输出高电平 led_state = 1; } else { GPIO_ResetBits(GPIOC, GPIO_Pin_13); // PC13输出低电平 led_state = 0; } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位 } } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能GPIOC时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟 // 配置GPIOC.13为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // 配置TIM2 TIM_TimeBaseStructure.TIM_Period = 999; // 自动重载值 TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能更新中断 TIM_Cmd(TIM2, ENABLE); // 启动定时器 // 配置NVIC NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 空闲循环 } } ``` 在上面的代码中,我们使用了定时器TIM2,并把它配置为1ms的定时器。在定时器中断服务函数中,我们通过改变LED的状态来实现LED的闪烁。由于使用了中断方式,CPU不会一直忙碌,从而可以释放CPU资源,让它能够及时地刷新屏幕。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值