📄 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 + -