STC8G1K08A驱动WS2812八个灯珠实现开机启动扫描效果

整个工程所有文件代码如下
main.c

#include "ws2812.h"
#include"timer.h"



/*功能说明
单片机8G1K08
WS2812引脚接P5.5
烧录时晶振选22.1184M
*/


void main(  )
{
	unsigned char i=0;
	Ws2812Init();
	cmdWorkCnt=forNumber;
	for(i=0;i<taskNumber;i++) 
	{
		if(taskLed[i]>max) 
		{
			max=taskLed[i];
		}
	}
	refreshNumber=max;
	AUXR=0x00;
	WriteRgbNumber(refreshNumber,BLACK);
	Ws2812Refresh(refreshNumber);
	ConfigTimer0(1);
	WDT_CONTR = 0x25;//使能看门狗,溢出时间约为1.1s	
	EA=1;

	while( 1 )	
	{
		WDT_CONTR = 0x35; 	//清看门狗,溢出时间约为1.1s

		
		if( (cmdWorkCnt>0)&&(cmdNumber==0)&&(Number_Down[Wait_delay]==0) )
		{
			if(cmdWorkCnt!=0xFF)cmdWorkCnt--;
			cmdNumber=taskNumber;
			taskStep=0;
			refreshNumber=0;
		}


		if(cmdNumber>0)//1
		{						
			if(Number_Down[Wait_delay]==0)2
			{				
				if(taskLed[taskStep]<=LED_MAX)//3
				{													
					if(taskLed[taskStep]==0)//4
					{
						refreshNumber=max;//接下来刷新最大数量
						WriteRgbNumber(refreshNumber,taskColorR[taskStep],taskColorG[taskStep],taskColorB[taskStep]);																	
					}else  
					{
						if(taskLed[taskStep]>refreshNumber)refreshNumber=taskLed[taskStep];
						WriteRgbOne(taskLed[taskStep],taskColorR[taskStep],taskColorG[taskStep],taskColorB[taskStep]);																	
					}///4								
				}/3
				Number_Down[Wait_delay]=taskWaitTime[taskStep];
				taskStep++;//4
				cmdNumber--;
				styleFig=1;
			}//2

		}/1
	
	
		if(Number_Down[WsOut_delay]==0)
		{
			if(styleFig==1) 
			{
				styleFig=0;
				if(refreshNumber>0)Ws2812Refresh(refreshNumber);
				refreshNumber=0;//清0刷新数
				对需要点亮的灯珠进行输出  降低开销				
			}
		}


		
	}
	
}


config.h

#ifndef __CONFIG_H
#define __CONFIG_H
#include 
#include 
#include "string.h"


#define FOSC 22118400L

#define TASK_MAX 92

typedef unsigned char u8;//给8位数据类型unsigned char取个名字
typedef unsigned int u16;//给16位数据类型unsigned int取个名字

enum //延时任务枚举  最后参数不要加,
{
	 Wait_delay,
    WsOut_delay,
    Time_Delay

};
#define Down_Task  (Time_Delay+1)//向下减数组长度
extern unsigned int Number_Down[Down_Task];     //延时-- 数组




sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P3M0 = 0xb2;
sfr P3M1 = 0xb1;
sfr P5M0 = 0xca;
sfr P5M1 = 0xc9;
sfr P5=0xC8;
sfr WDT_CONTR = 0xc1;
//sfr AUXR=0x8E;

#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80


//GPIO封装
#define GPIOP0 0x00
#define GPIOP1 0x01
#define GPIOP2 0x02
#define GPIOP3 0x03
#define GPIOP4 0x04
#define GPIOP5 0x05

#define GPIO_Mode_Out_IN 0x00//M1:M0=00为准双向口 01为推挽 10为高阻 11为开漏
#define GPIO_Mode_Out_PP 0x01
#define GPIO_Mode_AIN 0x02 
#define GPIO_Mode_Out_OD 0x03

