通过串口指令实现对两枚WS2812B全彩LED的控制

指令通过控制字和操作数两部分发送,每次只发送一部分(四个字节),先发控制字,再发操作数。全彩LED的控制字为“aled,操作数最高位为LED序号,0LED21LED3,低三位分别为RGB三个像素的亮度,每位可输入0-9中的一个数值,0为写灭,9为最亮。例如操作数为1530,即LED3红色像素亮度值为5,绿色像素亮度值为3,蓝色像素不亮。

引用头文件和库:

使用 #include <stc8h.h> 引用STC8H单片机的头文件。

使用 #include <intrins.h> 引用内置函数头文件。

使用 #include <stdio.h> 引用标准I/O头文件(尽管没有在代码中使用标准I/O功能)。

定义全局变量和宏定义:

定义了一系列全局变量,包括颜色数据、计数器、标志位等,用于存储颜色信息、接收到的数据和控制逻辑。

定义了宏 WB,用于控制数据传输时的输出引脚。

延时函数:

delay_300ns():延时约300纳秒,实际用途未在代码中使用。

Delay1us():延时约1微秒。

Delay350us():延时约350微秒。

Delay100ms():延时约100毫秒。

Delay300ms():延时约300毫秒。

串口1初始化函数 Uart1Init():

初始化串口1(UART1)以与外部设备通信,波特率设置为9600bps。

配置串口工作模式和波特率发生器,使其与定时器1关联。

启动定时器1以产生波特率时钟。

串口1中断处理函数 UartIsr():

当串口1接收到数据时,触发串口1中断。

在中断处理函数中,首先检查是否是发送中断(TI 标志位),如果是则清除 TI 并不执行任何操作。

如果是接收中断(RI 标志位),将接收到的数据存储在 temp_data 数组中,并根据接收的数据进行相应的操作。

control_RGB() 函数:

根据接收到的字符数据(temp_G、temp_R、temp_B)设置对应的颜色值(turn_G、turn_R、turn_B)。

该函数主要是将字符型颜色数据转换为整数类型颜色数据。

全彩LED控制函数:

RGB_Reset():重置RGB传输,通过控制 WB 引脚。

RGB_Send0() 和 RGB_Send1():用于将数据发送到全彩LED,通过控制 WB 引脚实现。

Send_GRB() 函数:

通过 EA 控制总中断来实现暂时关闭中断,然后发送颜色数据到全彩LED。

RGB_set_color() 函数:

根据指定的颜色数据设置全彩LED的颜色。

使用 _rgb_buf_R、_rgb_buf_G 和 _rgb_buf_B 缓冲区来存储颜色数据,然后通过 Send_GRB() 函数发送到RGB设备。

setup() 函数:

配置P0、P1和P5口为数字输入/输出口。

调用 Uart1Init() 函数以初始化串口1。

通过 RGB_Reset() 函数重置RGB传输。

main() 函数:

在 main() 函数中,首先调用 setup() 函数进行初始化设置。进入一个无限循环,不断执行以下操作:

调用 control_RGB() 函数,根据接收到的字符数据设置颜色信息。

使用 RGB_set_color() 函数设置全彩LED的颜色。

发送一个标志字符 't' 到串口1,以表示数据传输完成。

进行延时Delay100ms()。、

#include <stc8h.h>
#include <intrins.h>
#include <stdio.h>
#define WB P54
#define RGB_NUMLEDS 2 //LED个数

unsigned int  s_data;
typedef unsigned int uint;
typedef unsigned char uchar;
unsigned int num=0;
bit flag;

xdata uint _rgb_buf_R[RGB_NUMLEDS] = { 0 };//颜色缓存
xdata uint _rgb_buf_G[RGB_NUMLEDS] = { 0 };
xdata uint _rgb_buf_B[RGB_NUMLEDS] = { 0 };

	uchar GRB;
	uchar bit8 = 'G';
  uchar bit16 = 'R';
  uchar bit24 = 'B';

	uchar temp;
	uchar temp_num;
	uchar temp_G;
	uchar temp_R;
	uchar temp_B;
    uchar turn_num;
	uchar turn_G;
	uchar turn_R;
	uchar turn_B;
    char temp_data[4]={0};
	unsigned int t_num=0;


void RGB_set_color(uint num, uint r, uint g, uint b);



