(仅供学习使用,如有错误,欢迎指正)
本项目是本人初学单片机与嵌入式系统的课程作业。小马老师有言曰:“会点LED灯,就可以说自己会单片机了。”于我个人而言,点亮LED灯在一定程度上提升了我学单片机的信心,同时也是我开始学习并使用单片机的开端。
该雪花板采用STC8051系列的STC15W24单片机作为控制器。此外,Snowflake还包含USB总线的转接芯片CH340,实现USB转串口。数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit;依次类推,以控制WS2812所亮颜色。像素点采用自动整形转发技术,使得该像素点的级联个数不受信号传送的限制,仅仅受限信号传输速度要求。
本人构想出来的一种LED灯组合亮灭方式为:在一个循环周期内,由内而外逐行“蓝白叠加”点亮WS2812RGB灯, 其中白色光强保持一致,蓝光光强逐圈增加;循环此过程。
硬禾学堂电子森林提供了一种程序设计思想:程序的主要思想就是将点亮一个灯的程序封装为一个函数,然后点亮方式的程序也封装为一个函数。那么,WS2812亮灭即为不同的点亮方式的组合。再通过一个标志位来判断以什么方式亮灭。串口就是用来控制这个标志位的媒介(这句话还不太理解)。
代码展示:
/*-------------------------------------------------------
* Project Name:
Illumination of the Water Lamps V1.0
* Instruction on Configuration:
- MCU : STC15W204S
- Frequency of CPU : 30MHz
--------------------------------------------------------- */
/*---------------to include the head files---------------*/
#include "STC15W.h"
#include "ws2812.h"
#include "delay.h"
#include "uart.h"
/*-------------to state the sub functions----------------*/
void WS2812_Close(void);
void WS2812_1_5Line(unsigned char *p,unsigned char line);
void mine(unsigned char n,unsigned char m);
/*-------------to state the global variables----------------*/
unsigned char blue_a[3]={5,5,10};
unsigned char blue_b[3]={5,5,15}
unsigned char blue_c[3]={5,5,20};
unsigned char blue_d[3]={5,5,25};
unsigned char close[3]={0,0,0};
xdata unsigned char buffer[64];
unsigned char buf_data=0x00;
unsigned char m=0x01;
/*-------------------the main function body-----------------*/
void main()
{
DelayMs(1000);
UartInit();
UART1_SendString("STC15W204S\r\nUart is ok !\r\n");
DelayMs(1000);
ResetDataFlow();
WS2812_Close();
while(1)
{
mine(buf_data,m);
}
}
//--------------------------------------------------------------
// Name of the Sub-function: mine (unsigned char)
// Functioning:
void mine(unsigned char n,unsigned char m)
{
switch(n)
{
case 0x00:
if (m)
{
WS2812_1_5Line(blue_a,1);
Delay100Ms(5);
WS2812_Close();
WS2812_1_5Line(blue_b,2);
Delay100Ms(5);
WS2812_1_5Line(blue_c,3);
Delay100Ms(5);
WS2812_1_5Line(blue_d,4);
Delay100Ms(5);
WS2812_1_5Line(blue_e,5);
Delay100Ms(5);
}
void WS2812_Close(void)
{
unsigned char count_sum;
for(count_sum=0;count_sum<37;count_sum++)
{
SendOnePix(close);
}
ResetDataFlow();
}
void WS2812_1_5Line(unsigned char *p,unsigned char line)
{
unsigned char count_sum;
unsigned char m=1;
switch(line)
{
case 1:
for(count_sum=0;count_sum<=36;count_sum++)
{
if(count_sum==36)
{
SendOnePix(p);
}
else
SendOnePix(close);
}
ResetDataFlow();
break;
case 2:
for(count_sum=0;count_sum<36;count_sum++)
{
if(count_sum%6==0)
{
SendOnePix(p);
}
else
SendOnePix(close);
}
ResetDataFlow();
break;
case 3:
for(count_sum=0;count_sum<36;count_sum++)
{
if(count_sum%6==1)
{
SendOnePix(p);
}
else
SendOnePix(close);
}
ResetDataFlow();
break;
case 4:
for(count_sum=0;count_sum<36;count_sum++)//36¸öµÆÑ»·
{
if(count_sum%6==2)
{
SendOnePix(p);
}
else
SendOnePix(close);
}
ResetDataFlow();
break;
case 5:
for(count_sum=0;count_sum<36;count_sum++)//36¸öµÆÑ»·
{
if(count_sum==3*m)
{
SendOnePix(p);
}
else if(count_sum==(3*m)+1)
{
SendOnePix(p);
}
else if(count_sum==(3*m)+2)
{
SendOnePix(p);
m+=2;
}
else
SendOnePix(close);
}
m=1;
ResetDataFlow();
break;
}
}
代码点评:
本人用了马骥老师提供的函数:WS2812_1_5Line(unsigned char *p,unsigned char line), WS2812_Close(void), 以及ResetDataFlow(); UartInit()。