⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hclcd.c

📁 at89s51实验例程代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//aa 00 47 13 25 63 00 04 04
//	 秒 分 时  日 星期和月(最高3位0-6,代表1-7) 
#include <intrins.h>
#include<AT89x52.h>
#include "hclcddot.h"			//点阵库
#define Uchar unsigned char
#define Uint  unsigned int
#define SomeNOP(); _nop_();_nop_();_nop_(); 
/*LCD驱动要用到的一些口线定意*/
#define LCDPORT P0
sbit D_I = P3^7;
sbit R_W = P3^6;
sbit E = P3^5;
sbit CS1 = P3^4;
sbit CS2 = P3^2;
sbit RST = P3^3;
/*I2C要用到的口线定意*/
sbit SDA = P2^7;
sbit SCL = P2^6;

////////////以下为函数声明///////////////////////////////
//LCD驱动要用到的一些函数
void lcdwrite_cmd(Uchar cmd_dat);
void lcdwrite_dat(Uchar dot_dat);
void lcd_busy();
Uchar  lcdread_dat(void);
void lcddispon(void);
void lcddispoff(void);
void lcdclrall(void);
void lcdini(void);
void HZ12disp(Uchar Nowrow,Uchar Nowcol,Uchar CHplace);
void ASC12disp(Uchar Nowrow,Uchar Nowcol,Uchar ASCplace);
void flashlogo(Uchar Bmpcol);
void Disp128_64(Uchar BMPplace);
void delay(void);
//I2C驱动要用到的一些函数
void Delay_1ms(Uchar time);
void I2CStart(void);	
void I2CStop(void);
void ACK(void);			//Acknowledge信号
void NACK(void);			//没有Acknowledge信号
void AutoACK(void);		//在一定的时间内自动确定ACK的信号//
void Writex(Uchar j);
Uchar Readx(void);
void X24_Write(Uchar Addresshigh,Uchar Addresslow,Uchar Write_date);
Uchar X24_Read(Uchar Addresshigh,Uchar Addresslow);
void X24_WritePage(Uchar Addresshigh,Uchar Addresslow,Uchar idata *Writeip);
void X24_ReadPage(Uchar Addresshigh,Uchar Addresslow,Uchar idata *Readip);
void GetPCF8563(Uchar idata *Getip);
void SetPCF8563(Uchar idata *Setip);
Uchar ReadPCF8563(Uchar AddrePCF);
void WritePCF8563(Uchar AddrePCF,Uchar PCFdata);
void SetWaring (Uchar Wyear,Uchar Wmonth,Uchar Wday);
bit CheckTime(void);
void rs232(void);
void time0(void);
/*定义一个接收的数组*/
Uchar data recdata[8];			//
Uchar idata L24cxxdata[64];		//用于读出或写入24C16的数据
Uchar idata clockdata[7];		//系统时钟
Uchar pcpointer,timecount,timecount2,*gettimeip;				//用于设定从PC接收和发的指针
/*定义二个地址编码寄存器,设定地址线稳定时间,定时器2的延时时间参数,动画的时位置参数,发码结束后取消静音的时间*/
Uchar data MCaddreh,MCaddrel,MCaddtime,time0_1s,led1_8;led18count,logocol;
Uint data nomutetime;	
Uchar newbmpcount;
/*定义标志位存放的寄存器*/
Uchar bdata myflag,myflag2,bmpflag;				//定义一个用于标志寄存器存放的
sbit nomutebit = myflag^0;		//用于开始取消静音标志
sbit recpcokbit = myflag^1;		//用于设定接收到一个完整的控制指令码
sbit returnbit = myflag^2;		//用于向PC回传数据标志
sbit findokbit = myflag^3;		//寻找到明码地址
sbit sendbit = myflag^4;		//开始发码
sbit timenewbit = myflag^5;		//时钟更新标志
sbit callnewbit = myflag^6;		//有新的呼叫
sbit endnewbit=myflag^7;		//呼叫结束

