lpd6803 light.c

来自「本程序使用STC单片机控制LPD6803驱动LED全彩灯具产生各式变化」· C语言 代码 · 共 321 行

C
321
字号
#include "reg52.h"
#include "intrins.h"
//                       LPD6083程序
//软件说明:
//软件版本: V1.0
//制作时间: 2008-2-26
//作者:    
//使用AT89C54
//实现各种图形变化
//连接示意图
//O┈O--O--O--O--O--O--O
//                     │
//O--O--O--O--O--O--O--O
//│
//O--O--O--O--0--O--O--O
//                     │
//O--O--O--O--O--O--O--O
//│
//O--O--O--O--O--O--O--O
//                     │
//O--O--O--O--O--O--O--O
//│
//O--O--O--O--O--O--O--O
//                     │
//O--O--O--O--O--O--O--O
typedef unsigned char BYTE;
//引脚定义
sbit SDO=P1^2; //数据引脚
sbit SCLK=P1^3;//时钟引脚
sbit DOG=P1^7;//看门狗(MAX691)
//数据表,每样花样一个数据表——注:因为为S形连接,所以1、3、5、7行数据不变,2、4、6、8行数据镜像对调

code BYTE taba[]={
4,0,0,8,0,0,12,0,0,16,0,0,      20,0,0,24,0,0,28,0,0,31,0,0,
4,4,0,8,8,0,12,12,0,16,16,0,    20,20,0,24,24,0,28,28,0,31,31,0,
0,4,0,0,8,0,0,12,0,0,16,0,      0,20,0,0,24,0,0,28,0,0,31,0,
0,4,4,0,8,8,0,12,12,0,16,16,    0,20,20,0,24,24,0,28,28,0,31,31,
0,0,4,0,0,8,0,0,12,0,0,16,      0,0,20,0,0,24,0,0,28,0,0,31,
4,0,4,8,0,8,12,0,12,16,0,16,    20,0,20,24,0,24,28,0,28,31,0,31,
4,4,4,8,8,8,12,12,12,16,16,16,  20,20,20,24,24,24,28,28,28,31,31,31,

4,0,0,8,0,0,12,0,0,16,0,0,      20,0,0,24,0,0,28,0,0,31,0,0,
4,4,0,8,8,0,12,12,0,16,16,0,    20,20,0,24,24,0,28,28,0,31,31,0,
0,4,0,0,8,0,0,12,0,0,16,0,      0,20,0,0,24,0,0,28,0,0,31,0,
0,4,4,0,8,8,0,12,12,0,16,16,    0,20,20,0,24,24,0,28,28,0,31,31,
0,0,4,0,0,8,0,0,12,0,0,16,      0,0,20,0,0,24,0,0,28,0,0,31,
4,0,4,8,0,8,12,0,12,16,0,16,    20,0,20,24,0,24,28,0,28,31,0,31,
4,4,4,8,8,8,12,12,12,16,16,16,  20,20,20,24,24,24,28,28,28,31,31,31,

4,0,0,8,0,0,12,0,0,16,0,0,      20,0,0,24,0,0,28,0,0,31,0,0,
4,4,0,8,8,0,12,12,0,16,16,0,    20,20,0,24,24,0,28,28,0,31,31,0,
0,4,0,0,8,0,0,12,0,0,16,0,      0,20,0,0,24,0,0,28,0,0,31,0,
0,4,4,0,8,8,0,12,12,0,16,16,    0,20,20,0,24,24,0,28,28,0,31,31,
0,0,4,0,0,8,0,0,12,0,0,16,      0,0,20,0,0,24,0,0,28,0,0,31,
4,0,4,8,0,8,12,0,12,16,0,16,    20,0,20,24,0,24,28,0,28,31,0,31,
4,4,4,8,8,8,12,12,12,16,16,16,  20,20,20,24,24,24,28,28,28,31,31,31
				};


void watchdog()
{
	_nop_();
	DOG=0;
	_nop_();
	DOG=1;
	_nop_();
	DOG=0;
}

void delay(unsigned int n) //延时程序
{
	BYTE t,y;
    for(;n>0;n--)
        for(t=0;t<10;t++)
		{
		   for(y=0;y<40;y++);
		   watchdog();
		}
}

