📄 lcd.c
字号:
#include<math.h>
#include<INTRINS.H>
#include "lcd.h"
#include "main.h"
/****************全局变量定义*******************/
uchar row=0,col=0,cbyte; /*行(页)x,列y,输出数据*/
bit xy; /*画线方向标志:1水平,0垂直*/
/*************************************液晶屏初始化**************************************/
void Lcdinit(void)
{ Delay(40);
cbyte = DISPOFF; /*关闭显示屏*/
WrcmdL(cbyte);
WrcmdR(cbyte);
cbyte = DISPON; /*打开显示屏*/
WrcmdL(cbyte);
WrcmdR(cbyte);
cbyte = DISPFIRST; /*定义显示起始行为零*/
WrcmdL(cbyte);
WrcmdR(cbyte);
Lcdclr(); /*清屏*/
Locatexy();
}
/*********************************制定坐标函数******************************************/
void WR_rowcol(uchar x,uchar y)
{row=x;
col=y;
}
/*********************************命令输出到左区控制口*********************************/
void WrcmdL(uchar X)
{
lcdbusyL(); /*确定分区,返回时保留分区状态不变*/
RS= 0; /*命令操作*/
RW = 0; /*写输出*/
Data= X; /*数据输出到数据口*/
E = 1;_nop_();E= 0; /*读入到LCD*/
}
/*********************************命令输出到右区控制口********************************/
void WrcmdR(uchar X)
{
lcdbusyR(); /*确定分区,返回时保留分区状态不变*/
RS= 0; /*命令操作*/
RW= 0; /*写输出*/
Data = X; /*命令输出到数据口*/
E = 1;_nop_();E = 0; /*读入到LCM*/
}
/************************分区操作允许等待,返回时保留分区选择状态*************************/
void lcdbusyL(void)
{
CS1 = 1; CS2 = 0; /*置CS1为1,CS2为0,选择左区*/
wtcom(); /*等待使能*/
}
void lcdbusyR(void)
{
CS1= 0; CS2=1; /*置CS1为0,CS2为1,选择右区*/
wtcom(); /*等待使能*/
}
void wtcom(void)
{
RS= 0; /*清零RS*/
RW = 1; /*置RW为1*/
Data = 0xFF;
E= 1;_nop_();
while(Data & Lcdbusy);
E = 0;
}
/************************************清屏,全屏幕清零***********************************/
void Lcdclr( void )
{
for(row=0;row<8;row++)
for(col=0;col<LCDLIMIT;col++) Wrdata(0);
}
/******************根据设定的坐标数据,定位LCD上的下一个操作单元位置******************/
void Locatexy(void)
{ uchar x,y;
switch (col&0x40) /* col与0xC0*/
{ /*条件分支执行 */
case 0: {lcdbusyL();break;} /*左区*/
case 0x40: {lcdbusyR();break;} /*右区*/
}
x = row&0x07|SETX;
y = col&0x3F|SETY;
wtcom(); /*等待使能*/
RS= 0; /*清零rs */
RW= 0; /*清零RW*/
Data = x;
E= 1;_nop_();E = 0;
wtcom();
RS = 0;
RW= 0;
Data= y;
E = 1;_nop_();E = 0;
}
/*************************************数据写输出/**************************************/
void Wrdata(uchar X)
{
Locatexy(); /*坐标定位,返回时保留分区状态不变*/
RS= 1; /*数据输出*/
RW = 0; /*写输出*/
Data = X; /*数据输出到数据口*/
E = 1; /*读入到LCD*/
_nop_();
E = 0;
}
/***********************画线,任意方向的斜线,不支持垂直的或水平线***********************/
void Linexy(uchar posx,uchar posy,uchar endx,uchar endy)
{
uchar t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
uchar incx,incy;
WR_rowcol(posx,posy) ;
delta_x=endy-row; /*计算两个方向的距离*/
delta_y=endx-col;
if(delta_x>0) incx=1; /*计算增量方向,增量为0表示既不是垂直线也不是水平线*/
else if( delta_x==0 ) incx=0;
else incx=-1;
if(delta_y>0) incy=1;
else if( delta_y==0 ) incy=0;
else incy=-1;
delta_x = cabs( delta_x ); /* 判定哪个距离比较大*/
delta_y = cabs( delta_y );
if( delta_x > delta_y ) distance=delta_x;
else distance=delta_y;
/*开始画线*/
for( t=0;t <= distance+1; t++ ) {
point(row,col);
xerr += delta_x ;
yerr += delta_y ;
if( xerr > distance ) {
xerr-=distance;
col+=incx;
}
if( yerr > distance ) {
yerr-=distance;
row+=incy;
}
}
}
/***************************画线,只提供X或Y方向的,不支持斜线*************************/
void Linehv(uchar posx,uchar posy,uchar length,uchar XY)
{ uchar xs,ys;
if(XY==0x00)
xy=0;
else xy=1;
WR_rowcol(posx,posy);
if (xy)
{ys = col;
for (xs=0;xs<length;xs++)
{ col = ys + xs;
point(row,col);}
}
else {xs = row;
for (ys=0;ys<length;ys++)
{
row = xs + ys;
point(row,col);}
}
}
/*****************************************画点******************************************/
void point(uchar posx,uchar posy)
{ uchar x1,y1,x,y;
WR_rowcol(posx,posy);
x1=col;
y1=row;
row=y1>>3; /*取Y方向分页地址*/
Rddata();
y=y1&0x07; /*字节内位置计算*/
x=0x01;
x=x<<y; /*移入所画点*/
Wrdata(cbyte|x); /*画上屏幕*/
col=x1; /*恢复xy坐标*/
row=y1;
}
/**************************************屏幕滚动定位*************************************/
void Rollscreen(uchar x)
{
cbyte = DISPFIRST|x; /*定义显示起始行为x?*/
WrcmdL(cbyte);
WrcmdR(cbyte);
}
/**************************************一个字串的输出***********************************/
void Putstr(uchar posx,uchar posy,uchar *puts,uchar i)
{ uchar j,X;
WR_rowcol(posx,posy);
for (j=0;j<i;j++)
{
X = puts[j];
if (X&0x80)
{
Putcdot(X&0x7f);/*只保留低7位*/
}
else Putedot(X-0x20); /*ascii码表从0x20开始*/
}
}
/*********************************半角字符点阵码数据输出********************************/
void Putedot(uchar Order)
{
uchar i,bakerx,bakery; /*共定义4个局部变量*/
int x; /*偏移量,字符量少的可以定义为UCHAR */
bakerx = col; /*暂存x,y坐标,已备下半个字符使用*/
bakery = row;
x=Order * 0x10; /*半角字符,每个字符16字节*/
/*上半个字符输出,8列*/
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; /*取点阵码,rom数组*/
Wrdata(cbyte); /*写输出一字节*/
x++;
col++;
if (col==LCDLIMIT){col=0;row++;row++;}; /*下一列,如果列越界换行*/
if (row>7) row=0; /*如果行越界,返回首行*/
} /*上半个字符输出结束*/
col = bakerx; /*列对齐*/
row = bakery+1; /*指向下半个字符行*/
/*下半个字符输出,8列*/
for(i=0;i<8;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -