15W408AS驱动WS2812全彩LED
用15W408AS单片机驱动WS2812 ,使用内部晶振11.0592M.完全没问题。SPI方案:
只用到MOSI驱动WS2812,但由于SPI的3个信号是捆绑在一起的,MISO、SCLK不能做它用。本例使用P1.3-MOSI输出驱动信号,用户可以切换到别的脚。
===将 MISO 不做其他用途;
===将 MISO管脚 先设置为对外输出0;
===MOSI 发送完成后,对外停止时输出的是 MISO 读到的状态, 0 ,这 STC-R&D 留了这么个绝活支持 WS2812B !!!
我是小白,改成了触摸一下,切换一下灯的颜色,但是第二个灯,第三个灯的通讯起来,DO口输出是一直5V,不知道怎么改 代码是参考论坛另外一个人的。
#include <stc15.h>
#include <intrins.h>
typedef struct
{
unsigned char Value;
unsigned char Press;
unsigned short Count;
}KEY_Type;
void send_color(unsigned char r, unsigned char g, unsigned char b);
void send_byte(unsigned char byte_val);
void send_bit(unsigned char bit_val);
void sw(unsigned char y);
void update_led_strip();
void Delay350us();
void Delay1ms();
void ledaa();
void ledbb();//红光闪烁
void ledcc();
void leddd();//绿光闪烁
void ledee();//蓝光闪烁
void ledObb();//红光常亮
void ledOdd();//绿光常亮
void ledOee();//蓝光常亮
void ledOyy();//黄光常亮
void Key_Read(void);
void Key_Task(void);
// 定义端口
sbit LED = P3^4;
sbit KEYP = P3^2;// 按键引脚
unsigned int y;
unsigned char Trg;
unsigned char Cont;
unsigned char flag = 0;
unsigned char count = 0; // 按键计数器
KEY_Type Key;
unsigned char code led[]={
//7种颜色的光亮
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x00, 0x01, 0x02, 0x03, //32
//红色的光亮
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, //64
//绿色的光亮
0x07, 0x07, 0x01, 0x01, 0x07, 0x07, 0x01,
0x01, 0x07, 0x07, 0x01, 0x01, 0x07, 0x07,
0x01, 0x01, 0x07, 0x07, 0x01, 0x01, 0x07,
0x07, 0x01, 0x01, 0x07, 0x07, 0x01, 0x01,
0x07, 0x07, 0x07, 0x07, //96
//蓝色的光亮
0x02, 0x02, 0x02, 0x02, 0x07, 0x07, 0x07,
0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x07,
0x07, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07,
0x07, 0x07, 0x07, 0x02, 0x02, 0x02, 0x02,
0x07, 0x07, 0x07, 0x07, //128
//黄色的光亮
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, //160
//洋红色的光亮
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, //192
//青色的光亮
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, //224
//白色的光亮
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, //256
//不亮
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07 //288
};
// 主函数
void main()
{
P3M1 &= ~0x04;// 设置P3.2为准双向口模式(输入模式)
P3M0 &= ~0x04;// 确保P3.2不是开漏输出模式
while(1) // 进入无限循环
{
// 读取按键状态
if (KEYP == 1) {// 如果按键被按下
flag = 1; // 设置标志变量为1
count = (count + 1) % 3; // 按键按下时增加计数器,并取模3以实现颜色切换
} else {
flag = 0; // 如果按键未被按下,设置标志变量为0
}
// 根据计数器的值决定LED灯带颜色
switch(count) {
case 0:
ledObb(); // 红光常亮
break;
case 1:
ledOee(); // 蓝光常亮
break;
case 2:
ledOdd(); // 绿光常亮
break;
case 3:
ledOyy(); // 黄光常亮
break;
}
// 更新LED灯带
update_led_strip();
}
}
//遍历七彩,红,绿,蓝,黄,洋红,靑,白,不亮
void ledaa()
{
unsigned int n, i, j;
for(n=0; n<256; n++)
{
// 遍历每个LED灯珠
for(j=0; j<64; j++)
{
//指定颜色值
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<100; i++)
{
Delay1ms();
}
}
}
//颜色值
void sw(unsigned char y)
{
switch(y)
{
case 0: send_color(0xff, 0x00, 0x00); break;//红
case 1: send_color(0x00, 0xff, 0x00); break;//绿
case 2: send_color(0x00, 0x00, 0xff); break;//蓝
case 3: send_color(0xff, 0xff, 0x00); break;//黄
case 4: send_color(0xff, 0x00, 0xff); break;//洋红
case 5: send_color(0x00, 0xff, 0xff); break;//靑
case 6: send_color(0xff, 0xff, 0xff); break;//白
case 7: send_color(0x00, 0x00, 0x00); break;//不亮
default : break;
}
}
//红光闪烁
void ledbb()
{
unsigned int a, b, c, i;
for(a=0; a<10; a++)
{
for(b=32; b<64; b++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<200; i++)
{
Delay1ms();
}
for(c=256; c<289; c++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<200; i++)
{
Delay1ms();
}
}
}
//蓝光闪烁
void ledee()
{
unsigned int a, b, c, i;
for(a=0; a<10; a++)
{
for(b=64; b<96; b++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<150; i++)
{
Delay1ms();
}
for(c=256; c<289; c++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<150; i++)
{
Delay1ms();
}
}
}
//绿光闪烁
void leddd()
{
unsigned int a, b, c, i;
for(a=0; a<10; a++)
{
for(b=96; b<128; b++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<200; i++)
{
Delay1ms();
}
for(c=256; c<289; c++)
{
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时
for(i=0; i<200; i++)
{
Delay1ms();
}
}
}
// 红光常亮
void ledObb()
{
unsigned int b;
// 点亮LED灯带的红光部分
for(b = 32; b < 64; b++)
{
y = led;
sw(y);
}
// 更新LED灯带
update_led_strip();
}
// 蓝光常亮
void ledOee()
{
unsigned int b;
// 点亮LED灯带的绿光部分
for(b = 64; b < 96; b++)
{
y = led;
sw(y);
}
// 更新LED灯带
update_led_strip();
}
// 另一个绿光常亮(假设这部分代码也是用于常亮)
void ledOdd()
{
unsigned int b;
// 点亮LED灯带的另一部分绿光
for(b = 96; b < 128; b++)
{
y = led;
sw(y);
}
// 更新LED灯带
update_led_strip();
}
// 黄光常亮(假设这部分代码也是用于常亮)
void ledOyy()
{
unsigned int b;
// 点亮LED灯带的另一部分绿光
for(b = 128; b < 160; b++)
{
y = led;
sw(y);
}
// 更新LED灯带
update_led_strip();
}
// 洋红常亮(假设这部分代码也是用于常亮)
void ledOyr()
{
unsigned int b;
// 点亮LED灯带的另一部分绿光
for(b = 160; b < 192; b++)
{
y = led;
sw(y);
}
// 更新LED灯带
update_led_strip();
}
//遍历不亮,白,靑,洋红,黄,蓝,绿,红,七彩
void ledcc()
{
unsigned int n, i, j;
for(n=256; n>=0; n--)
{
// 遍历每个LED灯珠
//for(j=0; j<64; j++)
for(j=0; j<96; j++)
{
//指定颜色值
y=led;
sw(y);
}
// 更新LED灯带
update_led_strip();
// 延时一秒
for(i=0; i<100; i++)
{
Delay1ms();
}
}
}
// 发送一个比特
void send_bit(unsigned char bit_val)
{
if(bit_val)
{
// 发送逻辑1
LED = 1;
_nop_();_nop_();_nop_();
LED = 0;
_nop_();
}
else
{
// 发送逻辑0
LED = 1;
_nop_();
LED = 0;
_nop_();_nop_();_nop_();
}
}
// 发送一个字节
void send_byte(unsigned char byte_val)
{
unsigned char i;
for(i=0; i<8; i++)
{
send_bit(byte_val & (0x80 >> i)) ;
}
}
// 发送颜色值
void send_color(unsigned char r, unsigned char g, unsigned char b)
{
send_byte(g);
send_byte(r);
send_byte(b);
}
// 更新LED灯带
void update_led_strip()
{
LED = 0;
Delay350us();
}
void Delay350us() //@11.0592MHz
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 4;
j = 192;
do
{
while (--j);
} while (--i);
}
void Delay1ms() //@11.0592MHz
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
页:
[1]