#define PIN_0 0x01
#define PIN_1 0x02
#define PIN_2 0x04
#define PIN_3 0x08
#define PIN_4 0x10
#define PIN_5 0x20
#define PIN_6 0x40
#define PIN_7 0x80
#define PIN_L4 0x0F
#define PIN_H4 0xF0
#define PIN_ALL 0xFF
//GPIO封装


sfr IPH = 0xB7;
sfr     INTCLKO =   0x8f;
sfr AUXINTIF=0xEF;

sfr     T2L     =   0xd7;
sfr     T2H     =   0xd6;
sfr     IE2     =   0xaf;
#define ET2         0x04
#define T2IF        0x01





void SetGpioMode(unsigned char gpio,unsigned char pin,unsigned char mode);//设置GPIO模式
void IoModeInit();//IO口模式初始化
void TaskDelay();//延时 
#endif

config.c

#include "config.h"

//引脚配置数据缓存
/*
unsigned char P0M1Buf=0;
unsigned char P0M0Buf=0;
*/
unsigned char P1M1Buf=0;
unsigned char P1M0Buf=0;
/*
unsigned char P2M1Buf=0;
unsigned char P2M0Buf=0;
*/
unsigned char P3M1Buf=0;
unsigned char P3M0Buf=0;
/*
unsigned char P4M1Buf=0;
unsigned char P4M0Buf=0;
*/
unsigned char P5M1Buf=0;
unsigned char P5M0Buf=0;
//引脚配置数据缓存

unsigned int Number_Down[Down_Task];     //延时-- 数组
/*******************************************************************************
* 函数功能 : 任务延时
* 函数说明 : 中断1ms调用一次
*******************************************************************************/

void TaskDelay()
{
    unsigned char i;

    for(i = 0; i < Down_Task; i++)
    {
        if(Number_Down[i])//不为0就--
        {
            Number_Down[i]--; //不为0就--
        }
    }
}


void SetGpioMode(unsigned char gpio,unsigned char pin,unsigned char mode)//设置GPIO模式  自己写的函数  为了方便配置引脚
{
/*
	if(gpio==0)
	{
		if(mode==0)//准双向
		{
			P0M1Buf&=~pin;// M1:M0=00为准双向口
			P0M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P0M1Buf&=~pin;// M1:M0=01为推挽
			P0M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P0M1Buf|=pin;// M1:M0=10为高阻
			P0M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P0M1Buf|=pin;// M1:M0=11为开漏
			P0M0Buf|=pin;//
		}
	}else */if(gpio==1)
	{
		if(mode==0)//准双向
		{
			P1M1Buf&=~pin;// M1:M0=00为准双向口
			P1M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P1M1Buf&=~pin;// M1:M0=01为推挽
			P1M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P1M1Buf|=pin;// M1:M0=10为高阻
			P1M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P1M1Buf|=pin;// M1:M0=11为开漏
			P1M0Buf|=pin;//
		}
	}/*else if(gpio==2)
	{
		if(mode==0)//准双向
		{
			P2M1Buf&=~pin;// M1:M0=00为准双向口
			P2M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P2M1Buf&=~pin;// M1:M0=01为推挽
			P2M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P2M1Buf|=pin;// M1:M0=10为高阻
			P2M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P2M1Buf|=pin;// M1:M0=11为开漏
			P2M0Buf|=pin;//
		}
	}*/else if(gpio==3)
	{
		if(mode==0)//准双向
		{
			P3M1Buf&=~pin;// M1:M0=00为准双向口
			P3M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P3M1Buf&=~pin;// M1:M0=01为推挽
			P3M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P3M1Buf|=pin;// M1:M0=10为高阻
			P3M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P3M1Buf|=pin;// M1:M0=11为开漏
			P3M0Buf|=pin;//
		}
	}/*else if(gpio==4)
	{
		if(mode==0)//准双向
		{
			P4M1Buf&=~pin;// M1:M0=00为准双向口
			P4M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P4M1Buf&=~pin;// M1:M0=01为推挽
			P4M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P4M1Buf|=pin;// M1:M0=10为高阻
			P4M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P4M1Buf|=pin;// M1:M0=11为开漏
			P4M0Buf|=pin;//
		}
	}*/else if(gpio==5)
	{
		if(mode==0)//准双向
		{
			P5M1Buf&=~pin;// M1:M0=00为准双向口
			P5M0Buf&=~pin;//
		}else if(mode==1)//推挽
		{
			P5M1Buf&=~pin;// M1:M0=01为推挽
			P5M0Buf|=pin;//
		}else if(mode==2)//模拟输入
		{
			P5M1Buf|=pin;// M1:M0=10为高阻
			P5M0Buf&=~pin;//
		}else if(mode==3)//开漏
		{
			P5M1Buf|=pin;// M1:M0=11为开漏
			P5M0Buf|=pin;//
		}
	}

}

void IoModeInit()//IO口模式初始化
{
	P1M1=P1M1Buf;// M1:M0=00为准双向口 01为推挽 10为高阻 11为开漏
	P1M0=P1M0Buf;//
	P3M1=P3M1Buf;// M1:M0=00为准双向口 01为推挽 10为高阻 11为开漏
	P3M0=P3M0Buf;//
	P5M1=P5M1Buf;// M1:M0=00为准双向口 01为推挽 10为高阻 11为开漏
	P5M0=P5M0Buf;//
}

timer.h

#ifndef __TIMER_H
#define __TIMER_H
#include"config.h"

extern unsigned char T0RH;  //T0重载值的高字节
extern unsigned char T0RL;  //T0重载值的低字节

void ConfigTimer0(unsigned int ms);





#endif

timer.c

#include"timer.h"
unsigned char T0RH = 0;  //T0重载值的高字节
unsigned char T0RL = 0;  //T0重载值的低字节

/*******************************************************************************
* 函数功能 : T0配置函数
* 函数说明 : 
*******************************************************************************/
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  //临时变量
    
    tmp = FOSC / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp;           //补偿中断响应延时造成的误差
    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1模式:01为16位定时器,02为8位自动重装定时器
    TH0 = T0RH;     //加载T0重载值(自动重装模式只需计算TH0)
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}

stc_it.c

#include"timer.h"




/* T0中断服务函数,用于数码管显示扫描与按键扫描 */
void InterruptTimer0() interrupt 1
{
   
    TH0 = T0RH;  //重新加载初值
    TL0 = T0RL;
	TaskDelay();//延时  1MS执行1次


}

ws2812.h

#ifndef __WS2812_H
#define __WS2812_H
#include"config.h"

#define LED_MAX 8


sbit DIO=P5^5;


#define    Wait400ns        {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}  //388
#define    Wait850ns        {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}        //860


#define BLACK 	0,0,0
#define RED 		255,0,0
#define GREEN 	0,255,0
#define BLUE 	0,0,255
#define YELLOW 	255,255,0
//#define YELLOW 	255,128,0
//#define YELLOW 	221, 156, 0
#define PURPLE   255,0,255//紫
#define CYAN 	0,255,255//青
#define WHITE 	255,255,255

extern unsigned char xdata ledDataR[LED_MAX];
extern unsigned char xdata ledDataG[LED_MAX];
extern unsigned char xdata ledDataB[LED_MAX];
extern unsigned int taskNumber;
extern unsigned char forNumber;
extern unsigned int xdata taskLed[TASK_MAX];
extern unsigned char xdata taskColorR[TASK_MAX];
extern unsigned char xdata taskColorG[TASK_MAX];
extern unsigned char xdata taskColorB[TASK_MAX];
extern unsigned int xdata taskWaitTime[TASK_MAX];
extern bit styleFig;
extern unsigned int refreshNumber;
extern unsigned char cmdWorkCnt;
extern unsigned int cmdNumber;
extern unsigned int taskStep;
extern unsigned char max;//灯最大编号

void Ws2812Init();
void WriteRgbOne(unsigned int num,unsigned char Red,unsigned char Green,unsigned char Blue);	
void WriteRgbNumber(unsigned int num,unsigned char Red,unsigned char Green,unsigned char Blue);	
void Ws2812Refresh(unsigned int count);

#endif 

ws2812.c

#include "ws2812.h"

unsigned char xdata ledDataR[LED_MAX];//
unsigned char xdata ledDataG[LED_MAX];
unsigned char xdata ledDataB[LED_MAX];
unsigned int taskNumber=92;
unsigned char forNumber=1;
unsigned int xdata taskLed[TASK_MAX]={1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,1,1,2,2,3,3,4,4,5,5,6,6,7,1,1,2,2,3,3,4,4,5,5,6,1,1,2,2,3,3,4,4,5,1,1,2,2,3,3,4,1,1,2,2,3,1,1,2,1};
unsigned char xdata taskColorR[TASK_MAX]={255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,0xFF,255,0,255,0,0xFF,255,0,0xFF,0xFF};
unsigned char xdata taskColorG[TASK_MAX]={255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,0xFF,255,0,255,0,0xFF,255,0,0xFF,0xFF};
unsigned char xdata taskColorB[TASK_MAX]={255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,255,0,0xFF,255,0,255,0,255,0,0xFF,255,0,255,0,0xFF,255,0,0xFF,0xFF};
unsigned int xdata taskWaitTime[TASK_MAX]={30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,30,0,0x1E,30,0,30,0,30,0,30,0,30,0,30,0,0x1E,30,0,30,0,30,0,30,0,30,0,0x1E,30,0,30,0,30,0,30,0,0x1E,30,0,30,0,30,0,0x1E,30,0,30,0,0x1E,30,0,0x1E,0x1E};
bit styleFig=0;
unsigned int refreshNumber=0;
unsigned char cmdWorkCnt=0;
unsigned int cmdNumber=0;
unsigned int taskStep=0;
unsigned char max=0;//灯最大编号

void Ws2812Init()
{
	SetGpioMode(GPIOP5,PIN_5,GPIO_Mode_Out_PP);//设置GPIO模式   GPIO_Mode_Out_IN准双向 GPIO_Mode_Out_PP推挽 GPIO_Mode_AIN高阻GPIO_Mode_Out_OD开漏
	IoModeInit();
	DIO=0;
}

void Send0(void)
{
	
	DIO=1;
	Wait400ns;
	DIO=0;
	Wait850ns;
	
}

void Send1(void)
{
	
	DIO=1;
	Wait850ns;
	DIO=0;
	Wait400ns;
	
}

void Ws2812Rest(void)
{
	
  DIO=0;
  Number_Down[WsOut_delay]=2;		
	
}

void WriteRgbOne(unsigned int num,unsigned char Red,unsigned char Green,unsigned char Blue)	
{
	ledDataR[(num-1)]=Red;
	ledDataG[(num-1)]=Green;
	ledDataB[(num-1)]=Blue;
}


void WriteRgbNumber(unsigned int num,unsigned char Red,unsigned char Green,unsigned char Blue)	
{
	unsigned int i=0;
	for(;i<num;i++)
	{
		ledDataR[i]=Red;
		ledDataG[i]=Green;
		ledDataB[i]=Blue;
	}
}

void Ws2812Refresh(unsigned int count)
{
	unsigned int i=0;
    EA = 0;        //关中断
	for(;i<count;i++)
	{
		if((ledDataG[i]&0x80)==0)	Send0();	else Send1();//G
		if((ledDataG[i]&0x40)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x20)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x10)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x08)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x04)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x02)==0)	Send0();	else Send1();
		if((ledDataG[i]&0x01)==0)	Send0();	else Send1();
		
		if((ledDataR[i]&0x80)==0)	Send0();	else Send1();//R
		if((ledDataR[i]&0x40)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x20)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x10)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x08)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x04)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x02)==0)	Send0();	else Send1();
		if((ledDataR[i]&0x01)==0)	Send0();	else Send1();

		if((ledDataB[i]&0x80)==0)	Send0();	else Send1();//B
		if((ledDataB[i]&0x40)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x20)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x10)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x08)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x04)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x02)==0)	Send0();	else Send1();
		if((ledDataB[i]&0x01)==0)	Send0();	else Send1();		
	}
    EA = 1;        //开中断
    
	Ws2812Rest();

}


你可能感兴趣的:(单片机,嵌入式硬件)