void Outone(BYTE dr,BYTE dg,BYTE db)//输出3个5位RGB颜色数据子程序,参数格式:红颜色数据、
                                    //绿颜色数据、蓝颜色数据
{   BYTE k,mask;
      //首先输出1个'1'起始位
    SDO=1;SCLK=1;SCLK=0;
      //输出5位红色数据
    mask=0x10;
    for(k=0;k<5;k++)
    {    if(mask & dr)    SDO=1;
         else             SDO=0;
         SCLK=1;SCLK=0;
         mask>>=1;      }
    //输出5位绿色数据
    mask=0x10;
    for(k=0;k<5;k++)
    {   if(mask & dg)   SDO=1;
        else            SDO=0;
        SCLK=1;SCLK=0;
        mask>>=1;       }
    //输出5位兰色数据
    mask=0x10;
    for(k=0;k<5;k++)
    {   if(mask & db)   SDO=1;
        else            SDO=0;
        SCLK=1;SCLK=0;
        mask>>=1;       }
}

void BrushOut(BYTE nDots,BYTE dr,BYTE dg,BYTE db)//输出ndots点相同灰度颜色子程序,参数格式:点数、红颜色数据、
                                                 //绿颜色数据、蓝颜色数据
{
   BYTE i;
// SDO,SCLK为数据和移位输出口,位变量,nDots为灯的个数
// 本程序仅适用于GMODE=1,CMODE=1的情况
// 首先输出32个'0'的起始帧
    SCLK=0;
    SDO=0;
    for(i=0;i<32;i++) { SCLK=1;SCLK=0; }
// 再输出nDots点的数据,这里假设各点的颜色都是(dr,dg,db)
// dr,db,dg为红绿兰的灰度值0-31
    for(i=0;i<nDots;i++)
    {   Outone(dr,dg,db);
    }
    //输出完nDots的数据后,还要补nDots个脉冲
    SDO=0;
    for(i=0;i<nDots;i++) { SCLK=1;SCLK=0; }
    //传输结束
}

//任意颜色灰度转化程序,参数形式:点数、间隔时间、红开始色灰度、绿开始色灰度、蓝开始色灰度、
//红结束色灰度、绿结束色灰度、蓝结束色灰度
void Jianbian(BYTE nDots,BYTE ntime,BYTE hr,BYTE hg,BYTE hb,BYTE br,BYTE bg,BYTE bb)
{   BYTE f,dr=0,dg=0,db=0,fr=0,fg=0,fb=0;
     for(f=0;f<31;f++)
        {
		if (fr!=1)   //红色渐变控制
            {
		      if(hr<br)
			   {
                  if(br<=hr+f) fr=1;
                  else dr=hr+f;
               }
			   else
			   	 if(hr>br)
			   		{
                  		if(br>=hr-f) fr=1;
                  		else dr=hr-f;
			    	}
				 else dr=hr;
			 }

		if (fg!=1)   //绿色渐变控制
            {
		      if(hg<bg)
			   {
                  if(bg<=hg+f) fg=1;
                  else dg=hg+f;
               }
			   else
			   	 if(hg>bg)
			   		{
                  		if(bg>=hg-f) fg=1;
                  		else dg=hg-f;
			    	}
				 else dg=hg;
			 }

		if (fb!=1)   //红色渐变控制
            {
		      if(hb<bb)
			   {
                  if(bb<=hb+f) fb=1;
                  else db=hb+f;
               }
			   else
			   	 if(hb>bb)
			   		{
                  		if(bb>=hb-f) fb=1;
                  		else db=hb-f;
			    	}
				 else db=hb;
			 }

           if(fr==1 && fg==1 && fb==1) f=30;
           BrushOut(nDots,dr,dg,db);
           delay(ntime);
        }
}

void zzjb(BYTE nDots,BYTE n)
{
   BYTE i;
// SDO,SCLK为数据和移位输出口,位变量,nDots为灯的个数
// 本程序仅适用于GMODE=1,CMODE=1的情况
// 首先输出32个'0'的起始帧
    SCLK=0;
    SDO=0;
    for(i=0;i<32;i++) { SCLK=1;SCLK=0; }
// 再输出nDots点的数据,这里假设各点的颜色都是(dr,dg,db)
// dr,db,dg为红绿兰的灰度值0-31

    for(i=n;i<nDots;i++)
    {
		Outone(taba[i*3],taba[i*3+1],taba[i*3+2]);
    }
	if(n>0)
	{
		for(i=0;i<n;i++)
	{
		Outone(taba[i*3],taba[i*3+1],taba[i*3+2]);
	}
	}
    //输出完nDots的数据后,还要补nDots个脉冲
    SDO=0;
    for(i=0;i<nDots;i++) { SCLK=1;SCLK=0; }
    //传输结束
}

//从上到下追逐,参数形式:点数、间隔时间、红前景色灰度、绿前景色灰度、蓝前景色灰度、
//红背色灰度、绿背景色灰度、蓝背景色灰度
void Runagaindown(BYTE nDots,BYTE ntime,BYTE hr,BYTE hg,BYTE hb,BYTE br,BYTE bg,BYTE bb)
{   BYTE i,j,f,e;
    for (i=1;i<nDots+1;i++)
	{ // 首先输出32个'0'的起始帧
	 SCLK=0;
         SDO=0;
    for(f=0;f<32;f++) { SCLK=1;SCLK=0; }
	for(j=1;j<nDots+1;j++)
	{
	  if(j<=i)
	  Outone(hr,hg,hb);
	  else Outone(br,bg,bb);
	 }
	  //输出完nDots的数据后,还要补nDots个脉冲
    SDO=0;
    for(e=0;e<nDots;e++) { SCLK=1;SCLK=0; }
    delay(ntime);
	}
}

//向中间追逐,参数形式:点数、间隔时间、红前景色灰度、绿前景色灰度、蓝前景色灰度、
//红背色灰度、绿背景色灰度、蓝背景色灰度
void Runagainin(BYTE nDots,BYTE ntime,BYTE hr,BYTE hg,BYTE hb,BYTE br,BYTE bg,BYTE bb)
{   BYTE i,j,f,e;
    for (i=1;i<=(nDots+1)/2;i++)
	{
	 SCLK=0;
         SDO=0;
    for(f=0;f<32;f++) { SCLK=1;SCLK=0; }
	for(j=1;j<nDots+1;j++)
	{
	  if(j<=i || j>=nDots+1-i)
	  Outone(hr,hg,hb);
	  else Outone(br,bg,bb);
	 }
	  //输出完nDots的数据后,还要补nDots个脉冲
    SDO=0;
    for(e=0;e<nDots;e++) { SCLK=1;SCLK=0; }
    //传输结束
    delay(ntime);
	}
}
//从下到上追逐,参数形式:点数、间隔时间、红前景色灰度、绿前景色灰度、蓝前景色灰度、
//红背色灰度、绿背景色灰度、蓝背景色灰度
void Runagainup(BYTE nDots,BYTE ntime,BYTE hr,BYTE hg,BYTE hb,BYTE br,BYTE bg,BYTE bb)
{   BYTE i,j,f,e;
    for (i=nDots;i>0;i--)//从尾到头跑
	{
	 SCLK=0;
         SDO=0;
    for(f=0;f<32;f++) { SCLK=1;SCLK=0; }
	for(j=1;j<nDots+1;j++)
	{
	  if(j<=i)
	  Outone(hr,hg,hb);
	  else Outone(br,bg,bb);
	 }
	  //输出完nDots的数据后,还要补nDots个脉冲
    SDO=0;
    for(e=0;e<nDots;e++) { SCLK=1;SCLK=0; }
    delay(ntime);
	}
}

main()
{   BYTE nDots,Dots,i,ntimea,ntimeb,ntimec;
    BYTE n;
    nDots=168;
    Dots=145;
    ntimea=20;ntimeb=50;ntimec=6;//调节每帧数据时间参数
    while(1)
    {
    for(i=0;i<2;i++)
	{
		for(n=nDots;n>0;n--)
			{
			    zzjb(nDots,n);
		            delay(ntimea);
			}
	}
	Jianbian(nDots,ntimeb, 0, 0, 0,    31, 0, 0);
    	Jianbian(nDots,ntimeb,31, 0, 0,    31,31, 0);
    	Jianbian(nDots,ntimeb,31,31, 0,     0,31, 0);
    	Jianbian(nDots,ntimeb, 0,31, 0,     0,31,31);
    	Jianbian(nDots,ntimeb, 0,31,31,     0, 0,31);
    	Jianbian(nDots,ntimeb, 0, 0,31,    31, 0,31);
    	Jianbian(nDots,ntimeb,31, 0,31,    31,31,31);
        //七彩追逐
    	Runagaindown(Dots,ntimec,31,0,0,  0,0,0);
	Runagainup  (Dots,ntimec,0,31,0,  0,0,0);
	Runagainin  (Dots,ntimec,0,0,31,  0,0,0);
	Runagaindown(Dots,ntimec,31,0,0,  0,0,31);
	Runagainup  (Dots,ntimec,0,31,0,  31,0,0);
	Runagainin  (Dots,ntimec,31,31,0, 0,31,0);
	Runagaindown(Dots,ntimec,0,31,31, 31,31,0);
	Runagainup  (Dots,ntimec,31,0,31, 0,31,31);
        Runagainin  (Dots,ntimec,0,0,0,   31,0,31);
   }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?