📄 lcd.c
字号:
//**********************************************************************************
//**********************************************************************************
//点阵液晶模块上的汉字显示程序
//可以显示全部一二级中文简体汉字
//可以混显全角和半角,并自动转行
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h>
#include <absacc.h>
#include "study.h"
#define LCMD XBYTE[0xAf00] // 液晶数据口
#define LCMC XBYTE[0xAb00] // 液晶命令口
//#define LCMD XBYTE[0x7fff] // 数据口
//#define LCMC XBYTE[0x7bff] // 命令口
#define LCD_DOT_X 98 // lcd 的宽点数
#define LCD_DOT_Y 54 //lcd 的高点数
//定义光标范围,每个光标占用8*8点阵
#define LCD_MAX_X 11 //每行字符, ( LCD_MAX_X +1 ) * 8 点
#define LCD_MAX_Y 5 //共多少行,( LCD_MAX_Y +1 ) * 8 点
//光标位置定义
struct cursortype
{
uchar x;
uchar y;
};
struct cursortype cursor;
void wridata(uchar ch)
{
LCMD=ch;
}
void wricmd(uchar ch)
{
LCMC=ch;
}
//*******************************
//改变LCD亮度
//输入范围0-63
void light(uchar n)
{
LCMC=0x81;
LCMC=n;
}
//****************************
//清屏
//入口:ch=9会连带ICON一起清除,ch=8不清除ICON
void cls(uchar ch)
{
uchar i,j;
for(j=0x0;j<ch;j++)
{
wricmd(0xb0+j);//set page
wricmd(0x10);//set column msb
wricmd(0x0);//set column lsb
wricmd(0xe0);//set modify-read mode
for(i=0;i<132;i++)
{
wridata(0x00); //填满0即清屏
}
wricmd(0xee);//reset modify-read mode
}
}
show_asc(uchar ch);
//***********************
//初始化液晶
uchar lcdlight=6; //motorola的液晶默认亮度为32,早期学习板132*64液晶的默认亮度为6
void initlcd(void)
{
//初始化液晶0x2f,0x22,0x81,32,0x40,0xa0,0xc8,0xa2
// P2=0x00; //P2作为总线时,其寄存器的值对总线没有影响。
//初始化为0,是为了更好的配合液晶的6800总线。motorola的液晶内部固定了6800总线方式。
//如果去掉这一句,motorola的液晶的最左边一列点将无法控制。
//如果液晶是8080总线,则无需这样做。
wricmd(0x2f);//SET POWER CONTROL
wricmd(0x20);//REGULATOR RESISTOR SELECT
wricmd(0x81);
wricmd(lcdlight);
wricmd(0x40);//INITIAL DISPLAY LINE
wricmd(0xa0);//ADC=0(SEG1~SEG132)
wricmd(0xc8);//SHL=0(COM1~COM64)
wricmd(0xa2);//SET 1/9 LCD BIAS
LCMC=0xa6;//NORMAL DISPIAY SET
cls(9);
wricmd(0xaf);//DISPIAY ON
setcursor(0,0);//设置光标到左上角
}
//**********************************************************
//在当前光标位置显示一个12*6 点阵的ASC码字符
//入口:asc字符的值ch
show_asc(uchar ch)
{
uint addr;
uchar hzdata[16];
uchar xdot,i;
addr=16*ch; //寻址点阵在flash中的物理位置
readeprom(addr,hzdata,16); //读出16个字节的点阵数据
xdot=cursor.x*8; //计算出横向点位置
wricmd(0xb0+cursor.y); //将y位置送入液晶
wricmd(xdot & 0x0f); //将x位置送入液晶
wricmd( 0x10 | (xdot >> 4 ));
wricmd(0xe0);
for(i=0;i<8;i++)
{
wridata(hzdata[i]); //写上半个字符
}
wricmd(0xee);
wricmd(0xb0+cursor.y+1);
wricmd(xdot & 0x0f);
wricmd(0x10 | (xdot >> 4 ));
wricmd(0xe0);
for(;i<16;i++) //写下半个字符
{
wridata(hzdata[i]);
}
wricmd(0xee);
}
//*************************************
//在当前光标位置显示一个16*16 汉字或者全角字符
//入口:该汉字的区码ch1,和位码ch2
show_hz(uchar ch1, uchar ch2)
{
ulong addr;
uchar hzdata[32];
uchar xdot,i;
if (ch1>=0xb0) //寻址汉字在flash中的物理位置
{
addr=(ch1-0xb0)*94+ ch2-0xa1;
addr=addr*32+0x5a40;
}
else
{
addr=(ch1-0xa1)*94+ ch2-0xa1;
addr=addr*32+0x800;
}
readeprom(addr,hzdata,32); //读出32个汉字点阵数据
xdot=cursor.x*8; //计算X位置
wricmd(0xb0+cursor.y);
wricmd(xdot & 0x0f);
wricmd( 0x10 | (xdot >> 4 ));
wricmd(0xe0);
for(i=0;i<16;i++) //显示上半个汉字
{
wridata(hzdata[i]);
}
wricmd(0xee);
wricmd( 0xb0+cursor.y+1);
wricmd(xdot & 0x0f);
wricmd( 0x10 | (xdot >> 4 ));
wricmd(0xe0);
for(;i<32;i++) //显示下半个汉字
{
wridata(hzdata[i]);
}
wricmd(0xee);
}
//*******************************************
//设置光标位置
//以6×6点阵为一个光标单位,
//入口:x方向和y方向光标位置
void setcursor(uchar x, uchar y)
{
if ( x<= LCD_MAX_X )
cursor.x= x;
else
cursor.x= LCD_MAX_X;
if ( y<= LCD_MAX_Y )
cursor.y= y;
else
cursor.y= LCD_MAX_Y-1;
}
// **********************************
//在光标位置显示字符串
//入口:要显示的字符串
void lcdstring( uchar *pst)
{
while ( *pst != 0 )
{
if ( *pst < 0x80 ) //小于0x80是字符
{
if (*pst==0x0a) setcursor(0, cursor.y+2); //处理回车换行
else if (*pst== 0x0d) setcursor(0, cursor.y );
else
{
show_asc(*pst); //显示ASC字符
cursor.x++;
if (( cursor.x > LCD_MAX_X )&& (*(pst+1)!=0x0a)){cursor.x=0;cursor.y=cursor.y+2;}
}
pst++; //下一个要显示的字符
}
else //大于0x80是汉字
{
if ( cursor.x>= LCD_MAX_X )
{
show_asc(0x20); //一行的尾部只有半个汉字位置的处理,加一个空格,在下一行开始显示
cursor.x=0;cursor.y=cursor.y+2;
if (cursor.y> LCD_MAX_Y) cursor.y=0; //
}
show_hz(*pst, *(pst+1)); //显示一个汉字
cursor.x+=2;
pst+=2;
if ((cursor.x> LCD_MAX_X)&& (*(pst+1)!=0x0a)){cursor.x=0;cursor.y=cursor.y+2;}
}
if ( cursor.y> LCD_MAX_Y ){ cursor.x=0;cursor.y=0;return;}
}
}
//**********************************************
//在当前光标以十进制方式在液晶上显示一个字节的值
//入口:要显示的值
lcddigit(uchar ch)
{
uchar i[4];
i[0]=(0x30+ch/100);
i[1]=(0x30+(ch%100)/10);
i[2]=(0x30+ch%10);
i[3]=0; //添加结束符号
lcdstring(i);
}
//***********************************
//在当前光标显示一个ASC字符
//入口:要显示的字符
lcdchar(uchar ch)
{
uchar i[2];
i[0]=ch;
i[1]=0; //添加结束符号
lcdstring(i);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -