STM32学习-35-[定时器]呼吸灯实验

呼吸灯的原理

image

通过调节PWM的占空比来模拟sin函数输出正弦波形的电压变化

初始化IO引脚

image

按照如图的方法连接引脚
查阅文档找到对应的引脚
image

image

看一下如何初始化
image

	// 初始化IO引脚
	RCC_APB2PriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	// 开启GPIOA的时钟
	RCC_APB2PriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	// 开启GPIOB的时钟
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};	// 定义结构体

	// PA8
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 
	GPIO_Init(GPIOA, &GPIO_InitStruct);	// 对引脚进行初始化

	// PB13
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 
	GPIO_Init(GPIOB, &GPIO_InitStruct);	// 对引脚进行初始化

配置时基单元

image

image

image

	// 初始化时基单元
	RCC_APB2PeriphCLockCmd(RCC_APB2Periph_TIM1, ENABLE);	// 开启定时器的时钟
	// 初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 71;
	TIM_TimeBaseInitStruct.TIM_Period = 999;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_RepertitionCounter = 0;
 
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); 
 
	// 开启ARR的预加载
	TIM_ARRPreloadConfig(TIM1, ENABLE);

	// 闭合时基单元的总开关
	TIM_Cmd(TIM3, ENABLE);

配置输出比较的参数

image

image

	// 初始化输出比较
	// 初始化输出比较1通道的参数
	TIM_OC1InitTYpeDef TIM_OC1InitStruct;

	TIM OCInitStruct.TIM OCMode = TIM_OCMode_PWMl;
	TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM OCInitStruct.TIM Pulse = 0;

	TIM_OC1Init(TIM1, &TIM_OCInitStruct);

	// 闭合MOE总开关
	TIM_CtrlPWMOutputs(TIM1, ENABLE);
	
	// 启动CCR寄存器的预加载功能
	TIM_CCPreloadControl(TIM1, ENABLE);

改变PWM占空比

image

int main(void)
{
	App_PWM_Init();
	while(1)
	{
		float t = GetTick() * 1.0e-3f;	// 转换成s
		float duty = (sin(2 * 3.14 * t) + 1) * 0.5;

		// 计算占空比
		uint16_t ccr1 = duty * 1000;
		// 设置CCR1的值
		TIM_SetCompare1(TIM1, ccr1);
	}
}

注意引用头文件
GetTick函数是自己实现的,利用的是系统滴答时钟

汇总

#include "stm32f10x.h"

void App_PWM_Init(void);

int main(void)
{
	App_PWM_Init();
	while(1)
	{
		float t = GetTick() * 1.0e-3f;	// 转换成s
		float duty = (sin(2 * 3.14 * t) + 1) * 0.5;

		// 计算占空比
		uint16_t ccr1 = duty * 1000;
		// 设置CCR1的值
		TIM_SetCompare1(TIM1, ccr1);
	}
}

void App_PWM_Init(void){
	// 初始化IO引脚
	RCC_APB2PriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	// 开启GPIOA的时钟
	RCC_APB2PriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	// 开启GPIOB的时钟
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};	// 定义结构体

	// PA8
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 
	GPIO_Init(GPIOA, &GPIO_InitStruct);	// 对引脚进行初始化

	// PB13
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 
	GPIO_Init(GPIOB, &GPIO_InitStruct);	// 对引脚进行初始化

	// 初始化时基单元
	RCC_APB2PeriphCLockCmd(RCC_APB2Periph_TIM1, ENABLE);	// 开启定时器的时钟
	// 初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 71;
	TIM_TimeBaseInitStruct.TIM_Period = 999;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_RepertitionCounter = 0;
 
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); 
 
	// 开启ARR的预加载
	TIM_ARRPreloadConfig(TIM1, ENABLE);

	// 闭合时基单元的总开关
	TIM_Cmd(TIM3, ENABLE);

	// 初始化输出比较
	// 初始化输出比较1通道的参数
	TIM_OC1InitTYpeDef TIM_OC1InitStruct;

	TIM OCInitStruct.TIM OCMode = TIM_OCMode_PWMl;
	TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM OCInitStruct.TIM Pulse = 0;

	TIM_OC1Init(TIM1, &TIM_OCInitStruct);

	// 闭合MOE总开关
	TIM_CtrlPWMOutputs(TIM1, ENABLE);

	// 启动CCR寄存器的预加载功能
	TIM_CCPreloadControl(TIM1, ENABLE);
}

PixPin_2026-09-02_16-33-15

posted @ 2026-09-02 16:35  灵垚克府  阅读(4)  评论(0)    收藏  举报