void delay_300ns(void)//test!!! 375ns
{
	//P14=1;//41ns
	_nop_();_nop_();
	//P14=0;//41ns
	
}
//
void Delay1us(void)	//@24.000MHz
{
  unsigned char data i;
	i = 6;
	while (--i);
}
//
void Delay350us(void)	//@24.000MHz
{
	unsigned char data i, j;

	_nop_();
	i = 11;
	j = 230;
	do
	{
		while (--j);
	} while (--i);
}
//
void Delay100ms(void)	//@24.000MHz
{
	unsigned char data i, j, k;

	_nop_();
	_nop_();
	i = 13;
	j = 45;
	k = 214;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
//
void Delay300ms(void)	//@24.000MHz
{
	unsigned char data i, j, k;

	_nop_();
	_nop_();
	i = 37;
	j = 135;
	k = 138;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
//


void Uart1Init(void)		//9600bps@24.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x8F;			//设置定时初始值
	TH1 = 0xFD;			//设置定时初始值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
}


void UartIsr() interrupt 4
{
	if(TI)
	{
		TI=0;
	}	
	
	P11=1;
	P00=~P00;
	if(RI)
	{
		
		RI=0;
 
		if(t_num<4)
		{
			//flag=0;
			temp_data[t_num]=SBUF;
			t_num++;
			
		}
		
		if(t_num==4)
		{
			
			//flag=1;
			
		}
		
		if(t_num==4)
	{
		
		turn_num=temp_data[0]-'0';
		temp_G=temp_data[1];
		temp_R=temp_data[2];
		temp_B=temp_data[3];
		t_num=0;
		SBUF='t';
		
	}

}

  P11=0;
}

void control_RGB()
{

	
	if(temp_G=='0')
	{
		turn_G=0;
	}
	else if(temp_G=='1')
	{
		turn_G=28;
	}
	else if(temp_G=='2')
	{
		turn_G=57;
	}
	else if(temp_G=='3')
	{
		turn_G=85;
	}
	else if(temp_G=='4')
	{
		turn_G=113;
	}
	else if(temp_G=='5')
	{
		turn_G=142;
	}
	else if(temp_G=='6')
	{
		turn_G=170;
	}
	else if(temp_G=='7')
	{
		turn_G=198;
	}
	else if(temp_G=='8')
	{
		turn_G=227;
	}
	else if(temp_G=='9')
	{
		turn_G=255;
	}

	
		if(temp_R =='0')
	{
		turn_R =0;
	}
	else if(temp_R =='1')
	{
		turn_R =28;
	}
	else if(temp_R =='2')
	{
		turn_R =57;
	}
	else if(temp_R =='3')
	{
		turn_R =85;
	}
	else if(temp_R =='4')
	{
		turn_R =113;
	}
	else if(temp_R =='5')
	{
		turn_R =142;
	}
	else if(temp_R =='6')
	{
		turn_R =170;
	}
	else if(temp_R =='7')
	{
		turn_R =198;
	}
	else if(temp_R =='8')
	{
		turn_R =227;
	}
	else if(temp_R =='9')
	{
		turn_R =255;
	}


		if(temp_B=='0')
	{
		turn_B=0;
	}
	else if(temp_B=='1')
	{
		turn_B=28;
	}
	else if(temp_B=='2')
	{
		turn_B=57;
	}
	else if(temp_B=='3')
	{
		turn_B=85;
	}
	else if(temp_B=='4')
	{
		turn_B=113;
	}
	else if(temp_B=='5')
	{
		turn_B=142;
	}
	else if(temp_B=='6')
	{
		turn_B=170;
	}
	else if(temp_B=='7')
	{
		turn_B=198;
	}
	else if(temp_B=='8')
	{
		turn_B=227;
	}
	else if(temp_B=='9')
	{
		turn_B=255;
	}

	
	
}
//





void RGB_Reset(void)
{
	WB=0;
	Delay350us();
}
//

void RGB_Send0()
{
	WB=1;
	delay_300ns();
	WB=0;
	Delay1us();
}
//

void RGB_Send1()
{
	WB=1;
	Delay1us();
	WB=0;
	delay_300ns();//or 320ns
}


void RGB_Send_Data(uint s_data) 
{ 
   uint i;
	 P12=1;
   for(i=8;i>0;i--) 
   {
     if(s_data & 0x80)//按位与,为真发送1,为假发送零
     {
        RGB_Send1();
     }
     else
     {
        RGB_Send0();
     }
     s_data<<=1;
   }
	 P12=0;
}
//


void Send_GRB(uint G,uint R,uint B)
{
	EA=0;
	P13=1;
	//RGB_Reset();
	RGB_Send_Data(G);
	RGB_Send_Data(R);
	RGB_Send_Data(B);
	//RGB_Reset();
	P13=0;
	EA=1;
}
//



void RGB_set_color(uint num, uint r, uint g, uint b)//设置指定点的显示颜色
{

uint i;
P14=1;
for (i = 0; i < RGB_NUMLEDS; i++)
{
 _rgb_buf_R[num] = r;//缓冲
 _rgb_buf_G[num] = g;
 _rgb_buf_B[num] = b;
}
for (i = 0; i < RGB_NUMLEDS; i++)
{
 Send_GRB(_rgb_buf_G[i], _rgb_buf_R[i], _rgb_buf_B[i]);//发送显示
}

  P14=0;
}

void setup()
{
  
	P0M1=0x00;
	P0M0=0x00;
	P1M1=0x00;
	P1M0=0x00;
	P5M1=0x00;
	P5M0=0x00;
	P1=0x00;
	Uart1Init();
	RGB_Reset();
	ES=1;
	EA=1;
	

	
}



void main()
{
	setup();
	while(1)
	{
		P15=1;
		
    control_RGB();
		//RGB_Reset();
		SBUF=turn_num+'0';
		RGB_set_color(turn_num,turn_G,turn_R,turn_B);
//		RGB_set_color(0,0,255,0);
//		RGB_set_color(1,255,0,0);
		
		Delay100ms();
		P15=0;
		

		
		
		
		
		
	};
	
}



















  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值