STM32控制WS2812B HAL库

发布于:2023-01-04 ⋅ 阅读:(408) ⋅ 点赞:(0)

利用stm32cubeide实现几个功能:

1.跑马灯

2.单色呼吸灯

ws2812b就不介绍了,不懂得参考这个(39条消息) 初出茅庐的小李第84篇博客之驱动WS2812B灯带(一)_初出茅庐的小李的博客-CSDN博客_ws2812b知道控制原理后,在软件里面配置引脚,我这里用的是PA8。

 模式设置推挽输出,速度设置为HIGH,其他得没啥了,生成代码。

要想实现以上三个功能,首先我们得先让ws218b亮起来,根据时序图,编写我们的发送函数。

#define T0H() __NOP();__NOP();__NOP();__NOP();
#define T0L() __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
#define T1H() __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
#define T1L() __NOP();__NOP();__NOP();__NOP();

void WS2812_Send(uint8_t data){
	for(uint8_t i=0;i<8;i++){
		if(data & 0x80){
		  GPIOA->BSRR = GPIO_PIN_8;
		  T1H();
		  GPIOA->BRR = GPIO_PIN_8;
		  T1L();
		}
		else{
		  GPIOA->BSRR = GPIO_PIN_8;
		  T0H();
		  GPIOA->BRR = GPIO_PIN_8;
		  T0L();
		}
		data<<=1;
	}
}

 通过该函数可以写入一个颜色的数据,要想使彩灯亮起来,就需要发送三个颜色的数据。当然一般来说不会只有一个ws2812,我这里用到了24个,所以想让他们全部亮起来的话需要发送24次。

现在我们思考一个问题,由于ws2812是串在一起的,想要实现跑马灯的效果,不能对每个灯进行单独控制。

所以我采取的方法是把上一个灯的颜色设置为0,这样子就只有当前要显示的灯才有颜色。废话不多说看程序

void ws218_Clear(uint8_t num){  //清除颜色
	for(int j=0;j<num;j++){
	for(int i=0;i<3;i++)
	WS2812_Send(0x00);
	}
}

void waterfall_light(uint8_t green,uint8_t red,uint8_t blue){  
	for(int i=0;i<24;i++){      //因为有24个灯所以要发12次
		for(int j=0;j<i;j++){    //把上一个灯颜色清掉
		  ws218_Clear(1);
		}
		  WS2812_Send(green);      //发送当前需要亮的灯的颜色
		  WS2812_Send(red);
		  WS2812_Send(blue);
		HAL_Delay(500);   
	}
	ws218_Clear(24);    //把全部颜色都清掉
	HAL_Delay(1);       
}

这样就可以实现跑马灯效果了。

现在我们来实现呼吸灯,实现呼吸灯大部分都是通过pwm来改变输出,实现呼吸的效果,但是由于ws2812的控制方式,使得这种方式对于我们来说不可行,所以经过网上查找资料得知,可以把RGB转换成HSL,通过改变L的大小来实现亮度的变化,在把HSL转换成RGB显示出来。

具体转化代码请参考(39条消息) HSL和RGB的相互转换_qq_1769172560的博客-CSDN博客_hsl转rgb

解决了调节亮度问题这样就可以来编写我们的呼吸灯代码了

double luminance;

void breathing_light(uint8_t green,uint8_t red,uint8_t blue){   //呼吸灯 rgb单色的呼吸;
	RGB2HSL(green,red,blue,&H,&S,&L);   //将rgb转换成HSL
	luminance=L;      
	while(luminance>=0){        
		HSL2RGB(H,S,luminance,&r,&g,&b);  //将hsl转换成rgb
		for(int i=0;i<24;i++){
		  WS2812_Send(r);
		  WS2812_Send(g);
		  WS2812_Send(b);
		}
		luminance-=0.01;
		HAL_Delay(12);
	}
	luminance=0;
	while(luminance<L){
		HSL2RGB(H,S,luminance,&r,&g,&b);
		for(int i=0;i<24;i++){
		  WS2812_Send(r);
		  WS2812_Send(g);
		  WS2812_Send(b);
		}
		luminance+=0.01;
		HAL_Delay(12);
	}
}

我们只需要在main函数中调用就可以了。效果这里就不展示了。


网站公告

今日签到

点亮在社区的每一天
去签到