sbit w24cxxbit = myflag2^0;		//设定明码表
sbit timeoutbit =myflag2^1;
sbit newtimebit = myflag2^2;	//设定新的系统时间
sbit r_lbit	= bmpflag^0;
sbit b_wbit = bmpflag^1;		//图和文字标志
sbit newbmpbit = bmpflag^2;		//更新图片
void main(void)
{	
	TH0 = 0xf8;					//2ms
	TL0 = 0xce;
	TH1 = 0xfd;					//以9600Baud的速率和PC机通信
	TL1 = 0xfd;	
	TH2 = 0x4c;					//50ms
	TL2 = 0x00;
	T2CON = 0x00;
	TMOD = 0x21;				//Time0为16位,Time1为8位常数自装
	SCON = 0x50;
	IP = 0x10;
	TR0 = 1;
	TR1 = 1;
	TR2 = 1;
	IE = 0x92;					//Time0,Time2,RS232中断
	led1_8=0xfe;
	led18count=0x01;
	timecount = 0x64;
	time0_1s=0x05;
	timecount2 = 0x32;
	newbmpcount = 0x01;
	logocol =0;
	r_lbit =0;
	timeoutbit =0;
	b_wbit=1;
//	setadd(80);

	lcdini();
	lcdclrall();
	while(1)
	{

		HZ12disp(0x00,0x04,0x01);			//承
		HZ12disp(0x00,0x10,0x02);			//接
		HZ12disp(0x00,0x1C,0x03);			//单
		HZ12disp(0x00,0x28,0x04);			//片
		HZ12disp(0x00,0x34,0x05);			//机
		HZ12disp(0x00,0x40,0x06);			//开
		HZ12disp(0x00,0x4C,0x07);			//发
		HZ12disp(0x00,0x58,0x08);			//及	
		HZ12disp(0x00,0x64,0x09);			//解
		HZ12disp(0x00,0x70,0x0A);			//密

		HZ12disp(0x01,0x0A,0x0B);			//各
		HZ12disp(0x01,0x16,0x0C);			//类
		ASC12disp(0x01,0x22,0x0B);			//I
		ASC12disp(0x01,0x28,0x0C);			//C
		HZ12disp(0x01,0x2E,0x0D);			//卡
		ASC12disp(0x01,0x3A,0x0D);			//;
		ASC12disp(0x01,0x40,0x0A);			//P
		ASC12disp(0x01,0x46,0x0B);			//I
		ASC12disp(0x01,0x4C,0x0C);			//C
		HZ12disp(0x01,0x52,0x03);			//单
		HZ12disp(0x01,0x5E,0x04);			//片
		HZ12disp(0x01,0x6A,0x05);			//机
	
		ASC12disp(0x02,0x0A,0x05);			//5
		ASC12disp(0x02,0x10,0x01);			//1
		HZ12disp(0x02,0x16,0x0E);			//编
		HZ12disp(0x02,0x22,0x0F);			//程
		HZ12disp(0x02,0x2E,0x10);			//器
		ASC12disp(0x02,0x3A,0x0D);			//;
		ASC12disp(0x02,0x40,0x0A);			//P
		ASC12disp(0x02,0x46,0x0B);			//I
		ASC12disp(0x02,0x4C,0x0C);			//C
		HZ12disp(0x02,0x52,0x0E);			//编
		HZ12disp(0x02,0x5E,0x0F);			//程
		HZ12disp(0x02,0x6A,0x10);			//器
	
		HZ12disp(0x03,0x00,0x14);			//亮
		HZ12disp(0x03,0x0c,0x15);			//灯
	
		ASC12disp(0x03,0x2c,0x02);			//2
		ASC12disp(0x03,0x32,0x00);			//0
	
		HZ12disp(0x03,0x44,0x11);			//年

		HZ12disp(0x03,0x5c,0x12);			//月

		HZ12disp(0x03,0x74,0x13);			//日


		ASC12disp(0x04,0x5c,0x0e);			//:		

		ASC12disp(0x04,0x6e,0x0e);	

		while(1)							//b_wbit==1)
		{
			if(timenewbit==1)
			{
				Uchar newtime0;
				timenewbit=0;

				newtime0=(clockdata[6]>>4)&0x0f;
				ASC12disp(0x03,0x38,newtime0);
				newtime0=clockdata[6]&0x0f;
				ASC12disp(0x03,0x3e,newtime0);
			
				newtime0=(clockdata[4]>>4)&0x01;
				ASC12disp(0x03,0x50,newtime0);
				newtime0=clockdata[4]&0x0f;
				ASC12disp(0x03,0x56,newtime0);
			
				HZ12disp(0x03,0x1B,(led18count+0x15));			//几号
			
				newtime0=(clockdata[3]>>4)&0x03;
				ASC12disp(0x03,0x68,newtime0);
				newtime0=clockdata[3]&0x0f;
				ASC12disp(0x03,0x6e,newtime0);
			
				newtime0=(clockdata[2]>>4)&0x03;
				ASC12disp(0x04,0x50,newtime0);
				newtime0=clockdata[2]&0x0f;
				ASC12disp(0x04,0x56,newtime0);
				
				newtime0=(clockdata[1]>>4)&0x07;
				ASC12disp(0x04,0x62,newtime0);
				newtime0=clockdata[1]&0x0f;
				ASC12disp(0x04,0x68,newtime0);
			
				newtime0=(clockdata[0]>>4)&0x07;
				ASC12disp(0x04,0x74,newtime0);
				newtime0=clockdata[0]&0x0f;
				ASC12disp(0x04,0x7a,newtime0);
			}

			if(r_lbit==0)
			{
				flashlogo(logocol++);
				if (logocol==32)
				{r_lbit=1;}
				lcddispon();
				delay();
			}
			else
			{
				flashlogo(logocol--);
				if(logocol==0)
				{r_lbit =0;}
				lcddispon();
				delay();
			}	
		}
/*
		while(b_wbit==0)
		{
			if(newbmpbit==1)
			{
				newbmpbit=0;
				Disp128_64(newbmpcount);
			
			}
		}
*/		
	}
}

	
//以下为定时器TIME0中断程序
void time0(void) interrupt 1
{
	TH0 = 0xf8;
	TL0 = 0xce;
	timecount--;
	if(timecount==0)
	{	
		timecount = 0x64;
		gettimeip=&clockdata[0];
		GetPCF8563(gettimeip);
		time0_1s--;
		if(time0_1s==0)
		{
			time0_1s=0x05;
			led1_8=_crol_(led1_8,1);
			led18count++;
			if(led18count==0x09){led1_8=0xfe;led18count=0x01;}
			P1=led1_8;
			
		}		
		timenewbit=1;
		timecount2--;
		if(timecount2==0)
		{
			timecount2=0x32;
			b_wbit = !b_wbit;
			if(b_wbit==0)
			{
				newbmpbit=1;
				newbmpcount++;
				if(newbmpcount==0x03)
				{newbmpcount=0x01;}
			}
		}
	}

	if(newtimebit==1&&recpcokbit==1)
	{
//设定新的系统时间
		Uchar *pcfsetip;
		newtimebit=0;
		recpcokbit=0;
		pcfsetip=&recdata[1];
		SetPCF8563(pcfsetip);
		WritePCF8563(0x00,0x00);
		WritePCF8563(0x01,0x00);
		WritePCF8563(0x0d,0x83);
	}		
}

