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

📄 128.c

📁 keilc51环境下12864液晶显示
💻 C
字号:
/********************************************************
			lcd12864
		作者:张建江
		编写时间:2006年1月10日
		最后修改:2006年1月10日
		代码是否优化:否
		
********************************************************/
#include <reg51.h>
#define uchar unsigned char
//定义通信端口
sbit DQ =P2^0;//ds1820
sbit clock_clk=P1^0;//ds1302_clk
sbit clock_dat=P1^1;//ds1302_dat
sbit clock_rst=P1^2;//ds1302_rst
//lcd控制口
sbit cs2=P2^7;
sbit cs1=P2^6;
sbit rst=P2^5;
sbit rw=P2^3;
sbit di=P2^4;
sbit e=P2^2;
sbit display=P3^2;
sbit dis=P1^3;
//为了编程方便定义的位变量
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;

unsigned char x,y;
unsigned char *p[];
bit m=1;//闪烁指示位

unsigned char rec[7];//接收控制字缓冲
unsigned char num=0;//控制字序号
//汉字库及数字符号库
unsigned char code dang[32]={0x00,0x00,0x40,0x42,0x5C,0x48,0x40,0x40,0x7F,0x40,0x50,0x4E,0x44,0xC0,0x00,0x00,
0x00,0x00,0x20,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x7F,0x00,0x00};//当
unsigned char code qian[32]={0x08,0x08,0xE8,0xA8,0xA9,0xAE,0xEA,0x08,0x08,0xC8,0x0C,0x0B,0xEA,0x08,0x08,0x00,
0x00,0x00,0x7F,0x04,0x24,0x44,0x3F,0x00,0x00,0x1F,0x40,0x80,0x7F,0x00,0x00,0x00};//前
unsigned char code shi[32]={0x00,0x10,0x2C,0x24,0xA4,0x64,0x25,0x26,0x24,0x24,0xA4,0x24,0x34,0x2C,0x04,0x00,
0x40,0x40,0x48,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x4B,0x48,0x40,0x40,0x00};//室
unsigned char code wen[32]={0x10,0x21,0x86,0x70,0x00,0x7E,0x4A,0x4A,0x4A,0x4A,0x4A,0x7E,0x00,0x00,0x00,0x00,
0x02,0xFE,0x01,0x40,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x41,0x41,0x7F,0x40,0x00};//温
unsigned char code zero[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00};//0
unsigned char code one[16]={0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00};//1
unsigned char code two[16]={0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00};//2
unsigned char code three[16]={0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00};//3
unsigned char code four[16]={0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00};//4
unsigned char code five[16]={0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00};//5
unsigned char code six[16]={0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00};//6
unsigned char code seven[16]={0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00};//7
unsigned char code eight[16]={0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00};//8
unsigned char code nine[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00};//9
unsigned char code point[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00};//小数点
unsigned char code maohao[16]={0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};//冒号
/*unsigned char code tang[32]={0x00,0x00,0x00,0xFC,0x44,0x54,0x54,0x54,0x55,0xFE,0x54,0x54,0xF4,0x44,0x44,0x00,
0x00,0x40,0x30,0x0F,0x00,0x7D,0x25,0x25,0x25,0x27,0x25,0x25,0x7D,0x00,0x00,0x00};//唐
unsigned char code wen1[32]={0x08,0x08,0x08,0x08,0x78,0x88,0x09,0x0E,0x08,0x88,0x78,0x08,0x08,0x08,0x08,0x00,
0x40,0x40,0x40,0x20,0x20,0x11,0x0A,0x04,0x0A,0x11,0x10,0x20,0x60,0x20,0x20,0x00};//文
unsigned char code tao[32]={0x00,0x24,0x24,0xFF,0x24,0x24,0x00,0x94,0xA4,0x4C,0x12,0x82,0xA2,0x98,0x00,0x00,
0x01,0x01,0x01,0xFF,0x11,0x1F,0x00,0xFF,0x44,0x44,0x40,0x44,0x44,0xFF,0x00,0x00};//韬*/
unsigned char code nian[32]={0x40,0x20,0x10,0x0C,0xE3,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x02,0x00,0x00,
0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00};//年
unsigned char code yue[32]={0x00,0x00,0x00,0x00,0x00,0xFF,0x11,0x11,0x11,0x11,0x11,0xFF,0x00,0x00,0x00,0x00,
0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x01,0x21,0x41,0x3F,0x00,0x00,0x00,0x00};//月
unsigned char code xing[32]={0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,
0x00,0x48,0x46,0x41,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00};//星
unsigned char code qi[32]={0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,
0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00};//期
unsigned char code cone[32]={0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//一
unsigned char code ctwo[32]={0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,0x00,
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00};//二
unsigned char code cthree[32]={0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,
0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00};//三
unsigned char code cfour[32]={0x00,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,
0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x22,0x7F,0x00,0x00};//四
unsigned char code cfive[32]={0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00,0x00,
0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00};//五
unsigned char code csix[32]={0x10,0x10,0x10,0x10,0x10,0x91,0x12,0x1E,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x00,
0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x00,0x00,0x01,0x02,0x0C,0x78,0x30,0x00,0x00};//六
unsigned char code ri[32]={0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00};//日
unsigned char code sheshidu[32]={0x00,0x02,0x05,0xE2,0x18,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x18,0x00,0x00};//摄氏度的符号

void delay(int num)//延时函数
{
	while(num--) ;
}

void lw(unsigned char x,unsigned char y,unsigned char dd)//液晶显示器驱动函数 
{
	if (x<64) 
	{
		cs1=cs2=0;
		di=rw=0;cs1=1;cs2=0;P0=0xb8|y;e=1;delay(2);e=0;delay(2);
		di=rw=0;cs1=1;cs2=0;P0=0x40|x;e=1;delay(2);e=0;delay(2);
		di=1;rw=0;cs1=1;cs2=0;P0=dd;e=1;delay(2);e=0;delay(2);	
	}
	else 
	{
		cs1=cs2=0;x=x-64;
		di=rw=0;cs1=0;cs2=1;P0=0xb8|y;e=1;delay(2);e=0;delay(2);			
		di=rw=0;cs1=0;cs2=1;P0=0x40|x;e=1;delay(2);e=0;delay(2);
		di=1;rw=0;cs1=0;cs2=1;
        P0=dd;e=1;delay(2);e=0;delay(2);
		cs1=cs2=1;
	}
	P0=0xff;
}

void lcd_init(void)//lcd初始化
{
	unsigned char x,y;
	rst=0;
	rst=1;	
	e=di=rw=0;
	cs1=cs2=1;
	cs1=0;cs2=1;
	di=rw=0;P0=0x3f;e=1;delay(2);e=0;delay(2);
	cs1=0;cs2=1;
	di=rw=0;P0=0xc0;e=1;delay(2);e=0;delay(2);
	cs1=cs2=0;
	cs1=1;cs2=0;
	di=rw=0;P0=0x3f;e=1;delay(2);e=0;delay(2);
	cs1=1;cs2=0;
	di=rw=0;P0=0xc0;e=1;delay(2);e=0;delay(2);
	cs1=cs2=0;
    for (y=0;y<8;y++)
    {
		for (x=0;x<128;x++) lw(x,y,0); 
	}
}

void write_chinese(x,y,array)//向x,y处写入一个汉字
unsigned char x,y;
unsigned char array[];
{
	unsigned char j,dd;			
	for(j=0;j<32;j++)
	{
		dd=array[j];
		if(j<16) lw(x+j,y,dd);
		 else  lw(x+j-16,y+1,dd);
	}	
}

void write_flashcn(x,y,array)//向x,y处写入一个汉字,再次写入时取反,需要与变量m配合,构成闪烁效果
unsigned char x,y;
unsigned char array[];
{
	unsigned char j,dd;			
	for(j=0;j<32;j++)
	{
		if(m==1)
		dd=array[j];
		else
		dd=~array[j];
		if(j<16) 
			lw(x+j,y,dd);
		else
			lw(x+j-16,y+1,dd);
	}	
}

void write_digit(x,y,array)//向x,y处写入一个阿拉伯数字
unsigned char x,y;
unsigned char array[];
{
	unsigned char j,dd;			
	for(j=0;j<16;j++)
	{
		dd=array[j];
		if(j<8)
			lw(x+j,y,dd);
		else
			lw(x+j-8,y+1,dd);
	}	
}


Init_DS18B20(void)//初始化ds1820
{
	unsigned char x=0;
	DQ = 1;    //DQ复位
	delay(8);  //稍做延时
	DQ = 0;    //单片机将DQ拉低
	delay(80); //精确延时 大于 480us
	DQ = 1;    //拉高总线
	delay(14);
	x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	delay(20);
}


ReadOneChar(void)//读一个字节
{
	unsigned char i=0;
	unsigned char dat = 0;
	for (i=8;i>0;i--)
	{
		DQ = 0; // 给脉冲信号
		dat>>=1;
		DQ = 1; // 给脉冲信号
		if(DQ)
		dat|=0x80;
		delay(4);
	}
	return(dat);
}


WriteOneChar(unsigned char dat)//写一个字节
{
	unsigned char i=0;
	for (i=8; i>0; i--)
	{
		DQ = 0;
		DQ = dat&0x01;
		delay(5);
		DQ = 1;
		dat>>=1;
	}
}


ReadTemperature(void)//读取温度
{
	unsigned char a=0;
	unsigned char b=0;
	unsigned int t=0;
	float tt=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0x44); // 启动温度转换
	Init_DS18B20();
	WriteOneChar(0xCC); //跳过读序号列号的操作
	WriteOneChar(0xBE); //读取温度寄存器
	a=ReadOneChar();
	b=ReadOneChar();
	t=b;
	t<<=8;
	t=t|a;
	tt=t*0.0625;
	t= tt*10+0.5; //放大10倍输出并四舍五入
	return(t);
}

