本项目是我第一次接触单片机的契机,对于以前从来没有做过嵌入式编程和的我来说,这可以说是不小的挑战。本项目中对STC8051系列的STC15W24单片机进行编程我们使用的是keil-4软件。
MCU型号为STC15W204S,原理图如下
下面来讲讲本项目的流程。
首先,下载keil-4 软件。其次,下载相关驱动和stc-isp用于将编好的程序转存到单片机中。(在向单片机中转存代码的过程中,可能会出现LED灯不规则闪烁的情况,这对指令的转入没有任何影响)
这是相关代码的参考。
Ws2812.c
函数 | 功能 |
void ResetDataFlow(void) | 复位,为下一次发送做准备 |
void SendOnePix(unsigned char *ptr) | 发送一个像素点的24bit数据 |
Delay.c
函数 | 功能 |
void DelayMs(unsigned char m) | 延时函数 |
void Delay100Ms(unsigned char m) | 延时100ms子函数(晶振频率33MHz时) |
Main.c
函数 | 功能 |
void Flash_WS2812(unsigned char *p) | 整体闪烁,传递颜色参数 |
void LED_Water(unsigned char *p) | 由内而外流水点亮 |
void LED_Water_Color(unsigned char *p | 由内而外流水点亮,颜色变化 |
void LED_Single_Flower(void) | 单圈单个灯绽放点亮 |
void Water_lamp(unsigned char *p) | 按1-37顺序点亮 |
void DIY_SNOW(unsigned char *p) | 由外向内,按照数组的颜色顺序显示,最多五个颜色 |
void Flower(void) | 一圈一圈点亮 |
void Flower_In(void) | 一圈圈逐步点亮(外内) |
void Gradual_change(unsigned char *p) | 渐变亮 |
void Breathing_WS2812(unsigned char level,unsigned char Color) | 呼吸渐变,两个参数,第一个表示集中小颜色,第二个表示颜色 |
void WS2812_Close(void) | 将37个灯全部熄灭 |
void WS2812_1_5Line(unsigned char *p,unsigned char line) | 让其整圈一起点亮,传递两个参数,第一个参数为显示颜色,第二个参数是让第几圈点亮,圈数1-5 |
void WS2812_1_5Line_In(unsigned char *p,unsigned char line) | 让其整圈一起点亮,内圈颜色保持不变,传递两个参数,第一个参数为显示颜色,第二个参数是让第几圈点亮,圈数1-5 |
void WS2812_1_5Line_Single(unsigned char *p,unsigned char line) | 让对应圈的灯流水点亮,传递两个参数,第一个参数为显示颜色,第二个参数是让第几圈点亮,圈数1-5 |
void WS2812_LineIn_Single(unsigned char *p,unsigned char line) |
对应圈数最外层流水,里面全部点亮。传递两个参数,第一个参数为显示颜色,第二个参数是让第几圈点亮,圈数2-5 |
在本次设计中,我首先让雪花板亮出流水灯的效果,使37个LED灯按照1-37的顺序依次点亮。具体效果可在视频中见到。调用的代码模块为Water_lamp,之后我让全37灯均亮同种颜色的灯,再用不同颜色的流水灯效果将其覆盖。调用代码模块为Water_lamp,Flash_WS2812,为使效果清晰可辨,加上DelayMs(1000)指令使效果保持一段时间。之后调用LED_Water函数使雪花板上的灯由内而外的螺旋式点亮。主函数在while(1)中重复执行上述指令。
下面是程序的流程图
下面是WS2812的点亮原理。
数据为单总线传输,当你连续给入数据的时候,第一个WS2812会“吃掉”24bit的数据,后面依次类推。从而使得每一个WS2812亮不一样的颜色。
程序的主要思想就是将点亮一个灯的程序封装为一个函数,然后点亮方式的程序也封装为一个函数。那么你看到的WS2812亮灭也就是不同的点亮方式的组合。再通过一个标志位来判断以什么方式亮灭。串口就是用来控制这个标志位的媒介。
我们首先在PC端进行编程,然后用数据线连接雪花板上的接口,UART会对传输资料进行转换,实现串行通信,由CH340芯片实现USB转串口。数据协议采用单线归零码的通讯方式。然后由MCU控制各个LED灯的效果。