stm32f103c8t6学习 pwm驱动呼吸灯

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "pwm.h"

int8_t i;

int main(void)
{
	//初始化外设
	pwm_init();

	while(1)//死循环
	{
		for(i=0;i<=100;i++)
		{
			pwm_setcompare(i);
			Delay_ms(10);
		}
		for(i=100;i>=0;i--)
		{
			pwm_setcompare(i);
			Delay_ms(10);
		}
	}
}

pwm.c

#include "stm32f10x.h"                  // Device header

void pwm_init(void)//开启外设时钟→配置时基单元→配置输出比较单元→配置gpio口→运行控制启动计数器
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//通用计时器tim2是apb1总线的外设,故开启apb1的rcc时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启gpio_a时钟
	/*引脚重映射
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);//启用部分重映射1(pa0→pa15;pa1→pb3)
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//解除JTAG的赋用,可使pa15、pb3、pb4做普通gpio使用
	*/
	GPIO_InitTypeDef GPIO_InitStruct;//定义结构体 初始化gpio中一参数
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出 引脚控制来自片上外设,pwm通过引脚输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;//使用gpio_a0 tim2引脚查看引脚配置图
	//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_15;//引脚重映射至pa15 
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化gpio
	
	//配置时基单元
	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
	//定时频率=72m/(psc+1)/(arr+1)定时一秒即一赫兹=72m/10000/7200
	//注:psc和arr取值范围[0~65535]
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器 高级定时器中用
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化
	
	//配置输出比较单元
	TIM_OCInitTypeDef TIM_OCInitStruct;//定义结构体 初始化输出比较单元中一参数
	TIM_OCStructInit(&TIM_OCInitStruct);//所有结构体变量赋初始值
	//之后,根据使用的定时器类型针对部分变量进行修改(通用计时器tim2只需用到结构体的部分参数,其余参数在高级定时器中使用)
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//输出比较极性
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//设置输出使能
	TIM_OCInitStruct.TIM_Pulse=0 ;//设置ccr
	//频率=72m/(psc+1)/(arr+1) 占空比=ccr/(arr+1) 分辨率=1/(arr+1)
	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
	
	TIM_Cmd(TIM2, ENABLE);//启动定时器
}
void pwm_setcompare(uint16_t Compare1)//修改占空比
{
	TIM_SetCompare1(TIM2, Compare1);
}

pwm.h

#ifndef __pwm_h 
#define __pwm_h 

void pwm_init(void);
void pwm_setcompare(uint16_t Compare1);

#endif

Delay模块前有介绍

运行效果

pwm驱动呼吸灯

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,非常适合用于嵌入式系统中,比如实现LED灯的 PWM (Pulse Width Modulation) 控制,从而创建模拟呼吸效果。这里是一个基本步骤: 1. **配置GPIO**: 首先,你需要将GPIO口配置为推挽输出模式,并且设置为PWM功能。例如,如果使用PA8或PB6引脚作为PWM输出,需要启用GPIOA和GPIOB的时钟并配置相应的GPIO线。 2. **初始化TIM(定时器)模块**: STM32F103系列有一个通用定时器(TIM1或TIM2),可以选择一个合适的定时器,配置为PWM模式。设置周期(Prescaler)、占空比模式、自动装载值等参数。 3. **设置PWM波形**: 在 TIM 中设置 PWM 占空比寄存器,使其随时间变化以模仿呼吸灯的效果。对于呼吸灯,你可以设计一种规则,如开始时占空比较大,然后逐渐减小,再慢慢增大,形成起伏的节奏。 4. **编写主循环更新PWM**: 在主程序循环中,根据预定的时间间隔和算法计算新的占空比值,调用 TIM 的更新函数来改变 PWM 输出,从而驱动 LED 呼吸。 5. **可能的优化**: 可以添加延时或中断处理,使得控制更精细。例如,在占空比减小时,等待一段时间后再增加,这样可以让 LED 先暗后亮,效果更逼真。 下面是关键代码片段示例(仅作参考,具体细节取决于库函数和你的代码风格): ```c // 初始化GPIO GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_Pin_8; // PA8或PB6 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_Speed_50MHz; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化TIM TIM_TimeBaseInitTypeDef.TIM_Prescaler = ...; // 根据时钟频率设定预分频值 TIM_TimeBaseInitTypeDef.TIM_Period = ...; // 设置周期 TIM_TimeBaseInitTypeDef.TIM_ClockDivision = ...; // 分频系数 TIM_TimeBaseInitTypeDef.TIM_CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_Base_Init(&htim1, &TIM_TimeBaseInitTypeDef); HAL_TIM_PWM_Init(&htim1); // 设置占空比 void update_PWM(uint8_t duty_cycle) { HAL_TIM_PWM_SetCompare(&htim1, TIM_CHANNEL_1, duty_cycle); } // 主循环 while (1) { if (breathing_state == INHALE) { duty_cycle -= breathing_increment; } else { duty_cycle += breathing_increment; } if (duty_cycle > 100 || duty_cycle < 0) { duty_cycle = 100; // 如果超过最大值或最小值,设回边界 } update_PWM(duty_cycle); HAL_Delay(breath_interval); // 延迟一段时间 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值