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

📄 lcd12864.c

📁 LCD12864做的强大模拟电子钟
💻 C
字号:
//proteus仿真论坛:http://proteus.5d6d.com

#include <reg52.H>
#include<intrins.h>
#include<math.h>
#include"lcd12864.h"
#include"cncode.h"
#include"encode.h"


uchar xdata dispbuf[8][128];//1024Byte用于存放显示数据

void LcdInit()				//lcd初始化
{
	cs1 = 1;
	cs2 = 1;
	WriteCmd(DISP_OFF);
	WriteCmd(DISP_Y);
	WriteCmd(DISP_ON);
}

void WriteCmd(uchar cmd)		//lcd写命令
{
	WaiteBusy();
	e=0;
	rw = 0;
	rs = 0;
	DBPort = cmd;
	e = 1;
	_nop_();
	_nop_();
	e = 0;
}

void WriteData(uchar wdata)	//lcd写数据
{
	WaiteBusy();
	rs = 1;
	rw = 0;
	DBPort = wdata;
	e = 1;
	_nop_();
	_nop_();
	e = 0;
}
/****************************************
函数功能:将显示缓冲区所有数据送到12864显示
****************************************/
void Show()
{
	uchar i,j;
	LcdInit();
	for(j=0;j<8;j++)
	{
		cs1=1;
		cs2=0;
		WriteCmd(DISP_PAGE+j);
		WriteCmd(DISP_X);
		for(i=0;i<64;i++)
			WriteData(dispbuf[j][i]);		
		cs1=0;
		cs2=1;
		WriteCmd(DISP_PAGE+j);
		WriteCmd(DISP_X);
		for(i=64;i<128;i++)
			WriteData(dispbuf[j][i]);	
	}
}

void ClearBuff()//清空显存,0x00
{
	uchar i,j;
	for(j=0;j<8;j++)
	{
		for(i=0;i<128;i++)
			dispbuf[j][i] = 0x00;
	}		
}
void ClearScreen()		//清屏
{
	ClearBuff();
	Show();
}
/*********************************************
函数功能:drawflag = 1:在12864任意位置画点
		  drawflag = 0:在12864任意位置清除点

*********************************************/
void DrawPixel(uchar x,uchar y,bit drawflag)
{
	uchar a,b;
	a = y/0x08;
	b = y&0x07;
	if(drawflag)
		dispbuf[a][x] |= BIT(b);
	else
		dispbuf[a][x] &= ~BIT(b);		
}

/********************************************************************************
**函数功能描述:画直函数,采用非浮点型变量计算,显著提高了运算速度
**输        入:x0,y0,x1,y1:起始,结束点(坐标)

			***注意坐标不要越界***
			x:0-127
			y:0-63


**输        出:无
				坐标如图所示
----------------------------
|(0,0)				(127,0)|
|						   |
|						   |
|						   |
|						   |
|						   |
|						   |
|(0,63)			   (127,63)|
----------------------------

*******************************************************************************/

void Line(uchar x0,uchar y0,uchar x1,uchar y1)
{

//使用Bresenham算法画直线
	char dx,dy,x_increase,y_increase;
	int error;
	uchar x,y;
	uchar i;
	dx = x1-x0;
	dy = y1-y0;
	if(dx>=0)//判断x增长方向
		x_increase = 1;
	else
		x_increase = -1;
	if(dy>=0)//判断y增长方向
		y_increase = 1;
	else
		y_increase = -1;

 	x = x0;
	y = y0;
	dx = cabs(dx);
	dy = cabs(dy);
	if(dx > dy)
	{
		error = -dx;
		for(i=0;i<dx+1;i++)
		{
			DrawPixel(x,y,1);
			x += x_increase;
			error += 2*dy;
			if(error >= 0)
			{
				y += y_increase;
				error -= 2*dx;
			}
		}
	}
	else
	{
		error = -dy;
		for(i=0;i<dy+1;i++)
		{
			DrawPixel(x,y,1);
			y += y_increase;
			error += 2*dx;
			if(error >= 0)
			{
				x += x_increase;
				error -= 2*dy;
			}
		}
	}
}

/*****************************************************
函数功能:指定的位置按传入的数据画一条长度为len(len=<8)点的竖线
*****************************************************/
void DrawVerticalLine(uchar x,uchar y,uchar len,uchar d)
{
	uchar i;
	for(i=0;i<len;i++)
	{
		if(d&0x01)
			DrawPixel(x,y+i,1);
		d >>= 1;
	}
}



