一、什么是呼吸灯?
呼吸灯,就是指灯光设备的亮度随着时间由暗到亮逐渐增强,再由亮到暗逐渐衰减,很有节奏感地一起一伏,就像是在呼吸一样,因而被广泛应用于手机、 电脑等电子设备的指示灯中,冰冷的电子设备应用呼吸灯后,顿时增添了几分温暖。
二、呼吸灯与PWM控制原理
呼吸的特性是一种类似图 指数曲线 中的指数曲线过程,吸气是指数上升过程,呼气是指数下降过程,成年人吸气呼气整个过程持续约3秒。
要控制LED灯达到呼吸灯的效果,实际上就是要控制LED灯的亮度拟合呼吸特性曲线。前面控制全彩LED灯时,通过控制脉冲的占空比来调整各个通道LED灯的亮度,从而达到混色的效果。若控制脉冲的占空比在3秒的时间周期内按呼吸特性曲线变化,那么就可以实现呼吸灯的效果了。
这种使用脉冲占空比拟合不同波形的方式称为PWM(脉冲宽度调制)控制技术——通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。PWM控制的基本原理为:冲量相等而开头不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。其中冲量指窄脉冲的面积;效果相同指环节输出响应波形基本相同。
三、基于CYW20829硬件PWM的呼吸灯控制
PWM外设配置
/*******************************************************************************
* File Name: cycfg_peripherals.c
*
* Description:
* Peripheral Hardware Block configuration
* This file was automatically generated and should not be modified.
* Configurator Backend 3.20.0
* device-db 4.16.0.6098
* mtb-pdl-cat1 3.11.0.34443
*
*******************************************************************************
* Copyright 2024 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#include "cycfg_peripherals.h"
#define tcpwm_0_group_1_cnt_5_INPUT_DISABLED 0x7U
const cy_stc_tcpwm_pwm_config_t tcpwm_0_group_1_cnt_5_config =
{
.pwmMode = CY_TCPWM_PWM_MODE_PWM,
.clockPrescaler = CY_TCPWM_PWM_PRESCALER_DIVBY_1,
.pwmAlignment = CY_TCPWM_PWM_LEFT_ALIGN,
.deadTimeClocks = 0,
.runMode = CY_TCPWM_PWM_CONTINUOUS,
.period0 = 32768,
.period1 = 32768,
.enablePeriodSwap = false,
.compare0 = 16384,
.compare1 = 16384,
.enableCompareSwap = false,
.interruptSources = (CY_TCPWM_INT_ON_TC & 0U) | (CY_TCPWM_INT_ON_CC0 & 0U) | (CY_TCPWM_INT_ON_CC1 & 0U),
.invertPWMOut = CY_TCPWM_PWM_INVERT_DISABLE,
.invertPWMOutN = CY_TCPWM_PWM_INVERT_DISABLE,
.killMode = CY_TCPWM_PWM_STOP_ON_KILL,
.swapInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.swapInput = CY_TCPWM_INPUT_0,
.reloadInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.reloadInput = CY_TCPWM_INPUT_0,
.startInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.startInput = CY_TCPWM_INPUT_0,
.killInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.killInput = CY_TCPWM_INPUT_0,
.countInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.countInput = CY_TCPWM_INPUT_1,
.swapOverflowUnderflow = false,
.immediateKill = false,
.tapsEnabled = 45,
.compare2 = 16384,
.compare3 = 16384,
.enableCompare1Swap = false,
.compare0MatchUp = true,
.compare0MatchDown = false,
.compare1MatchUp = true,
.compare1MatchDown = false,
.kill1InputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.kill1Input = CY_TCPWM_INPUT_0,
.pwmOnDisable = CY_TCPWM_PWM_OUTPUT_HIGHZ,
.trigger0Event = CY_TCPWM_CNT_TRIGGER_ON_DISABLED,
.trigger1Event = CY_TCPWM_CNT_TRIGGER_ON_DISABLED,
.reloadLineSelect = false,
.line_out_sel = CY_TCPWM_OUTPUT_PWM_SIGNAL,
.linecompl_out_sel = CY_TCPWM_OUTPUT_INVERTED_PWM_SIGNAL,
.line_out_sel_buff = CY_TCPWM_OUTPUT_PWM_SIGNAL,
.linecompl_out_sel_buff = CY_TCPWM_OUTPUT_INVERTED_PWM_SIGNAL,
.deadTimeClocks_linecompl_out = 0,
#if defined (CY_IP_MXS40TCPWM)
.hrpwm_enable = false,
.hrpwm_input_freq = CY_TCPWM_HRPWM_FREQ_80MHZ_OR_100MHZ,
.kill_line_polarity = CY_TCPWM_LINEOUT_AND_LINECMPOUT_IS_LOW,
.deadTimeClocksBuff = 0,
.deadTimeClocksBuff_linecompl_out = 0,
.buffer_swap_enable = false,
.glitch_filter_enable = false,
.gf_depth = CY_GLITCH_FILTER_DEPTH_SUPPORT_VALUE_0,
.dithering_mode = CY_TCPWM_DITHERING_DISABLE,
.period_dithering_value = 128,
.duty_dithering_value = 128,
.limiter = CY_TCPWM_DITHERING_LIMITER_7,
#endif /* defined (CY_IP_MXS40TCPWM) */
};
#if defined (CY_USING_HAL) || defined(CY_USING_HAL_LITE)
const cyhal_resource_inst_t tcpwm_0_group_1_cnt_5_obj =
{
.type = CYHAL_RSC_TCPWM,
.block_num = 1U,
.channel_num = 5U,
};
#endif /* defined (CY_USING_HAL) || defined(CY_USING_HAL_LITE) */
#if defined(CY_USING_HAL_LITE) || defined (CY_USING_HAL)
const cyhal_clock_t tcpwm_0_group_1_cnt_5_clock =
{
.block = CYHAL_CLOCK_BLOCK_PERIPHERAL1_16BIT,
.channel = 0,
#if defined (CY_USING_HAL)
.reserved = false,
.funcs = NULL,
#endif /* defined (CY_USING_HAL) */
};
#endif /* defined(CY_USING_HAL_LITE) || defined (CY_USING_HAL) */
#if defined (CY_USING_HAL) || defined(CY_USING_HAL_LITE)
const cyhal_pwm_configurator_t tcpwm_0_group_1_cnt_5_hal_config =
{
.resource = &tcpwm_0_group_1_cnt_5_obj,
.config = &tcpwm_0_group_1_cnt_5_config,
.clock = &tcpwm_0_group_1_cnt_5_clock,
};
#endif /* defined (CY_USING_HAL) || defined(CY_USING_HAL_LITE) */
void init_cycfg_peripherals(void)
{
#if defined (CY_DEVICE_CONFIGURATOR_IP_ENABLE_FEATURE)
Cy_SysClk_PeriGroupSlaveInit(CY_MMIO_TCPWM0_PERI_NR, CY_MMIO_TCPWM0_GROUP_NR, CY_MMIO_TCPWM0_SLAVE_NR, CY_MMIO_TCPWM0_CLK_HF_NR);
#endif /* defined (CY_DEVICE_CONFIGURATOR_IP_ENABLE_FEATURE) */
Cy_SysClk_PeriphAssignDivider(PCLK_TCPWM0_CLOCK_COUNTER_EN261, CY_SYSCLK_DIV_16_BIT, 0U);
}
void reserve_cycfg_peripherals(void)
{
#if defined (CY_USING_HAL)
cyhal_hwmgr_reserve(&tcpwm_0_group_1_cnt_5_obj);
#endif /* defined (CY_USING_HAL) */
}
四、实物展示
。
---------------------
作者:YangTwo
链接:https://bbs.21ic.com/icview-3390742-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。