#include<reg51.h>
#include<math.h>
#include<INTRINS.H>
#define Uchar unsigned char
/*注:8031的晶振頻率為12MHz*/
/***********液晶顯示幕介面引腳定義***************/
sbit Elcm=P2^7;
sbit CSALCM= P2^2;
sbit CSBLCM= P2^3;
sbit Dilcm=P2^0;
sbit Rwlcm=P2^1;
sfr Datalcm=0x80; /*資料口*/
/***********常用操作命令和引數定義***************/
#define DISPON 0x3f /*顯示on*/
#define DISPOFF 0x3e /*顯示off */
#define DISPFIRST 0xc0 /*顯示起始行定義*/
#define SETX 0x40 /*X定位設定指令(頁)*/
#define SETY 0xb8 /*Y定位設定指令(列)*/
#define Lcdbusy 0x80 /*LCM忙判斷位*/
/**************顯示磁區邊界位置*****************/
#define MODL 0x00 /*左區*/
#define MODM 0x40 /*左區和中區分界*/
#define MODR 0x80 /*中區和右區分界*/
#define LCMLIMIT 0xC0 /*顯示區的右邊界*/
/****************全域變數定義*******************/
Uchar col,row,cbyte; /*列x,行(頁)y,輸出資料*/
bit xy; /*畫線方向標志:1水平*/
/*****************函式串列**********************/
void Lcminit(void); /*液晶模塊初始化*/
void Delay(Uchar); /*延時,入口數為Ms */
void lcdbusyL(void); /*busy判斷、等待(左區)*/
void lcdbusyM(void); /*busy判斷、等待(中區)*/
void lcdbusyR(void); /*busy判斷、等待(右區)*/
void Putedot(Uchar); /*半角字符輸出*/
void Putcdot(Uchar); /*全角(漢字)輸出*/
void Wrdata(Uchar); /*資料輸出給LCM*/
void Lcmcls( void ); /*LCM全螢屏清零(填充0) */
void wtcom(void); /*公用busy等待*/
void Locatexy(void); /*游標定位*/
void WrcmdL(Uchar); /*左區命令輸出 */
void WrcmdM(Uchar); /*中區命令輸出 */
void WrcmdR(Uchar); /*右區命令輸出 */
void Putstr(Uchar *puts,Uchar i); /*中英文字串輸出*/
void Rollscreen(Uchar x); /*螢屏向上滾動*/
void Rddata(void); /*從液晶片上讀資料*/
void Linehv(Uchar length); /*橫(豎)方向畫線*/
void point(void); /*打點*/
void Linexy(Uchar endx,Uchar endy);
/******************陣列串列*********************/
Uchar code Ezk[]; /*ASCII常規字符點陣碼表 */
Uchar code Hzk[]; /*自用漢字點陣碼表*/
Uchar code STR1[]; /*自定義字串*/
Uchar code STR2[];
Uchar code STR3[];
Uchar code STR4[];
/****************************************主程式*****************************************/
void main(void)
{
Uchar x;
col=0;
row=0;
Delay(40); /*延時大約40Ms,等待外設準備好*/
Lcminit(); /*液晶模塊初始化,包括全螢屏清屏*/
Putstr(STR1,12); /*第一行字符輸出,12位元組*/
col=0;
row=2;
Putstr(STR2,14); /*第二行字符輸出,14位元組*/
col=0;
row=4;
Putstr(STR3,11); /*第三行字符輸出,11位元組*/
col=0;
row=6;
Putstr(STR4,12); /*第四行字符輸出,12位元組*/
x=0;
col=0;
row=0;
xy = 1; /*方向標志。定為水平方向*/
Linehv(192); /*畫一條橫線(0,0)-(191,0)*/
col=0;
row=15;
xy = 1;
Linehv(192); /*畫一條橫線(0,15)-(191,15)*/
col=0;
row=32;
xy = 1;
Linehv(192); /*畫一條橫線(0,32)-(191,32)*/
col=0;
row=1;
xy = 0; /*方向標志。定為垂直方向*/
Linehv(31); /*畫一條豎線(0,1)-(0,31)*/
col=191;
row=1;
xy = 0;
Linehv(31); /*畫一條豎線(191,1)-(191,31)*/
col=0; /*設定斜線的起點坐標*/
row=63;
Linexy(44,31); /*畫一段斜線(0,63)-(44,31) */
col=44;
row=31;
Linexy(190,62); /*繼續畫斜線(44,31)-(191,63)*/
while(1){
Rollscreen(x); /*定位新的顯示起始行*/
x++;
Delay(100); /*延時,控制滾動速度*/
};
}
/***********************畫線,任意方向的斜線,不支持垂直的或水平線***********************/
void Linexy(Uchar endx,Uchar endy)
{
register Uchar t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
Uchar incx,incy;
delta_x=endx-col; /*計算兩個方向的距離*/
delta_y=endy-row;
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();
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 length)
{
Uchar xs,ys;
if (xy){ys = col;
for (xs=0;xs<length;xs++){
col = ys + xs;
point();}
}
else {xs = row;
for (ys=0;ys<length;ys++)
{
row = xs + ys;
point();}
}
}
/*****************************************畫點******************************************/
void point(void)
{
Uchar x1,y1,x,y;
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);
WrcmdM(cbyte);
WrcmdR(cbyte);
}
/**************************************一個字串的輸出***********************************/
void Putstr(Uchar *puts,Uchar i)
{
Uchar j,X;
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==LCMLIMIT){col=0;row++;row++;}; /*下一列,如果列越界換行*/
if (row>7) row=0; /*如果行越界,回傳首行*/
} /*上半個字符輸出結束*/
col = bakerx; /*列對齊*/
row = bakery+1; /*指向下半個字符行*/
/*下半個字符輸出,8列*/
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; /*取點陣碼*/
Wrdata(cbyte); /*寫輸出一位元組*/
x++;
col++;
if (col==LCMLIMIT){col=0;row=row+2;}; /*下一列,如果列越界換行*/
if (row>7) row=1; /*如果行越界,回傳首行*/
} /*下半個字符輸出結束*/
row=bakery;
} /*整個字符輸出結束*/
/*********************************全角字符點陣碼資料輸出********************************/
void Putcdot(Uchar Order)
{
Uchar i,bakerx,bakery; /*共定義3個區域變數*/
int x; /*偏移量,字符量少的可以定義為UCHAR */
bakerx = col; /*暫存x,y坐標,已備下半個字符使用*/
bakery = row;
x=Order * 0x20; /*每個字符32位元組*/
/*上半個字符輸出,16列*/
for(i=0;i<16;i++)
{
Wrdata(Hzk[x]); /*寫輸出一位元組*/
x++;
col++;
if (col==LCMLIMIT){ col=0;row++;row++;} /*下一列,如果列越界換行*/
if (row>6) row=0; /*如果行越界,回傳首行*/
} /*上半個字符輸出結束*/
/*下半個字符輸出,16列 */
col = bakerx;
row = bakery+1;
for(i=0;i<16;i++) /*下半部分*/
{
Wrdata(Hzk[x]);
x++;
col++;
if (col==LCMLIMIT){col=0;row++;row++;} /*下一列,如果列越界換行*/
if (row>7) row=1; /*如果行越界,回傳首行*/
} /*下半個字符輸出結束*/
row = bakery;
} /*整個字符輸出結束*/
/************************************清屏,全螢屏清零***********************************/
void Lcmcls( void )
{
for(row=0;row<8;row++)
for(col=0;col<LCMLIMIT;col++) Wrdata(0);
}
/***************************從液晶片上讀資料,保留在全域變數中***************************/
void Rddata(void)
{
Locatexy(); /*坐標定位,回傳時保留磁區狀態不變*/
Datalcm=0xFF;
Dilcm = 1; /*資料*/
Rwlcm = 1; /*讀資料*/
Elcm = 1; /*讀入到LCM*/
_nop_();
cbyte = Datalcm; /*虛讀一次*/
Elcm = 0;
Locatexy(); /*坐標定位,回傳時保留磁區狀態不變*/
Datalcm=0xFF;
_nop_();
Dilcm = 1; /*資料*/
Rwlcm = 1; /*讀資料*/
Elcm = 1; /*讀入到LCM*/
_nop_();
cbyte = Datalcm; /*從資料口讀資料,真讀*/
Elcm = 0;
}
/*************************************資料寫輸出/**************************************/
void Wrdata(Uchar X)
{
Locatexy(); /*坐標定位,回傳時保留磁區狀態不變*/
Dilcm = 1; /*資料輸出*/
Rwlcm = 0; /*寫輸出*/
Datalcm = X; /*資料輸出到資料口*/
Elcm = 1; /*讀入到LCM*/
_nop_();
Elcm = 0;
}
/*********************************命令輸出到左區控制口*********************************/
void WrcmdL(Uchar X)
{
lcdbusyL(); /*確定磁區,回傳時保留磁區狀態不變*/
Dilcm = 0; /*命令操作*/
Rwlcm = 0; /*寫輸出*/
Datalcm = X; /*資料輸出到資料口*/
Elcm = 1;_nop_();Elcm = 0; /*讀入到LCM*/
}
/********************************命令輸出到中區控制口********************************/
void WrcmdM(Uchar X)
{
lcdbusyM(); /*確定磁區,回傳時保留磁區狀態不變*/
Dilcm = 0; /*命令操作*/
Rwlcm = 0; /*寫輸出*/
Datalcm = X; /*命令輸出到資料口*/
Elcm = 1;_nop_();Elcm = 0; /*讀入到LCM*/
}
/*********************************命令輸出到右區控制口********************************/
void WrcmdR(Uchar X)
{
lcdbusyR(); /*確定磁區,回傳時保留磁區狀態不變*/
Dilcm = 0; /*命令操作*/
Rwlcm = 0; /*寫輸出*/
Datalcm = X; /*命令輸出到資料口*/
Elcm = 1;_nop_();Elcm = 0; /*讀入到LCM*/
}
/************************磁區操作允許等待,回傳時保留磁區選擇狀態*************************/
void lcdbusyL(void)
{
CSALCM = 0; CSBLCM = 0; /*清零CSA,CSB,選擇左區*/
wtcom(); /*等待使能*/
}
void lcdbusyM(void)
{
CSALCM = 0; CSBLCM =1; /*置CSA為0,CSB為1,選擇中區*/
wtcom(); /*等待使能*/
}
void lcdbusyR(void)
{
CSALCM = 1; CSBLCM = 0; /*置CSA為1,CSB為0,選擇右區*/
wtcom(); /*等待使能*/
}
void wtcom(void)
{
Dilcm = 0; /*清零DI*/
Rwlcm = 1; /*置RW為1*/
Datalcm = 0xFF;
Elcm = 1;_nop_();
while(Datalcm & Lcdbusy);
Elcm = 0;
}
/******************根據設定的坐標資料,定位LCM上的下一個操作單元位置******************/
void Locatexy(void)
{
unsigned char x,y;
switch (col&0xc0) /* col與0xC0*/
{ /*條件分支執行 */
case 0: {lcdbusyL();break;} /*左區*/
case 0x40: {lcdbusyM();break;} /*中區*/
case 0x80: {lcdbusyR();break;} /*右區*/
}
x = col&0x3F|SETX; /*col.and.0x3f.or.setx*/
y = row&0x07|SETY; /*row.and.0x07.or.sety*/
wtcom(); /*等待使能*/
Dilcm = 0; /*清零DI */
Rwlcm = 0; /*清零RW*/
Datalcm = y; /*MOV P0,Y */
Elcm = 1;_nop_();Elcm = 0;
wtcom(); /*等待使能*/
Dilcm = 0; /*清零DI*/
Rwlcm = 0; /*清零RW*/
Datalcm = x; /*MOV P0,X*/
Elcm = 1;_nop_();Elcm = 0;
}
/*************************************液晶屏初始化**************************************/
void Lcminit(void)
{
cbyte = DISPOFF; /*關閉顯示屏*/
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPON; /*打開顯示屏*/
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPFIRST; /*定義顯示起始行為零*/
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
Lcmcls();
col=0; /*清屏*/
row=0;
Locatexy();
}
/****************************************延時*******************************************/
void Delay(Uchar MS)
{
Uchar us,usn;
while(MS!=0)
{ usn = 4;
while(usn!=0)
{
us=0xf0;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
/************************************定義字串陣列
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/42001.html
標籤:區塊鏈技術
上一篇:民生健康程羽:“區塊鏈技術+分布式商業”推動互聯網保險創新
下一篇:混幣服務
