定时器&PWM应用编程

一、概述

        本文主要通过学习定时器、中断知识与相关原理,实现稍微复杂一点的PWM呼吸灯功能,旨在通过此文掌握STM32的相关技能。

二、定时器原理
        定时器的本身是一个计数器,他记录着时钟信号周期数,每个时钟周期都会使定时器里的计数器增加或减少,当我们知道了时钟周期的频率,算出每个时钟周期的时间,进而就可以通过定时器中的计数器进行定时的操作。 

        定时器的模式有向上计、向下计、中心计数的模式,以向上计数为例,如下图,当计数值达到重装载值时,触发定时器中断,随后CNT继续从初始值开始计数。

三、定时器中断的配置

首先新建STM32CubeMx工程,并自主完成基础的时钟树配置与工程配置,随后开始进行定时器的配置。

        受芯片型号的影响,各芯片各定时器的功能不同,需要用户自行选择。这里选了一个通用定时器TIM2,开启的方法是将时钟源选择为内部时钟。

 生成代码,并在main.c中启动定时器。

我们重写中断处理函数,并在其中写LED闪烁程序。

/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim2)
	{
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
	}
}
/* USER CODE END 0 */

相关库函数

拉高,拉低输出

//拉高引脚输出电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
 
//拉低引脚输出电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

RCC(Reset and Clock Control)是STM32微控制器中的一个模块,用于控制和配置各种外设的时钟和复位信息。在初始化STM32引脚之前,需要先开启相应引脚所对应的GPIO外设的时钟。

开启GPIO外设的时钟是为了确保引脚能够正常工作。因为STM32中的GPIO引脚是通过GPIO外设来控制的,而GPIO外设需要时钟信号来运行。通过RCC开启GPIO外设的时钟后,才能正常地对引脚进行配置和操作。

四、PWM配置

PWM即脉冲宽度调制,当高电平触发的LED,我们通过在相同时间内控制其高电平所占的时间来控制LED的亮度,这种方式就是PWM。我们将高电平时间与周期的比值称为占空比。

        那么如何在定时器中使用PWM呢?定时器中的通道作为PWM输出的时候,可以连接到一个IO口,那么这个IO口的电平可以通过定时器的计数值发生变化,通过这种方法,我们可以产生PWM波或改变占空比。

        此处我选择TIM4的Channel3进行后续的呼吸灯开发,在STM32CubeMx配置好相关参数。

仍然要先开启定时器,不过方法有些许改变。

HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);

        最后我们在主函数中加入改变计数值的代码,即可实现呼吸灯功能:

		for(int i=0;i<99;i++)
		{
				__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,i);
				HAL_Delay(1);
		}
#include "stm32f10x.h"
 
//定义LED端口引脚
#define LED0_GPIO_PORT    	GPIOB		                /* GPIO端口 */
#define LED0_GPIO_CLK 	    RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
#define LED0_GPIO_PIN			  GPIO_Pin_8		          //引脚
 
 
/* 使用标准的固件库控制IO*/
#define LED(a)	if (a)	\
					GPIO_SetBits(LED0_GPIO_PORT,LED0_GPIO_PIN);\
					else		\
					GPIO_ResetBits(LED0_GPIO_PORT,LED0_GPIO_PIN)
 
 
 
//初始化LED引脚
void GPIO_init_LED(void)
{
		/*定义一个GPIO_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure0;		
	
		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd( LED0_GPIO_CLK,ENABLE);
	
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure0.GPIO_Pin = LED0_GPIO_PIN;	
 
		/*设置引脚模式为通用推挽输出*/
		GPIO_InitStructure0.GPIO_Mode = GPIO_Mode_Out_PP;   
 
		/*设置引脚速率为50MHz */   
		GPIO_InitStructure0.GPIO_Speed = GPIO_Speed_50MHz; 
 
		/*调用库函数,初始化GPIO*/
		GPIO_Init(LED0_GPIO_PORT, &GPIO_InitStructure0);		
	
}

主函数:

int main(void)
{	
	uint32_t t;
   GPIO_init_LED();
	
	while(1)                            
	{	   
  		LED(0);  //开灯
			t=9900000;
      while(t!=0)
			{t--;}
			LED(1);  //灭灯
			t=9900000;
      while(t!=0)
			{t--;}
	}
}

效果展示:

五、实验心得

这次定时器&PWM应用编程实验使我在理论知识和实践技能方面都取得了显著的进步。通过实验,我深入了解了定时器和PWM的工作原理及应用,并掌握了相关的编程技巧和硬件配置方法。理解定时器工作原理:在开始实验之前,我深入学习了定时器的工作原理。这使我了解到定时器是如何在指定的时间段内生成脉冲的,以及如何通过编程控制这些脉冲的宽度。掌握PWM控制:通过实验,我进一步理解了PWM控制的概念,包括如何生成和调节脉冲的宽度。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值