欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

嵌入式驱动程序(1)IO口模拟PWM(呼吸灯)

程序员文章站 2022-06-28 13:15:05
市面上有很多产品都是都运用到了PWM的功能,比方说动态变化各种颜色的背光灯,渐明渐暗的呼吸灯等产品。PWM就是在固定的周期内,改变IO口高电平和低电平的维持时间。其中 占空比 = 高电平时间/周期时间。通过调节占空比,就可以改变led灯的亮度,通过控制三色灯的不同亮度(权重)来实现不同颜色的显示。如果led灯不停的高低电平切换。我们看到的不应该是一直在闪烁的灯吗?其实不是的,有一种现象叫做视觉暂留:人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留...

市面上有很多产品都是都运用到了PWM的功能,比方说动态变化各种颜色的背光灯,渐明渐暗的呼吸灯等产品。

PWM就是在固定的周期内,改变IO口高电平和低电平的维持时间。其中 占空比 = 高电平时间/周期时间。通过调节占空比,就可以改变led灯的亮度,通过控制三色灯的不同亮度(权重)来实现不同颜色的显示。

如果led灯不停的高低电平切换。我们看到的不应该是一直在闪烁的灯吗?其实不是的,有一种现象叫做视觉暂留:人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”。物体在快速运动时, 当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右的图像,同样的道理,在led亮起来的时候,然后让led短暂时间的熄灭,再亮起来,因为之前led亮的后像还没有消失,再次衔接led亮的动作,人眼就感觉不出led有过熄灭的动作。如果熄灭的时间超过了残留的后像时间人眼就会感觉到led闪烁。

但是物理上led灯的确有过短暂的时间熄灭过,这就会导致led看起来亮度没有一直亮着的led灯亮。

有些嵌入式芯片没有集成PWM功能,那么我们可以通过普通IO口模拟PWM功能。本文通过STM32硬件资源,通过普通IO口模拟PWM功能。代码也可以很容易移植到其他硬件平台。

1. 需要的资源

  • 普通IO口
  • 一个定时器中断,满足固定时间执行一次的调节(这里我们设置成100us)

2. 定义结构体

typedef struct
{
	unsigned char Cycle;		/* 周期计时 周期 = 每次执行的中断时间*0xff */
	unsigned char Duty;			/* 当前占空比 */
	void (*IO_HIGH)(void);		/* 高电平函数 */
	void (*IO_LOW)(void);		/* 低电平函数 */
}PWM_CONFIG;

3. 函数功能

/*
*********************************************************************************************************
*	函 数 名: PWM_Control
*	形    参: pwm
*	返 回 值: 无
*	功能说明:  周期计数Cycle从1到0xff,依次递增计时,每循环一次也就是一次周期完成,
			   当设置的当前占空比大于等于当前的周期计数的时候,IO设置成高电平,否则设置成低电平。
			   比方说,Duty设置成0x40,则Cycle 在[1,0x40]这范围内是高电平,[0x41,0xff]这范围内是低电平
*********************************************************************************************************
*/
void PWM_Control(PWM_CONFIG pwm)
{
	if(pwm.Duty >= pwm.Cycle)
		pwm.IO_HIGH();
	else
		pwm.IO_LOW();
	
	if(++pwm.Cycle > 0xff)
		pwm.Cycle = 1;
}


/*
*********************************************************************************************************
*	函 数 名: PWM_Handler
*	形    参: 无
*	返 回 值: 无
*	功能说明: 将函数放在定时器中断里面,比方说100us的定时中断函数中,保证每100us调用一次
*********************************************************************************************************
*/
void PWM_Handler(void)
{
	PWM_Control(pwm_red_config);
	PWM_Control(pwm_green_config);
	PWM_Control(pwm_blue_config);
}



/*
*********************************************************************************************************
*	函 数 名: PWM_SetColor
*	形    参: red,红色占空比;green,绿色占空比;blue,蓝色占空比
*	返 回 值: 无
*	功能说明: 通过设置每个灯的占空比,来设置三色灯的颜色
*********************************************************************************************************
*/
void PWM_SetColor(unsigned char red, unsigned char green, unsigned char blue)
{
	pwm_red_config.Duty = red;
	pwm_green_config.Duty = green;
	pwm_blue_config.Duty = blue;
}


/*
*********************************************************************************************************
*	函 数 名: PWM_Init
*	形    参: 无
*	返 回 值: 无
*	功能说明: PWM的IO配置,初始化函数
*********************************************************************************************************
*/
void PWM_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;//定义GPIO结构体
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOC的时钟
	
	GPIO_InitStruct.GPIO_Pin = LED_R_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LED_R_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = LED_G_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LED_G_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = LED_B_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LED_B_PORT,&GPIO_InitStruct);	
}

4. RGB颜色对照表

通过调用函数PWM_SetColor,改变三个参数的占空比就可以实现,不同的颜色。可以参考RGB颜色对照表

嵌入式驱动程序(1)IO口模拟PWM(呼吸灯)

5. 建议

  • 周期可以根据实际需要更改,这里我们设置的是100us*0xff
  • 实际运用中将三色灯,一直导通按理说应该是白色灯,但是实际情况可能会偏向其中一个颜色。比方说颜色偏红色,就把红的那一路通过加电阻减小电流或者软件调占空比减小,建议是在三色灯每个IO口串联一个电阻,用来调整亮度。
  • 如果实际产品是和音频有关的注意走线,防止PWM对模拟信号的干扰。

6. 代码下载

io口模拟PWM驱动程序提取码:ihaf

我的个人博客网址:一个点的频率 希望大家关注一下,谢谢!!!

本文地址:https://blog.csdn.net/weixin_49467863/article/details/108184398

相关标签: 嵌入式驱动程序