📄 hd61202.c
字号:
/*************************************************************
* LCD Graphic Routines HD61202 *
*************************************************************/
#define UINT unsigned int
#define UCHAR unsigned char
#include <W77E58.H>
/********** 字库首地址 *****************************************************/
#define HZK12 0x8000 //12点阵简体字库首址
#define ASC12 0x8380 //12点阵ASC字库首址(半角)
/********** HD61202 操作命令 ***********************************************/
#define LDISPON 0x3f //开显示
#define LDISPOFF 0x3e //关显示
#define LSTATLN 0xc0 //起始行:0xc0|行号
#define LSETPG 0xb8 //页地址设置
#define LSETCOLM 0x40 //列地址设置
/********** HD61202 端口定义 ***********************************************/
#define lcd_RD(x) *((UCHAR volatile xdata*)0x07ff+((x)<<8))
#define lcd_RC(x) *((UCHAR volatile xdata*)0x06ff+((x)<<8))
#define lcd_WD(x) *((UCHAR volatile xdata*)0x05ff+((x)<<8))
#define lcd_WC(x) *((UCHAR volatile xdata*)0x04ff+((x)<<8))
#define AZClr *((UCHAR volatile xdata*)0x7fff)
/********** 变 量 定 义 ****************************************************/
extern void delay(UCHAR);
extern bit ENGLISH,REVI;
static idata UCHAR Bcd[9]; //数字-->字符
idata UCHAR LcdBuf[32]; //多用缓冲区
data UCHAR LcdSize,mCsr;
static data UCHAR xdata *Font;
/********** 传送 HD61202 命令 **********************************************/
void lcd_command(UCHAR x,UCHAR com)
{
x = x>>4 & 0x0c;
while(lcd_RC(x)&0x80);
lcd_WC(x)=com;
}
/********** 写 HD61202 显示数据 ********************************************/
void lcd_write(UCHAR x,UCHAR dat)
{
lcd_command(x,LSETCOLM|x&0x3f);
while(lcd_RC(x>>4 & 0x0c)&0x80);
lcd_WD(x>>4 & 0x0c)=dat;
}
/********** 读 HD61202 显示数据 ********************************************
UCHAR lcd_read(UCHAR x)
{
x = x>>4 & 0x0c;
while(lcd_RC(x)&0x80);
return(lcd_RD(x));
}
/********** HD61202 清屏 ***************************************************/
void erase(UCHAR fill)
{
data UCHAR i,j,m;
for(i=0;i<LcdSize;i+=0x40) //域
{
lcd_command(i,LDISPON);
for(j=0;j<8;j++) //行(页)
{
lcd_command(i,LSETPG|j);
lcd_command(i,LSETCOLM|0);
for(m=0;m<0x40;m++) //列
{
while(lcd_RC(i>>4)&0x80);
lcd_WD(i>>4)=fill;
}
}
}
}
/********** HD61202 初试化 *************************************************/
void lcd_initial(void)
{
for(LcdSize=0;LcdSize<0xc0;LcdSize+=0x40)
{
if(lcd_RC(LcdSize>>4)==0xff) break;
lcd_command(LcdSize,LDISPON);
lcd_command(LcdSize,LSTATLN);
}
erase(0);
}
/********** 读 字 库 数 据 *************************************************/
void read_font(UCHAR xdata *fp)
{
data UCHAR i;
i=AZClr; //读clrport,清AZ4~AZ0
for(i=0;i<32;i++) //从同一地址读入32Byte
LcdBuf[i]=*fp;
}
/********** 显示半角字符 字库位于 0x8380-0x83bf *****************************/
void ascii(UCHAR xc,UCHAR yc,UCHAR ch)
{
data UCHAR i,j,x,c;
c=((yc&0x10)!=0)!=REVI?0xff:0; //yc.4==1:反白显示
yc&=0x07; //yc:0--7
if(++xc>LcdSize-6)return; //xc:0--127
if(ch<32)return;
Font=(ch>>1)+ASC12;
read_font(Font);
i=ch<<4&0x10;
ch=2;
do{
lcd_command(xc,LSETPG|yc);
if(xc==1)
lcd_write(0,c);
if(xc==121)
lcd_write(127,c);
lcd_command(xc,LSETCOLM | xc&0x3f);
j=6;x=xc;
do{
if((x&0x3f)==0){
lcd_command(x,LSETPG|yc);
lcd_command(x,LSETCOLM);
}
while(lcd_RC(x>>4&0x0c)&0x80);
lcd_WD(x>>4&0x0c)=LcdBuf[i++]^c;
x++;
}while(--j);
yc++;i+=2;
}while(--ch);
}
/********** 显示汉字 汉字库位于 0x8000-0x9fff *******************************/
void chinese(UCHAR xc,UCHAR yc,UCHAR h,UCHAR l)
{
data UCHAR i,x,c;
c=((yc&0x10)!=0)!=REVI?0xff:0; //yc.4==1:反白显示
yc&=0x07; //yc:0--7
if(++xc>LcdSize-12)return; //xc:0--127
Font=(h-0xa1)*94+(l-0xa1)+HZK12;
read_font(Font);
h=2;i=0;
do{
lcd_command(xc,LSETPG|yc);
if(xc==1)
lcd_write(0,c);
if(xc==115)
lcd_write(127,c);
lcd_command(xc,LSETCOLM | xc&0x3f);
l=12;x=xc;
do{
if((x&0x3f)==0){
lcd_command(x,LSETPG|yc);
lcd_command(x,LSETCOLM);
}
while(lcd_RC(x>>4&0x0c)&0x80);
lcd_WD(x>>4&0x0c)=LcdBuf[i++]^c;
x++;
}while(--l);
yc++;
}while(--h);
}
/********** 显示字符(汉字)串 ***********************************************/
void string(UCHAR xs,UCHAR ys,UCHAR *s,UCHAR code *es)
{
code UCHAR reverse[]={ // 0:无反白
0x00,0x30,0x60,0xc0, //1~4:指定行反白
0x80,0xe0,0xf0,0x10}; // 7:全反白
data UCHAR ch,chl,rev;
if((*es!=0) && ENGLISH) s=es;
rev = ys>>4 & 0x07;
ys &= 0x07;
rev=reverse[rev];
ys^=rev&0x10;
while((ys&0x0f)<7)
{
ch=*s; s++;
if(ch<0x20)
{
if(ch=='\r') xs=0;
else if(ch=='\n'){
ys+=2;rev>>=1;ys^=rev&0x10;}
else if(ch=='\t') xs+=6;
else break;
continue;
}
if(ch<0xa1)
{
ascii(xs,ys,ch);
xs+=6;
}
else
{
chl=*s; s++;
if(ch==0xa4)
chinese(xs,ys,chl,0xfd);
else
chinese(xs,ys,ch,chl);
xs+=12;
}
}
}
/********** 显 示 数 值 *****************************************************/
void number(UCHAR xn,UCHAR yn,UINT num,UCHAR dp)
{
data UCHAR i,m,n;
data UINT shift,adjust;
n=dp>>4;dp&=0x0f; //dp<=4:小数位数,消零
Bcd[8]=0; //dp==5:无小数,3位,xxx^
if(dp==9) //dp==6:无小数,3位,xxx^
{ //dp==7:消零,4位,密码显示'*'
m=num;dp=num>>8; //dp==8:不消零,4位,无小数
i=8; //dp==9:二进制,8位
while(i--) //dp高4位:
{ // dp==9:光标
if(dp&0x01) // else:显示8-n位
if(m&0x01) Bcd[i]='1';
else Bcd[i]='0';
else Bcd[i]='.';
dp>>=1;m>>=1;
}
if(n<8) Bcd[7-n]+=0x50;
n=0;
}
else
{
m=0;
Bcd[3]=Bcd[2]=Bcd[1]=Bcd[0]=
dp<=4?'0':' ';
for(i=0;num>=10000;i++) //取万位数
num-=10000;
Bcd[3]+=i;
shift=0;
for(i=0;i<16;i++) //x 转换成BCD码
{
if(shift)
{
adjust=(shift+0x3333)&0x8888;
adjust>>=2;
adjust+=adjust>>1;
shift+=adjust;
}
shift<<=1;
num<<=1;
if(CY)shift++;
}
for(i=7;i>3;i--) //转换成字符串
{
Bcd[i]=((UCHAR)shift&0x0f)+0x30;
shift>>=4;
}
if(dp<=4)
{ //插入小数点
if(dp)
{
for(i=0;i<(7-dp);i++)
Bcd[i]=Bcd[i+1];
Bcd[7-dp]='.';
}
else
dp--;
for(i=0;i<6-dp;i++) //消零
if(Bcd[i]=='0') Bcd[i]=' ';
else break;
}
else if(dp<=6)
{
for(i=4;i<7;i++)
Bcd[i]=Bcd[i+1];
Bcd[7]=dp&0x01?0x82:0x83;
}
else if(dp==7) for(i=4;i<8;i++)
{
if(Bcd[i]!='0') m=Bcd[i];
Bcd[i]=m?'*':' ';
}
}
string(xn,yn,Bcd+n,"");
}
/******************************************************************************
void test(void)
{
static data UCHAR ch,cl=0xa1;
data UCHAR i,j;
if(ch<0xa1)
{
for(j=0;j<8;j+=2)
for(i=0;i<128-6;i+=6)
{
ascii(i,j,ch);
if(ch<0xa1) ch++;
}
}
else
{
for(j=0;j<8;j+=2)
for(i=0;i<128-12;i+=12)
{
chinese(i,j,ch,cl);
if(++cl==0xff){
cl=0xa1;ch++;}
}
}
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -