#include <pic.h>
__CONFIG(WDTDIS & HS & UNPROTECT)
/*This will disable the watchdog timer, specify an HS crystal 25MHz and leave
  the code space unprotected.*/

#define Line_SELA RC0 //RC0 is connected to A pin of double-row socket.
#define Line_SELB RC1 //RC1 is connected to B pin of double-row socket.
#define Line_SELC RC2 //RC2 is connected to C pin of double-row socket.
#define Line_SELD RC3 //RC3 is connected to D pin of double-row socket.

#define Line_EN RB1 //RB1 is connected to EN pin of double-row socket.
#define CLK RB3 //RB3 is connected to CLK pin of double-row socket.
#define LAT RB2 //RB2 is connected to ST pin of double-row socket.

#define DAT_R1 RC4 //RC4 is connected to R1 pin of double-row socket.
#define DAT_R2 RC5 //RC5 is connected to R2 pin of double-row socket.
#define DAT_G1 RC6 //RC6 is connected to G1 pin of double row socket.
#define DAT_G2 RC7 //RC7 is connected to G2 pin of double row socket.

#define KEY RB0 //RB0 is connected to key.

/*This group of data is specifically used to display "If Glitch Press & Hold" 
  and "Sure Electronics".*/;
const unsigned char CoName[8]={
		0x0e,0x03,0x38,0x06,0x21,0x00,0x01,0x00		
		};
unsigned char cnt,flag,guide,cnt_flag;	//flag=0 suggests diameter of LED is 5mm.
										//flag=1 suggests diameter os LED is 3mm.
										//guide=0 suggests waiting to be confirm.
										//guide=1 suggests testing process.
										//Variable "cnt_flag" ranges from 0 to 111,
										//assistant flag of element of data array.

/*These variables are used to store key states.*/
unsigned char keydata;

void delay_100ms(void)
{
	unsigned char i,j;
	for(j=0;j<208;j++)
		for(i=0;i<250;i++);
}
void delay_sometime()
{
	unsigned char j;
	for(j=0;j<100;j++);
}
void init(void)
{
	TRISA=0b00000000;
	TRISB=0b00000001;	//RB0 input, RB1,RB2,RB3 output.
	TRISC=0b00000000;	//RC0-RC7 output.
	
	keydata=0;
	guide=1;
	flag=0;
	cnt_flag=0;
}
//Send a line of data wich contains 64 bits.
//Send one bit with clk down to up.
//Every 64bits should be ended with latch down to up.
void sendone(unsigned char line)
{
unsigned char k,value,t;	//Variable "k" counts times of bit sent in a line.
								//Variable "value" tells value to be sent.
								//Variable "t" is available only when sending character
								//of data array.
	if(!flag)
		Line_EN=0;				//Turn off DE-DP029~DE-DP032.
	else
		Line_EN=1;				//Turn off DE-DP033.
	value=0x00;
	if((keydata==0)||(keydata==3))
		value=~value;
	for(k=0;k<64;k++)			//Send a line of data wich contains 64 bits.
	{
		switch(keydata)
		{
		case 0:
		{
			if(line%8==7)
				t=1;
			else
			{
				if(k%8==0)
				{				//Fetch a character from data array.
					value=*(CoName+(guide<<7)-(guide<<4)+cnt_flag);
					value=~value;
					cnt_flag++;
				}
				t=value & 1;
			}
			DAT_R1=t;
			DAT_R2=t;
			DAT_G1=1;
			DAT_G2=1;
			value=value>>1;
			}break;
		}
		CLK=0;					//Send one bit with CLK down to up.
		CLK=1;
	}
	if(!flag)
		Line_EN=1;				//Turn on DE-DP029~DE-DP032.
	else
		Line_EN=0;				//Turn on DE-DP033.
	LAT=0;						//Every 64 bits should be ended with latch down to up.
	LAT=1;
	if(cnt_flag==112)
		cnt_flag=0;
	delay_sometime();			//Delay some time for display.
	if(!flag)
		Line_EN=0;				//Turn off DE-DP029~DE-DP032.
	else
		Line_EN=1;				//Turn off DE-DP033.
}
//This program is used for dynamic scanning display.
void rundisplay()
{
	unsigned char t,temp;
	for(t=0;t<16;t++)
	{
		temp=t;
		Line_SELA==temp & 1;		//Select line.
		temp=temp>>1;
		if((keydata==6)||(keydata==10))
			Line_SELB=0;
		else if((keydata==7)||(keydata==11))
			Line_SELB=1;
		else
			Line_SELB==temp & 1;
		temp=temp>>1;
		if(keydata<2)
			Line_SELC=0;
		else if((keydata==2)||(keydata==3))
			Line_SELC=1;
		else
			Line_SELC==temp & 1;
		temp=temp>>1;
		Line_SELD==temp & 1;
		sendone(t);
	}
}
void main(void)
{
	init();
	while(1)
	{
	rundisplay();
	}
}