定时器&PWM应用编程

深入了解STM32定时器原理,掌握脉宽调制pwm生成方法。

一. 使用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用,见下图),连接一个LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭。

二. 接上,采用定时器pwm模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整到一个满意效果。使用Keil虚拟示波器,观察 pwm输出波形。

三. 再接上,采用定时器的另外一个通道,编程采集上面的pwm输出信号,获得其周期和脉宽,并重定向输出到串口显示。

STM32定时器

STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6),如下图所示:
在这里插入图片描述
高级定时器具有捕获/比较通道和互补输出,通用定时器只有捕获/比较通道,基本定时器没有以上两者。
定时器工作原理
在这里插入图片描述

- PWM

PWM对电​脉冲宽度调制,是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。 ​

  • 机转速的控制
    占空比可以实现对电机转速的调节,占空比是高电平在一个周期之中的比值,高电平的所占的比值越大,占空比就越大,对于直流电机来讲,电机输出端引脚是高电平电机就可以转动,当输出端高电平时,电机会转动,但是是一点一点的提速,在高电平突然转向低电平时,电机由于电感有防止电流突变的作用是不会停止的,会保持这原有的转速,以此往复,电机的转速就是周期内输出的平均电压值,所以实质上我们调速是将电机处于一种,似停非停,似全速转动又非全速转动的状态,那么在一个周期的平均速度就是我们占空比调出来的速度了。

一.建立工程模板
在文件夹中复制好需要用到的官方固件库在工程目录下
user文件夹
在这里插入图片描述
core文件夹
在这里插入图片描述
stm文件夹
在这里插入图片描述
设置好project target
在这里插入图片描述
在group里面添加我们需要的文件

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
将工程中引用到的所有头文件的路径都包含进来
在这里插入图片描述
PWM即脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。STM32的定时器除了TIM6与7,其他都可以用来产生PWM输出。
本次实验利用TIM2的CH2产生一路PWM输出要使STM32的通用定时器TIMx产生PWM输出,除了使用寄存器,还需要用到捕获/比较模式寄存器,捕获/比较使能寄存器,捕获/比较寄存器。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

- LED周期性亮灭

代码:
在PWM.h处

#ifndef __PWM_H
#define __PWM_H

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

#endif

在PWM.c处

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
	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);
}

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

最后,在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();
	
	while (1)
	{
			PWM_SetCompare1(0);
			Delay_ms(2000);
		
			PWM_SetCompare1(100);
			Delay_ms(2000);
	}
}

然后进行烧录
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

- 波形观察

在这里插入图片描述
可以看到实际高电平为1.4s左右

- PWM呼吸灯

将上一问中的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();
	
	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);
		}
	}
}

然后生成hex文件后再进行烧录
在这里插入图片描述

呼吸灯

- 波形

在这里插入图片描述
配置debug
在这里插入图片描述

将输出的波形图缩小可以观察到高低电平即占空比在不断变化,占空比越大,呼吸灯越亮。

- 总结

通过这次实验我深入理解了PWM的工作原理,通过调整脉冲的宽度,可以实现LED灯在一定范围内的连续亮度变化。在实现基本的呼吸灯效果后,我有思考如何进一步优化和拓展如改变呼吸灯变化速度,相信在未来的学习中我能够解决这些疑问。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值