/*
IRC15F107W 管脚(默认内部震荡源24Mhz)
1 P3.4
2 VCC 3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3
*/
#include "reg52.h"
#include "intrins.h"
#define WS2812_NUM 60
sbit Led_Pin = P3^0;
unsigned short G_0=191;
unsigned short R_0=98;
unsigned short B_0=10;
unsigned short G_1=11;
unsigned short B_1=45;
unsigned short R_1=14;
void delay_ms(unsigned int ms) //@24.000MHz
{
unsigned char data i, j;
while(ms--){
_nop_();
i = 24;
j = 85;
do
{
while (--j);
} while (--i);
}
}
void Delay75us(void) //@24.000MHz
{
unsigned char data i, j;
i = 2;
j = 189;
do
{
while (--j);
} while (--i);
}
void ws2812_writebit1(void){
Led_Pin=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//调整此行可注释掉
Led_Pin=!Led_Pin;
//_nop_();_nop_();_nop_();
}
void ws2812_writebit0(void){
Led_Pin=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Led_Pin=!Led_Pin;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();//调整此行可注释掉
}
void ws2812_writecolor(unsigned short dat){
//由于STC8G1K08执行左移或者右移等移位操作耗时太久(2us,无符号短整型都这样),导致时序严重落后,所以用原始的if-else代码进行代替
if(dat&0x80)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x40)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x20)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x10)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x08)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x04)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x02)
ws2812_writebit1();
else
ws2812_writebit0();
if(dat&0x01)
ws2812_writebit1();
else
ws2812_writebit0();
}
void ws2812_writeled(unsigned short green,unsigned short red,unsigned short blue){
ws2812_writecolor(green);
ws2812_writecolor(red);
ws2812_writecolor(blue);
}
void ws2812_rest()
{
Led_Pin=0;
Delay75us();
}
void ws2812_clear()
{
static int j=0;
for(j=0;j<WS2812_NUM;j++)
{
ws2812_writeled(0,0,0);
}
ws2812_rest();
ws2812_rest();
ws2812_rest();
}
void WS2812_DIS()
{
static int j=0;
int i;
j%=WS2812_NUM;
j++;
for(i=0;i<WS2812_NUM;i++)
{
if(i>j&&(i<j+10))
{
ws2812_writeled(G_0,R_0,B_0);
}
else
{
ws2812_writeled(G_1,R_1,B_1);
}
}
}
void main(void)
{
ws2812_clear();
while(1)
{
WS2812_DIS();
delay_ms(50);
}
}