//以下为串行口中断程序,用于接收串行数据
void rs232(void) interrupt 4
{
	if(RI==1)
	{	
		
//原输入格式为AA 秒,分,时 日,星期,月年
		if (SBUF==0xaa)
		{
			newtimebit=1;
			pcpointer=0;
		}
		RI = 0;
		recdata[pcpointer++]=SBUF;
		if(pcpointer==8)
		{
			pcpointer =0;
			recpcokbit =1;		//指针还原,置收到完整的控制码			
		}
	}
	else
	{
		TI = 0;
	}			
}

void time2(void) interrupt 5
{
	TF2 = 0;
	TH2 = 0x4c;					//50ms
	TL2 = 0x00;
}

		

/*---------------LCD驱动要用到的一些子程序--------------------*/
/*向LCD写指令*/
void lcdwrite_cmd(Uchar cmd_dat)
{
	D_I = 0;
	R_W = 0;
	E = 0;
	LCDPORT = cmd_dat;
	SomeNOP();
	E = 1;
	SomeNOP();
	E = 0;
}
/*向LCD写数据*/
void lcdwrite_dat(Uchar dot_dat)
{
	D_I = 1;
	R_W = 0;
	E = 0;
	LCDPORT = dot_dat;
	SomeNOP();
	E = 1;
	SomeNOP();
	E = 0;
}
/*判断LCD是否处于*/
void lcd_busy()
{
	Uchar i;
	D_I = 0;
	R_W = 1;
	while(1)
	{
		E = 0;
		LCDPORT = 0xff;
		SomeNOP();
		E = 1;
		SomeNOP();
		i = LCDPORT;
		E = 0;
		if(i<0x80) break;
	}
}