void clock_out(uchar dd)
{
	ACC=dd;
	clock_dat=a0; clock_clk=1; clock_clk=0;
	clock_dat=a1; clock_clk=1; clock_clk=0;
	clock_dat=a2; clock_clk=1; clock_clk=0;
	clock_dat=a3; clock_clk=1; clock_clk=0;
	clock_dat=a4; clock_clk=1; clock_clk=0;
	clock_dat=a5; clock_clk=1; clock_clk=0;
	clock_dat=a6; clock_clk=1; clock_clk=0;
	clock_dat=a7; clock_clk=1; clock_clk=0;
}

uchar clock_in(void)
{
	clock_dat=1;
	a0=clock_dat;
	clock_clk=1; clock_clk=0; a1=clock_dat;
	clock_clk=1; clock_clk=0; a2=clock_dat;
	clock_clk=1; clock_clk=0; a3=clock_dat;
	clock_clk=1; clock_clk=0; a4=clock_dat;
	clock_clk=1; clock_clk=0; a5=clock_dat;
	clock_clk=1; clock_clk=0; a6=clock_dat;
	clock_clk=1; clock_clk=0; a7=clock_dat;
	return(ACC);
}

uchar read_clock(uchar ord)
{
	uchar dd=0;
	clock_clk=0;
	clock_rst=0;
	clock_rst=1;
	clock_out(ord);
	dd=clock_in();
	clock_rst=0;
	clock_clk=1;
	return(dd);
}

