这里使用cw32l010系列单片机点亮呼吸灯
呼吸灯是一种特殊的LED灯光效果,其亮度会逐渐增加或减小,模拟人类的呼吸动作。实现呼吸灯可以通过控制LED的亮度来完成。下面是一种简单的方法:
/* PB4 作为GTIM1的CH3 PWM 输出 */

可按照功能框图进行配置
下面是具体案例代码
首先是配置SYSCTRL
void SYSCTRL_Configuration(void)
{
/* 0. HSI使能并校准 */
SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV1);
/* 1. 设置HCLK和PCLK的分频系数 */
SYSCTRL_HCLKPRS_Config(SYSCTRL_HCLK_DIV1);
SYSCTRL_PCLKPRS_Config(SYSCTRL_PCLK_DIV1);
SYSCTRL_SystemCoreClockUpdate(4000000);
}
然后是配置GPIO,中断以及定时器使用pwm
void GPIO_Configuration(void)
{
/* PB4 作为GTIM1的CH3 PWM 输出 */
__SYSCTRL_GPIOB_CLK_ENABLE();
PB04_DIGTAL_ENABLE();
PB04_DIR_OUTPUT();
PB04_PUSHPULL_ENABLE();
PB04_AFx_GTIM1CH3();
}
/**
* @brief Configure the nested vectored interrupt controller.
* @param None
* @retval None
*/
void NVIC_Configuration(void)
{
__disable_irq();
NVIC_EnableIRQ(GTIM1_IRQn);
__enable_irq();
}
void PWM_OutputConfig(void)
{
GTIM_InitTypeDef GTIM_InitStruct = {0};
GTIM_OCModeCfgTypeDef GTIM_OCModeCfgStruct = {DISABLE,DISABLE,0};
__SYSCTRL_GTIM1_CLK_ENABLE();
GTIM_InitStruct.AlignMode = GTIM_ALIGN_MODE_EDGE;
GTIM_InitStruct.ARRBuffState = GTIM_ARR_BUFF_EN;
GTIM_InitStruct.Direction = GTIM_DIRECTION_UP; //向上计数
GTIM_InitStruct.EventOption = GTIM_EVENT_NORMAL;
GTIM_InitStruct.Prescaler = 4800 -1; //GTIM的预分频系数,得到10000HZ,0.1ms
GTIM_InitStruct.PulseMode = GTIM_PULSE_MODE_DIS;
GTIM_InitStruct.ReloadValue = 100 -1; //GTIM的重载值,每隔10ms溢出一次
GTIM_InitStruct.UpdateOption = GTIM_UPDATE_DIS;
GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);
GTIM_OCModeCfgStruct.FastMode = DISABLE;
GTIM_OCModeCfgStruct.OCMode = GTIM_OC_MODE_PWM1;
GTIM_OCModeCfgStruct.OCPolarity = GTIM_OC_POLAR_NONINVERT;
GTIM_OCModeCfgStruct.PreloadState = DISABLE;
GTIM_OC3ModeCfg(CW_GTIM1, >IM_OCModeCfgStruct);
// GTIM_SetCompare3(CW_GTIM1,100-1);
GTIM_OC3Cmd(CW_GTIM1, ENABLE); // 使能 GTIM1 的通道 3 输出比较功能
GTIM_Cmd(CW_GTIM1, ENABLE); // 使能 GTIM1 定时器
}
这里我们依旧使用简单延时
void Delay(__IO uint16_t nCount)
{
/* Decrement nCount value */
while (nCount != 0)
{
nCount--;
}
}
也可以写一个系统时钟的延时函数
uint16_t time_ms = 1;
void systick_init(void)
{
SysTick->VAL = 0;
SysTick->LOAD = 48000;
NVIC_SetPriority(SysTick_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
}
void delay_ms(uint16_t time)
{
uint16_t t_ms = time_ms;
while(time_ms != (uint16_t)(t_ms+time));
}
最后是主函数
/**
* @brief GTIM1计数,CH3通道比较,PB04做PWM输出
*
* @return int32_t
*/
int32_t main(void)
{
/* System Clocks Configuration */
SYSCTRL_Configuration();
/* GPIO Configuration */
GPIO_Configuration();
PWM_OutputConfig();
/* NVIC Configuration */
NVIC_Configuration();
uint8_t dutyCycle = 1;//定义占空比
int8_t step = -1;//定义步长
while(1)
{
if (dutyCycle <=1 || dutyCycle >= 100)
{
/* 只要超出了占空比的取值范围,就直接取步长的相反数 */
step = -step;
}
dutyCycle += step;
GTIM1_SetDutyCycle(dutyCycle);
Delay(0xffff);
}
}
这样我们就完成了一个简单的呼吸灯,快来试试吧
————————————————
版权声明:本文为CSDN博主「大漠无河」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2302_80124130/article/details/145533415
|