/*********************************************
函数功能:指定的位置显示一个12x12汉字
		x:0~127-12
		y:0~63-12
*********************************************/
void Print12_12CHN(uchar x,uchar y,bit cpl,struct typFNT_GB12 a)
{
	uchar i;
	for(i=0;i<12;i++)
	{
		if(cpl)
			DrawVerticalLine(x+i,y,8,~a.Msk[i]);
		else
			DrawVerticalLine(x+i,y,8,a.Msk[i]);				
	}

	for(i=0;i<12;i++)
	{
		if(cpl)
			DrawVerticalLine(x+i,y+8,4,~a.Msk[i+12]);
		else
			DrawVerticalLine(x+i,y+8,4,a.Msk[i+12]);
	}
}
/*********************************************
函数功能:指定的位置显示一个12x6ASCII 
		x:0~127-6
		y:0~63-12
*********************************************/
void Print12_6En(uchar x,uchar y,bit cpl,uchar asc)
{
	uchar i,j;
	for(j=0;j<2;j++)
	{
		for(i=0;i<6;i++)
		{
			if(cpl)
				DrawVerticalLine(x+i,y+8*j,8-4*j,~AsciiDot[(asc-0x20)*12+i+6*j]);
			else
				DrawVerticalLine(x+i,y+8*j,8-4*j,AsciiDot[(asc-0x20)*12+i+6*j]);
		}
	}
}

/********************************************************************************
**函数功能描述:送显示数据到显存,显示12x12文字(中,英,标点,数字)
**输        入:ptr字符串首地址
**输        出:无
**说明:在显示字符串中遇到  "\n"  输出换行;反显两个"~"中间的包括的字符如:~反显~
*******************************************************************************/
void BufferPrint12(uchar x,uchar y,uchar *ptr)
{
	uchar c1,c2,i,j;
	bit cpl = 0;
	for(i=0;ptr[i] != '\0';i++)
	{
		c1 = ptr[i];
		c2 = ptr[i+1];
		if(c1 == '\n')//换行符
		{
			x = 0;
			y += 2;
			continue;
		}
		if(c1 == '~')//反显
		{
			cpl = !cpl;
			continue;
		}
		if(c1<128)							//英文或标点
		{
			Print12_6En(6*x+4,6*y+2,cpl,c1);
			x++;
		}
		else									//中文
		{
			for(j=0;j<sizeof(GB_12)/sizeof(GB_12[0]);j++)			//查找汉字
			{
				if(c1 == GB_12[j].Index[0] && c2 == GB_12[j].Index[1])
					break;
			}
			Print12_12CHN(6*x+4,6*y+2,cpl,GB_12[j]);						
			x += 2;
			i++;												//汉字长度为2			
		}
	}
}



/**/
uchar getState(void) 
{
	uchar temp;
	DBPort = 0xFF;
	e=0;
	rs=0;
	rw=1;
	e=1;
	_nop_();
	e=0;
	temp = DBPort;
	return temp;
}

void WaiteBusy()
{
	uchar temp;
	while(1)
	{
		temp = getState();
		temp &= 0x80;
		if(temp == 0)
			break;
	}
}

























#define CLK_X	95//时钟中心点坐标
#define CLK_Y	31


//秒针结束点坐标,起点坐标(x0,y0)=(31,31);
uchar code secondpointerx[]=//x1
{
//0-15秒
CLK_X+ 0,CLK_X+ 2,CLK_X+ 4,CLK_X+ 7,CLK_X+ 9,CLK_X+11,CLK_X+13,CLK_X+14,CLK_X+16,CLK_X+18,
CLK_X+19,CLK_X+20,CLK_X+21,CLK_X+21,CLK_X+21,CLK_X+22,
//16-30秒
CLK_X+22,CLK_X+21,CLK_X+21,CLK_X+20,CLK_X+19,CLK_X+18,CLK_X+16,CLK_X+14,CLK_X+13,CLK_X+11,
CLK_X+ 9,CLK_X+ 7,CLK_X+ 4,CLK_X+ 2,CLK_X+ 0,
//31-45秒
CLK_X- 2,CLK_X- 4,CLK_X- 7,CLK_X- 9,CLK_X-11,CLK_X-13,CLK_X-14,CLK_X-16,CLK_X-18,CLK_X-19,
CLK_X-20,CLK_X-21,CLK_X-21,CLK_X-21,CLK_X-22,
//46-59秒
CLK_X-22,CLK_X-21,CLK_X-21,CLK_X-20,CLK_X-19,CLK_X-18,CLK_X-16,CLK_X-14,CLK_X-13,CLK_X-11,
CLK_X- 9,CLK_X- 7,CLK_X- 4,CLK_X- 2,

};
uchar code secondpointery[]=//y1
{
//0-15秒
CLK_Y-22,CLK_Y-22,CLK_Y-21,CLK_Y-21,CLK_Y-20,CLK_Y-19,CLK_Y-18,CLK_Y-16,CLK_Y-14,CLK_Y-13,
CLK_Y-11,CLK_Y- 9,CLK_Y- 7,CLK_Y- 4,CLK_Y- 2,CLK_Y- 0,
//16-30秒
CLK_Y+ 2,CLK_Y+ 4,CLK_Y+ 7,CLK_Y+ 9,CLK_Y+11,CLK_Y+13,CLK_Y+14,CLK_Y+16,CLK_Y+18,CLK_Y+19,
CLK_Y+20,CLK_Y+21,CLK_Y+21,CLK_Y+22,CLK_Y+22,
//31-45秒
CLK_Y+22,CLK_Y+21,CLK_Y+21,CLK_Y+20,CLK_Y+19,CLK_Y+18,CLK_Y+16,CLK_Y+14,CLK_Y+13,CLK_Y+11,
CLK_Y+ 9,CLK_Y+ 7,CLK_Y+ 4,CLK_Y+ 2,CLK_Y+ 0,
//46-59秒
CLK_Y- 2,CLK_Y- 4,CLK_Y- 7,CLK_Y- 9,CLK_Y-11,CLK_Y-13,CLK_Y-14,CLK_Y-16,CLK_Y-18,CLK_Y-19,
CLK_Y-20,CLK_Y-21,CLK_Y-21,CLK_Y-22,

};