void write_clock(uchar ord, uchar dd)
{
	clock_clk=0;
	clock_rst=0;
	clock_rst=1;
	clock_out(ord);
	clock_out(dd);
	clock_rst=0;
	clock_clk=1;
}

void Serial_Ini()//设置串行口,波特率为4800
{
	TMOD=0x20;
	TH1=TL1=0xF3;
	PCON=0x80;
	EA=1;
	ES=1;
	TR1=1;
	SCON=0x50;
}


main()
{
	unsigned int i=0,k;
	unsigned char a=0,b=0,c=0,d,e,f=0;

	lcd_init();//设置液晶显示器
	Serial_Ini();//初始化串行口
	EX0=1;
	//在预定的位置上写入汉字
	write_chinese(0,4,dang);
	write_chinese(16,4,qian);
	write_chinese(32,4,shi);
	write_chinese(48,4,wen);
	write_digit(80,4,point);
	write_chinese(96,4,sheshidu);
	write_chinese(80,6,tang);
	write_chinese(96,6,wen1);
	write_chinese(112,6,tao);
	write_digit(72,2,maohao);
	write_digit(96,2,maohao);
	write_chinese(0,2,xing);
	write_chinese(16,2,qi);
	write_chinese(32,0,nian);
	//设置时钟的初始值
/*
	write_clock(0x8e,0x00);//protect
	write_clock(0x8c,0x06);//year
	write_clock(0x8a,0x02);//day
	write_clock(0x88,0x08);//month
	write_clock(0x86,0x22);//date
	write_clock(0x84,0x14);//hour
	write_clock(0x82,0x20);//minute
	write_clock(0x80,0x01);//second
	write_clock(0x8e,0x80);//protect	
*/
	dis=0;
	while(1)//主循环
 	{
	EX0= 1; 
	i=ReadTemperature();//读温度
	a=i/100;
	write_digit(64,4,zero+a*16);
	b=i/10-a*10;
	write_digit(72,4,zero+b*16);
	c=i-a*100-b*10;
	write_digit(88,4,zero+c*16);
	d=read_clock(0x8d);//读年
	e=d;
	d=d>>4;
	e=e&0xf;
	write_digit(0,0,two);
	write_digit(8,0,zero);
	write_digit(16,0,zero+d*16);
	write_digit(24,0,zero+e*16);
	d=read_clock(0x89);//读月
	e=d;
	d=d>>4;
	e=e&0x0f;
	write_digit(56,0,zero+d*16);
	write_digit(64,0,zero+e*16);
	write_chinese(72,0,yue);
	d=read_clock(0x87);//读日
	e=d;
	d=d>>4;
	e=e&0x0f;
	write_digit(88,0,zero+d*16);
	write_digit(96,0,zero+e*16);
	write_chinese(104,0,ri);
	d=read_clock(0x8b);//读星期
	write_chinese(32,2,cone+(d-1)*32);//写入星期的汉字
	d=read_clock(0x85);//读小时
	e=d;
	d=d>>4;
	e=e&0x0f;
	write_digit(56,2,zero+d*16);
	write_digit(64,2,zero+e*16);
	d=read_clock(0x83);//读分钟
	e=d;
	d=d>>4;
	e=e&0x0f;
	write_digit(80,2,zero+d*16);
	write_digit(88,2,zero+e*16);
	d=read_clock(0x81);//读秒
	e=d;
	d=d>>4;
	e=e&0x0f;
	write_digit(104,2,zero+d*16);
	write_digit(112,2,zero+e*16);
	if(f==5)//闪烁控制
	{
	write_flashcn(80,6,tang);
	write_flashcn(96,6,wen1);
	write_flashcn(112,6,tao);
	m=!m;
	f=0;
	}
	f=f+1;
	k=100;
	while(k)//延时
 	{
		k--;
	}
	if(num==7||num==2)//控制字的格式
	{
		write_clock(0x8e,0x00);//解除ds1302的写保护
		if(rec[0]=='1')//用户写年月日
		{
			a=rec[1]-'0';
			b=rec[2]-'0';
			b=(a<<4)|b;
			write_clock(0x8c,b);//写年
			a=rec[3]-'0';
			b=rec[4]-'0';
			b=(a<<4)|b;
			write_clock(0x88,b);//写月
			a=rec[5]-'0';
			b=rec[6]-'0';
			b=(a<<4)|b;
			write_clock(0x86,b);//写日
		}
		else if(rec[0]=='2')
		{
			a=rec[1]-'0';
			b=rec[2]-'0';
			b=(a<<4)|b;
			write_clock(0x84,b);//写小时
			a=rec[3]-'0';
			b=rec[4]-'0';
			b=(a<<4)|b;
			write_clock(0x82,b);//写分钟
			a=rec[5]-'0';
			b=rec[6]-'0';
			b=(a<<4)|b;
			write_clock(0x80,b);//写秒
		}
		else if(rec[0]=='3')
		{
			a=rec[1]-'0';
			write_clock(0x8a,a);//写星期
		}
		write_clock(0x8e,0x80);//加入写保护
	}
	num=0;//指令序号归零
   }
}

void serial() interrupt 4//串行口的中断服务函数
{
	rec[num]=SBUF;
	num++;
	RI=0;
}
void Int0()interrupt 0 using 1
{	
	EX0=0;
	if(display==0)
	{dis=!dis;} 
}

⌨️ 快捷键说明

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