基于stm32的呼吸灯,要求产生4彩(红、绿、蓝、白)呼吸灯,呼吸周期为1.6s,CCR更新周期为0.2s 
时间: 2023-05-30 21:07:04 浏览: 47
首先,我们需要了解呼吸灯的原理。呼吸灯是一种渐变效果,通过控制LED的亮度从而产生渐变的效果。呼吸灯的亮度变化可以使用PWM(脉冲宽度调制)实现,而STM32的定时器可以用来产生PWM。
接下来,我们可以按照以下步骤实现基于STM32的呼吸灯:
1. 初始化定时器TIM,设置为PWM模式,使能比较器CCR1、CCR2、CCR3、CCR4输出。同时,设置定时器时钟频率为APB1的2倍,以便可以使用更高的分辨率。
2. 初始化GPIO,将LED连接的引脚设置为TIM的比较器输出。
3. 在主循环中,使用TIM的CCR寄存器和定时器中断来控制呼吸灯的亮度变化。具体流程如下:
- 在每个CCR更新周期(0.2s)中,更新CCR1、CCR2、CCR3、CCR4的值,使其逐渐增加或减少,从而产生呼吸灯的渐变效果。
- 在每个呼吸周期(1.6s)中,将CCR1、CCR2、CCR3、CCR4的值重置为0,从而让呼吸灯重新开始。
- 在TIM的比较器中断中,将LED的引脚输出值设置为比较器的输出状态,从而让LED的亮度随着CCR的变化而变化。
4. 在每个呼吸周期结束后,可以根据需要切换LED的颜色,从而实现多彩的呼吸灯效果。
参考代码如下(仅供参考,实际使用需要根据具体硬件和需求进行修改):
```c
#include "stm32f1xx_hal.h"
#define LED_RED_PIN GPIO_PIN_0
#define LED_RED_PORT GPIOB
#define LED_GREEN_PIN GPIO_PIN_1
#define LED_GREEN_PORT GPIOB
#define LED_BLUE_PIN GPIO_PIN_10
#define LED_BLUE_PORT GPIOB
#define LED_WHITE_PIN GPIO_PIN_11
#define LED_WHITE_PORT GPIOB
#define BREATH_PERIOD 1600 // 呼吸周期,单位ms
#define CCR_UPDATE_PERIOD 200 // CCR更新周期,单位ms
uint32_t ccr1 = 0;
uint32_t ccr2 = 0;
uint32_t ccr3 = 0;
uint32_t ccr4 = 0;
uint32_t ccr_max = 1000; // CCR最大值,即LED的最大亮度
void TIM_Init(TIM_HandleTypeDef *htim)
{
TIM_OC_InitTypeDef sConfigOC = {0};
htim->Instance = TIM3;
htim->Init.Prescaler = 71; // 定时器时钟频率为APB1的2倍,分频系数为72
htim->Init.CounterMode = TIM_COUNTERMODE_UP;
htim->Init.Period = ccr_max; // 定时器计数器最大值为CCR最大值
htim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(htim);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 初始CCR值为0
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL_3);
HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, TIM_CHANNEL_4);
HAL_TIM_PWM_Start_IT(htim, TIM_CHANNEL_1); // 使能比较器CCR1、CCR2、CCR3、CCR4输出并开启定时器中断
HAL_TIM_PWM_Start_IT(htim, TIM_CHANNEL_2);
HAL_TIM_PWM_Start_IT(htim, TIM_CHANNEL_3);
HAL_TIM_PWM_Start_IT(htim, TIM_CHANNEL_4);
}
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = LED_RED_PIN;
HAL_GPIO_Init(LED_RED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LED_GREEN_PIN;
HAL_GPIO_Init(LED_GREEN_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LED_BLUE_PIN;
HAL_GPIO_Init(LED_BLUE_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LED_WHITE_PIN;
HAL_GPIO_Init(LED_WHITE_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_BLUE_PORT, LED_BLUE_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_WHITE_PORT, LED_WHITE_PIN, GPIO_PIN_RESET);
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, htim->Instance->CCR1 >= ccr1);
}
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, htim->Instance->CCR2 >= ccr2);
}
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{
HAL_GPIO_WritePin(LED_BLUE_PORT, LED_BLUE_PIN, htim->Instance->CCR3 >= ccr3);
}
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
HAL_GPIO_WritePin(LED_WHITE_PORT, LED_WHITE_PIN, htim->Instance->CCR4 >= ccr4);
}
}
int main(void)
{
HAL_Init();
TIM_HandleTypeDef htim;
TIM_Init(&htim);
GPIO_Init();
uint32_t last_update_time = HAL_GetTick();
uint32_t last_breath_time = HAL_GetTick();
while (1)
{
uint32_t current_time = HAL_GetTick();
if (current_time - last_update_time >= CCR_UPDATE_PERIOD)
{
last_update_time = current_time;
ccr1 = ccr1 + (ccr1 >= ccr_max ? -ccr_max : 1); // CCR逐渐增加或减少,达到呼吸灯效果
ccr2 = ccr2 + (ccr2 >= ccr_max ? -ccr_max : 2);
ccr3 = ccr3 + (ccr3 >= ccr_max ? -ccr_max : 3);
ccr4 = ccr4 + (ccr4 >= ccr_max ? -ccr_max : 4);
}
if (current_time - last_breath_time >= BREATH_PERIOD)
{
last_breath_time = current_time;
ccr1 = 0; // 呼吸周期结束后,重置CCR值
ccr2 = 0;
ccr3 = 0;
ccr4 = 0;
// 根据需要切换LED颜色,实现多彩呼吸灯效果
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_BLUE_PORT, LED_BLUE_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_WHITE_PORT, LED_WHITE_PIN, GPIO_PIN_RESET);
}
}
}
```
相关推荐