Uchar  lcdread_dat(void)
{	Uchar i;
	D_I = 1;
	R_W = 1;
	E = 0;
	LCDPORT = 0xff;
	SomeNOP();
	E =1;
	SomeNOP();
	i = LCDPORT;
	E = 0;
	LCDPORT =0xff;
	SomeNOP();
	E = 1;
	SomeNOP();
	i =LCDPORT;
	E =0;
	return(i);
}

//开LCD显示
void lcddispon(void)
{
	CS1=0;CS2=1;
	lcdwrite_cmd(0x3f);
	CS1=1;CS2=0;
	lcdwrite_cmd(0x3f);
}
//关LCD显示
void lcddispoff(void)
{
	CS1=0;CS2=1;
	lcdwrite_cmd(0x3e);
	CS1=1;CS2=0;
	lcdwrite_cmd(0x3e);
}
//对整屏清除,就是写空的数据
void lcdclrall(void)
{
	Uchar i,j;
	for(i=0;i<8;i++)
	{
		CS1=0;CS2=1;
		lcdwrite_cmd(i|0xb8);
		lcdwrite_cmd(0x40);
		for(j=64;j>0;j--)
		{
			lcdwrite_dat(0x00);
			lcd_busy();
//			P3_1=!P3_1;
		}
			
		CS1=1;CS2=0;
		lcdwrite_cmd(i|0xb8);
		lcdwrite_cmd(0x40);
		for(j=64;j>0;j--)
		{
			lcdwrite_dat(0x00);
			lcd_busy();
		}
	}
}

//LCD初始化
void lcdini(void)
{
	CS1=0;CS2=1;
	lcdwrite_cmd(0xc0);				//从第0行开始显示
	CS1=1;CS2=0;
	lcdwrite_cmd(0xc0);
	lcddispon();
}

		
/*在指定的行列上显示12点阵的汉字*/		

void HZ12disp(Uchar Nowrow,Uchar Nowcol,Uchar CHplace)
{
	Uchar i,tmp1,tmp2,k=12;
	Uint j;
	j = (CHplace-1)*24;
	if((Nowrow%2)==0)			//
	{
		switch(Nowrow)
		{
			case 0: i=0;break;
			case 2: i=3;break;
			default: i=6;
		}
		while(k!=0)
		{
			if(Nowcol<0x40)
				{CS1=0;CS2=1;}
			else
			{	if(Nowcol<0x80)
				{CS1=1;CS2=0;}
				else
				{break;}
			}
			lcdwrite_cmd(i|0xb8);
			lcdwrite_cmd(Nowcol|0x40);
			lcdwrite_dat(Hzk12[j]);
			lcd_busy();
			lcdwrite_cmd((i+1)|0xb8);	//到下一页
			lcdwrite_cmd(Nowcol|0x40);
			tmp1 = lcdread_dat();
			lcdwrite_cmd(Nowcol|0x40);
			lcdwrite_dat((Hzk12[j+12]&0x0f)|(tmp1&0xf0));
			j++;
			Nowcol++;
			k--;
		}
	}
	else
	{
		switch(Nowrow)
		{
			case 1: i=1;break;
			default: i=4;
		}
		while(k!=0)
		{
			if(Nowcol<0x40)
			{CS1=0;CS2=1;}
			else
			{
				if(Nowcol<0x80)
				{CS1=1;CS2=0;}
				else
				{break;}
			}
			lcdwrite_cmd(i|0xb8);
			lcdwrite_cmd(Nowcol|0x40);
			tmp1=lcdread_dat();
			tmp1=tmp1&0x0f;
			tmp1=(Hzk12[j]<<4)|tmp1;
			tmp2=(Hzk12[j+12]<<4)|(Hzk12[j]>>4);
			lcdwrite_cmd(Nowcol|0x40);
			lcdwrite_dat(tmp1);
			lcd_busy();
			lcdwrite_cmd((i+1)|0xb8);
			lcdwrite_cmd(Nowcol|0x40);
			lcdwrite_dat(tmp2);

⌨️ 快捷键说明

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