6-3PWM驱动LED呼吸灯

本文详细描述了如何在STM32F103VET6微控制器上使用TIM3定时器和GPIOPB0实现PWM信号的生成,包括时钟配置、TIM初始化、输出比较单元设置和GPIO配置,以及创建PWM_SetCompare3函数来动态调整输出频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本次是基于STM32F103VET6野火指南者,选用的是外设是TIM3和PB0绿灯,因为根据引脚定义表查得PB0对应的是TIM3_CH3,也就是通道3的TIM3,PB0的通道3

/*
PWM初始化
* 第一步:RCC开启时钟,把要用的TIM外设和GPIO外设的时钟打开

* 第二步:配置时基单元,包括时钟源选择和PSC预分频器,CNT计数器,ARR自动重装器

* 第三步:配置输出比较单元,包括:CCR的值,输出比较模式,极性选择,输出使能
*第四步:配置GPIO,把PWM对应的GPIO口,初始化为复用推免输出的配置
*第五步:运行控制,启动计数器,这样就能输出PWM

*/

PWM.c

#include "PWM.h"                  // Device header

void PWM_Init(void)
{
	/*
	*		PWM初始化
	*		第一步:RCC开启时钟,把要用的TIM外设和GPIO外设的时钟打开
	*		第二步:配置时基单元,包括时钟源选择和PSC预分频器,CNT计数器,ARR自动重装器
	*		第三步:配置输出比较单元,包括:CCR的值,输出比较模式,极性选择,输出使能
	*		第四步:配置GPIO,把PWM对应的GPIO口,初始化为复用推免输出的配置
	*		第五步:运行控制,启动计数器,这样就能输出PWM
	*/
	
	//第一步:RCC开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	//第四步
	/*第一步:使用RCC开启GPIO时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	/*第二步:使用GPIO_Init函数初始化GPIO*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//一开始全是关闭状态
	//GPIO_SetBits(GPIOB,GPIO_Pin_5 | GPIO_Pin_1);
	
	//第二步:选择时基单元的时钟源,内部时钟
	TIM_InternalClockConfig(TIM3);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//计数器模式--向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;//APR自动重装器
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;//PSC预分频器
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	//第三步:配置输出比较单元,包括:CCR的值,输出比较模式,极性选择,输出使能
	TIM_OCInitTypeDef 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   实现呼吸灯,就是要不断更改CCR值
	//要使用的是PB0端口,所以选TIM3的OC3也就是TIM3_CH3
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	
	//第六步:启动定时器
	TIM_Cmd(TIM3,ENABLE);
	
}

/*
*		TIM_SetCompare3这个函数是用来单独更改通道3的CCR的值,通过引脚定义表查看得到
*		用下面函数封装一下
*/
void PWM_SetCompare3(uint16_t Compare)
{
		TIM_SetCompare3(TIM3,Compare);
}

PWM.h

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"                  // Device header
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "OLED.h"
#include "PWM.h" 
#include "./delay.h"

uint8_t i;

int main(void){
	
	
	OLED_Init();
	PWM_Init();
	delay_init();
	
	while(1)
	{
		/*只需要在主循环里,不断调用PWM_SetCompare3这个函数,
		 *更改CCR的值,就可以完成LED呼吸灯的效果
		 */
		for(i=0;i<=100;i++)
		{
				PWM_SetCompare3(i);
				delay_ms(10);
		}
		for(i=0;i<=100;i++)
		{
				PWM_SetCompare3(100-i);
				delay_ms(10);
		}
	}
}

### 实现PWM驱动LED呼吸效果 要实现通过微控制器使用PWM控制LED达到呼吸效果,可以按照以下方法设计程序逻辑和硬件配置。 #### 1. PWM基础概念 PWM(Pulse Width Modulation)是一种利用数字信号来模拟连续变量的技术。其核心原理在于调整高电平持续时间相对于整个周期的比例,即占空比[^1]。对于LED而言,改变PWM的占空比能够调节亮度,从而形成渐亮渐暗的效果。 #### 2. 配置定时器生成PWM波形 在STM32系列微控制器中,通常会使用通用定时器(如TIM3、TIM4)生成PWM信号。具体步骤如下: - **初始化GPIO**: 将用于输出PWM信号的引脚配置为复用功能模式。 - **配置定时器参数**: - 设定预分频系数(Prescaler),以确定计数频率。 - 定义自动重装载值(ARR, Auto Reload Register),这决定了PWM信号的周期长度。 - **设定比较寄存器 (CCR)**: 使用`TIMx_CCRx`寄存器动态修改占空比,该值表示在一个完整周期内保持高电平的时间比例[^2]。 #### 3. 编写代码实现呼吸效果 下面提供一段基于STM32 HAL库编写的C语言代码示例,展示如何逐步增加再减少PWM占空比以达成呼吸的功能。 ```c #include "stm32f1xx_hal.h" void MX_TIM3_Init(void); uint16_t dutyCycle = 0; // 初始占空比设为零 int main(void){ HAL_Init(); MX_GPIO_Init(); // 初始化GPIOs MX_TIM3_Init(); // 初始化 TIM3 while (1){ for(dutyCycle=0;dutyCycle<=100;dutyCycle++){// 占空比从0%到100% __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutyCycle*2); HAL_Delay(10); // 延迟让视觉感受更流畅 } for(dutyCycle=100;dutyCycle>=0;dutyCycle--){// 占空比从100%回到0% __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutyCycle*2); HAL_Delay(10); } } } /* 用户自定义函数 */ void MX_TIM3_Init(void){ TIM_HandleTypeDef htim3; htim3.Instance = TIM3; htim3.Init.Prescaler = 8399; // 设置预分频值使得时钟等于1KHz htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; // 自动重载值对应于1ms周期 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_PWM_Init(&htim3)!=HAL_OK){ // 如果初始化失败则停止运行 Error_Handler(); } /* 配置通道1作为PWM输出 */ TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; // 起始脉宽为0 sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;// 输出极性反转以便适应低电平有效型LED连接方式[^3] sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim3,&sConfigOC,TIM_CHANNEL_1); } ``` 此代码片段展示了如何通过不断更新PWM占空比的方式创建一个循环变化的过程,从而使LED呈现出柔和闪烁的现象。 ####
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值