//分针结束点坐标,起点坐标(x0,y0)=(31,31);
uchar code minpointerx[]=//x1
{
//0-15分
CLK_X+ 0,CLK_X+ 2,CLK_X+ 4,CLK_X+ 6,CLK_X+ 8,CLK_X+ 9,CLK_X+11,CLK_X+12,CLK_X+14,CLK_X+15,
CLK_X+16,CLK_X+17,CLK_X+18,CLK_X+19,CLK_X+20,CLK_X+20,
//16-30分
CLK_X+20,CLK_X+19,CLK_X+18,CLK_X+17,CLK_X+16,CLK_X+15,CLK_X+14,CLK_X+12,CLK_X+11,CLK_X+ 9,
CLK_X+ 8,CLK_X+ 6,CLK_X+ 4,CLK_X+ 2,CLK_X+ 0,
//31-45分
CLK_X- 2,CLK_X- 4,CLK_X- 6,CLK_X- 8,CLK_X- 9,CLK_X-11,CLK_X-12,CLK_X-14,CLK_X-15,CLK_X-16,
CLK_X-17,CLK_X-18,CLK_X-19,CLK_X-20,CLK_X-20,
//46-59分
CLK_X-20,CLK_X-19,CLK_X-18,CLK_X-17,CLK_X-16,CLK_X-15,CLK_X-14,CLK_X-12,CLK_X-11,CLK_X- 9,
CLK_X- 8,CLK_X- 6,CLK_X- 4,CLK_X- 2,
};
uchar code minpointery[]=//y1
{
//0-15分
CLK_Y-20,CLK_Y-20,CLK_Y-19,CLK_Y-18,CLK_Y-17,CLK_Y-16,CLK_Y-15,CLK_Y-14,CLK_Y-12,CLK_Y-11,
CLK_Y- 9,CLK_Y- 8,CLK_Y- 6,CLK_Y- 4,CLK_Y- 2,CLK_Y- 0,
//16-30分
CLK_Y+ 2,CLK_Y+ 4,CLK_Y+ 6,CLK_Y+ 8,CLK_Y+ 9,CLK_Y+11,CLK_Y+12,CLK_Y+14,CLK_Y+15,CLK_Y+16,
CLK_Y+17,CLK_Y+18,CLK_Y+19,CLK_Y+20,CLK_Y+20,
//31-45分
CLK_Y+20,CLK_Y+19,CLK_Y+18,CLK_Y+17,CLK_Y+16,CLK_Y+15,CLK_Y+14,CLK_Y+12,CLK_Y+11,CLK_Y+ 9,
CLK_Y+ 8,CLK_Y+ 6,CLK_Y+ 4,CLK_Y+ 2,CLK_Y+ 0,
//46-59分
CLK_Y- 2,CLK_Y- 4,CLK_Y- 6,CLK_Y- 8,CLK_Y- 9,CLK_Y-11,CLK_Y-12,CLK_Y-14,CLK_Y-15,CLK_Y-16,
CLK_Y-17,CLK_Y-18,CLK_Y-19,CLK_Y-20,
};

//时针结束点坐标,起点坐标(x0,y0)=(31,31);

uchar code hourpointerx[]=//x1
{
CLK_X+ 0,CLK_X+ 1,CLK_X+ 3,CLK_X+ 5,CLK_X+ 6,CLK_X+ 8,CLK_X+ 9,CLK_X+11,CLK_X+12,CLK_X+13,
CLK_X+14,CLK_X+14,CLK_X+15,CLK_X+16,CLK_X+16,CLK_X+16,

CLK_X+16,CLK_X+16,CLK_X+15,CLK_X+14,CLK_X+14,CLK_X+13,CLK_X+12,CLK_X+11,CLK_X+ 9,CLK_X+ 8,
CLK_X+ 6,CLK_X+ 5,CLK_X+ 3,CLK_X+ 1,CLK_X+ 0,

CLK_X- 1,CLK_X- 3,CLK_X- 5,CLK_X- 6,CLK_X- 8,CLK_X- 9,CLK_X-11,CLK_X-12,CLK_X-13,CLK_X-14,
CLK_X-14,CLK_X-15,CLK_X-16,CLK_X-16,CLK_X-16,

CLK_X-16,CLK_X-16,CLK_X-15,CLK_X-14,CLK_X-14,CLK_X-13,CLK_X-12,CLK_X-11,CLK_X- 9,CLK_X- 8,
CLK_X- 6,CLK_X- 5,CLK_X- 3,CLK_X- 1,

};
uchar code hourpointery[]=//y1
{
CLK_Y-16,CLK_Y-16,CLK_Y-16,CLK_Y-15,CLK_Y-14,CLK_Y-14,CLK_Y-13,CLK_Y-12,CLK_Y-11,CLK_Y- 9,
CLK_Y- 8,CLK_Y- 6,CLK_Y- 5,CLK_Y- 3,CLK_Y- 1,CLK_Y- 0,

CLK_Y+1,CLK_Y+ 3,CLK_Y+ 5,CLK_Y+ 6,CLK_Y+ 8,CLK_Y+ 9,CLK_Y+11,CLK_Y+12,CLK_Y+13,CLK_Y+14,
CLK_Y+14,CLK_Y+15,CLK_Y+16,CLK_Y+16,CLK_Y+16,

CLK_Y+16,CLK_Y+16,CLK_Y+15,CLK_Y+14,CLK_Y+14,CLK_Y+13,CLK_Y+12,CLK_Y+11,CLK_Y+ 9,
CLK_Y+ 8,CLK_Y+ 6,CLK_Y+ 5,CLK_Y+ 3,CLK_Y+ 1,CLK_Y+ 0,

CLK_Y-1,CLK_Y- 3,CLK_Y- 5,CLK_Y- 6,CLK_Y- 8,CLK_Y- 9,CLK_Y-11,CLK_Y-12,CLK_Y-13,CLK_Y-14,
CLK_Y-14,CLK_Y-15,CLK_Y-16,CLK_Y-16,
};
uchar code clkbmp[]=//时钟图
{
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0x60,0x20,0x30,
      0x38,0xC8,0x0C,0x04,0x04,0x06,0x02,0x02,0x02,0x03,0x01,0x01,0x21,0xF1,0x01,0x07,
      0x21,0x91,0x51,0x21,0x01,0x03,0x02,0x02,0x02,0x06,0x04,0x04,0x0C,0xC8,0x38,0x30,
      0x20,0x60,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x80,0xE0,0x30,0x1C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,
      0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x01,0x03,0x06,0x1C,0x30,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,
      0x00,0xE0,0x3C,0x07,0x01,0x01,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x02,0x01,0x01,0x07,0x3C,0xE0,0x00,0x00,
      0xFE,0x83,0x80,0x00,0x40,0xA0,0xA0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xE0,
      0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0xA0,0x40,0x00,0x80,0x83,0xFE,0x00,
      0x3F,0xE0,0x00,0x00,0x00,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,
      0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x00,0x00,0xE0,0x3F,0x00,
      0x00,0x03,0x1E,0x70,0xC0,0xC0,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0xC0,0xC0,0x70,0x1E,0x03,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x1C,0x30,0x60,0xC0,0x80,0x80,0x00,0x00,0x00,
      0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,
      0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,
      0x00,0x00,0x80,0x80,0xC0,0x60,0x30,0x1C,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x02,0x06,
      0x0E,0x09,0x18,0x10,0x10,0x30,0x20,0x20,0x20,0x60,0x40,0x40,0x40,0x40,0x43,0x75,
      0x45,0x42,0x40,0x40,0x40,0x60,0x20,0x20,0x20,0x30,0x10,0x10,0x18,0x09,0x0E,0x06,
      0x02,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void WriteClkBmp(uchar  code *image)		//送一幅64x64点阵图像到显存
{
	uchar i,j;
	for(j=0;j<8;j++)
	{
		for(i=64;i<128;i++)
			dispbuf[j][i] = image[j*64+i-64];
	}
}
void TimeDisp(uchar hour,uchar min,uchar sec)
{
	uchar hp;
	hp = hour*5+min/12;
	WriteClkBmp(clkbmp);
	Line(CLK_X,31,secondpointerx[sec],secondpointery[sec]);//秒针
	Line(CLK_X,31,minpointerx[min],minpointery[min]);//分针
	Line(CLK_X,31,hourpointerx[hp],hourpointery[hp]);//时针
}


⌨️ 快捷键说明

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