📄 driver.c
字号:
}
return 0xff;
}
uchar KeyScan()
{
uchar k;
k=0xFF;
while(k==0xFF){k=GetKey();}
return k;
}
*/
//************************************************************8
//* lock 键盘锁 驱动*
//**************************************************************
//uchar GetLock()
//{//(第5版)
// uchar lock;
// KeyEnable;
// P4 = (P4 & 0xf0)|15;//列输出
// lock = XBYTE[KeyAdr];
// KeyDisable;
// return lock;//P0口数据
//}
//************************************************************8
//* BEEP 驱动*
//**************************************************************
void Beep(ulong n)
{
BeepOn;
while(--n);
BeepOff;
}
//************************************************************8
//* BOX 驱动*
//**************************************************************
void OpenBox()
{
uint x=80;
OpenCashbox;
while(--x);
CloseCashbox;
}
//---------------------------Key End----------------------------------------------------
//---------------------------Lcd Begin--------------------------------------------------------------
//void LcdBusyCheck(uint CS)
//{
// uchar State = 0x80;
// uint ChipAdr;
//
// ChipAdr = StatusReadAdr|CS;
// while(State & 0x80)
// {
// State = XBYTE[ChipAdr];
// }
//}
uchar LcdReadData(uint CS)
{
uchar ReadData;
uchar State = 0x80;
uint ChipAdr;
// LcdBusyCheck(CS);
ChipAdr = StatusReadAdr|CS;
while(State & 0x80)
{
State = XBYTE[ChipAdr];
}
ChipAdr = ReadDataAdr|CS;
ReadData = XBYTE[ChipAdr];
return ReadData;
}
void LcdWriteData(uchar WriteData,uint CS)
{
uint ChipAdr;
uchar State = 0x80;
// LcdBusyCheck(CS);
ChipAdr = StatusReadAdr|CS;
while(State & 0x80)
{
State = XBYTE[ChipAdr];
}
ChipAdr = WriteDataAdr|CS;
XBYTE[ChipAdr] = WriteData;
}
void LcdWriteCommand(uchar Command,uint CS)
{
uint ChipAdr;
uchar State = 0x80;
// LcdBusyCheck(CS);
ChipAdr = StatusReadAdr|CS;
while(State & 0x80)
{
State = XBYTE[ChipAdr];
}
ChipAdr = InstructionSetAdr|CS;
XBYTE[ChipAdr] = Command;
}
//**************************************************************/
//画点函数
//DisON=1为画点 DisON=0为消点
void LcdDisplayDot(uchar Dot_X,uchar Dot_Y,uchar DisON)
{
uchar x,y,y1,dat;
uint cs;
if(Dot_X<64)
{
cs=LcdChip1;
x=Dot_X;
}
else
{
if(Dot_X<128)
{
cs=LcdChip2;
x=Dot_X-64;
}
else
{
cs=LcdChip3;
x=Dot_X-128;
}
}
x |= 0x40;
y=Dot_Y / 8;
y|=0xb8;
y1=Dot_Y % 8;
y1=1<<y1;
LcdWriteCommand(x,cs); //X 座标
LcdWriteCommand(y,cs); //Y 座标
dat=LcdReadData(cs); //必须先虚读一次
dat=LcdReadData(cs);
if(DisON)
dat|= y1; //画点
else
dat=dat & (!(1<<y1)); //消点
LcdWriteCommand(x,cs); //X 座标
LcdWriteCommand(y,cs); //Y 座标
LcdWriteData(dat,cs);
}
void LcdTurnOn()
{
// LcdWriteCommand(0x3E,1); //关闭LCD
// LcdWriteCommand(0x3E,2);
// LcdWriteCommand(0x3E,3);
LcdWriteCommand(0x3f,LcdChip1); //开LCD显示
LcdWriteCommand(0x3f,LcdChip2);
LcdWriteCommand(0x3f,LcdChip3);
LcdWriteCommand(0xc0,LcdChip1); //起始行设置指令 左半屏
LcdWriteCommand(0xc0,LcdChip2); //起始行设置指令 中半屏
LcdWriteCommand(0xc0,LcdChip3); //起始行设置指令 右半屏
}
//清屏
void LcdClear(uchar LastCol)
{
unsigned char i,j,k;
LastCol -= 128;
for(i=0;i<8;i++)
{
k=i|0xb8;
LcdWriteCommand(k,LcdChip1);
LcdWriteCommand(k,LcdChip2);
LcdWriteCommand(k,LcdChip3);
LcdWriteCommand(0x40,LcdChip1); //列地址设置指令 左半屏
LcdWriteCommand(0x40,LcdChip2); //列地址设置指令 右半屏
LcdWriteCommand(0x40,LcdChip3); //列地址设置指令 右半屏
for(j=0;j<64;j++)
{
LcdWriteData(0x0,LcdChip1);
LcdWriteData(0x0,LcdChip2);
if(j<LastCol)LcdWriteData(0x0,LcdChip3);
}
}
}
//清屏
void LcdClearLine(uchar Line,uchar LastCol)
{
unsigned char i,var;
LastCol -= 128;
var = Line|0xb8;
LcdWriteCommand(var,LcdChip1);
LcdWriteCommand(var,LcdChip2);
LcdWriteCommand(var,LcdChip3);
LcdWriteCommand(0x40,LcdChip1); //列地址设置指令 左半屏
LcdWriteCommand(0x40,LcdChip2); //列地址设置指令 右半屏
LcdWriteCommand(0x40,LcdChip3); //列地址设置指令 右半屏
for(i=0;i<64;i++)
{
LcdWriteData(0x0,LcdChip1);
LcdWriteData(0x0,LcdChip2);
if(i<LastCol)LcdWriteData(0x0,LcdChip3);
}
}
/////////////////////////////////////////////////////////////////////////////
//函数:long g20(uchar c1, uchar c2, uchar c3, uchar c4)
//功能:计算汉字点阵在芯片中的地址
//参数:c1,c2,c3,c4:4字节汉字内码通过参数c1,c2,c3,c4传入,双字节内码通过参数c1,c2传入,c3=0,c4=0
//返回:汉字点阵的字节地址(byte address)。如果用户是按 word mode 读取点阵数据,则其地址(word
//address)为字节地址除以2,即:word address = byte address / 2 .
//例如:“啊”字的内码为0xb0a1,则byte address = g(0xb0,0xa1,0x00,0x00) *32+0xa7700
//word address = byte address / 2
//“ ”字的内码为0x8139ee39,则byte address = g(0x81,0x39,0xee,0x39) *32+0xa7700
//word address = byte address / 2
//说明:在以上计算字节地址中byte address = g(0xb0,0xa1,0x00,0x00) *32+0xa7700的0xa7700是15X16
//点阵字库相对整个字库芯片0000 0000的偏移地址
/////////////////////////////////////////////////////////////////////////////
ulong CountZkAdr(uchar c1, uchar c2, uchar c3, uchar c4)
{
ulong h;
if(c1 >= 0xb0 && c2 >= 0xA1 && c3 == 0 && c4 == 0)//汉字2区 B0A1 --- F7FE 0xAF8C0
{
return (ulong)((c1-0xB0)*94+(c2-0xA1))*32+0xAF8C0;
}
else if(c1 >= 0xAA && c2 >= 0x40 && c3 == 0 && c4 == 0)//16点阵4区汉字 AA40 --- FEAE 0x113EC0
{
if(c2>0x7f)c2--;
if(c2 > 0xA0) c2 = 0x40;
return (ulong)((c1-0xAA)*96+(c2-0x40))*32+0x113EC0;
}
else if(c1 >= 0xA8 && c3 == 0 && c4 == 0)//字符5区 A840 --- A996 0xAE0C0
{
if(c1>=0xA8 && c2>=0xA1);
else if(c2>0x7f)c2--;
if(c2>=0xA1)
return (ulong)((c1-0xA1)*94+(c2-0xA1))*32+0xA7700;
else
return (ulong)((c1-0xA8)*96+(c2-0x40))*32+0xAE0C0;
}
else if(c1 >= 0xA1 && c3 == 0 && c4 == 0)//字符1区 A1A1 --- A9FE 0xA7700
{
return (ulong)((c1-0xA1)*94+(c2-0xA1))*32+0xA7700;
}
else if(c1 >= 0x81 && c3 == 0 && c4 == 0)//汉字3区 8140 --- A0FE 0xE46C0
{
if(c2>0x7f)c2--;
return (ulong)((c1-0x81)*190+(c2-0x40))*32+0xE46C0;
}
else if(c2>=0x30)//汉字4区
{
// four bytes HZ
h=(((ulong)(c1-0x81)*10+(c2-0x30))*126+(ulong)(c3-0x81))*10+(c4-0x30);
h-=12439;
if(h<0 || h>=6530) return(0);
h += 22046;
return h*32+0xA7700;
}
}
//功能:在LCD指定位置显示一行汉字或字符(16*16或8*16)
//参数说明:
//x 显示起行(0~63只能是8的倍数) y显示起始列(0~191)
//str需要显示的字符指针
//mode低4位=0:只显示不清除其它内容;
//mode低4位=1:清除本行原有内容并显示;
//mode低4位=2:清除整屏内容并显示;
//mode低4位=10D只显示不清除其它内容并在字符最上面补画一横线,用于画表用
//mode低4位=11D只显示不清除其它内容并在字符最下面补画一横线,用于画表用
//mode低4位=12D只显示不清除其它内容并在字符最上面和下面补画一横线,用于画表用
//mode高4位!=0:反白显示,
//mode高4位==0:正常显示。
//NotLen需要取反显示的字符长度
void LcdDisplay(uchar x,uchar y,uchar *str,uchar mode)
{
uchar Buff[2][192]; //显示缓冲区 上半行和下半行
uint i,j,poz,DisStart, DisEnd;
uchar len,val,k,bm1,bm2,bm3,bm4,hzi;
ulong addr;
uchar SendPos;
if(str[0]==0 || str[0]=='\0')return;
len = strlen(str); //字符长度
x/=8;
poz = y;
memset(Buff,0,sizeof(Buff)); //清显示缓冲区
for(i=0;i<len;i++) //读出点阵数据放入缓显示冲区
{
if(str[i]>0x80)
{
k=16;
hzi = i;
bm1=str[hzi++];
bm2=str[hzi++];
bm3=str[hzi++];
bm4=str[hzi];
if(bm1 >= 0x82 && bm2 > 0x35)
{
bm3 = bm4 = 0;
i += 1;
}
else i += 3;
addr = CountZkAdr(bm1,bm2,bm3,bm4);
}
else
{
k=8;
addr = 0x18A010+(str[i]-0x20)*16;
}
SerialFlashRead(Flashziku,addr,k,Buff[0]+poz);
SerialFlashRead(Flashziku,addr+k,k,Buff[1]+poz);
poz+=k;
if(poz>192)
{
poz=192;
break;
}
}
if(mode & 0xf0) //高4位为1反白显示,为0正常显示
{
for(j=y;j<poz;j++)
{
Buff[0][j] = ~Buff[0][j];
Buff[1][j] = ~Buff[1][j];
}
}
j=0;
switch(mode & 0x0f)
{
case 2: j=184; //清除其余三行(不包括滚动条)并显示
case 3: if(j==0)j=192;
for(i=0;i<8;i++) //清除其余三行(包括滚动条)并显示
{//清屏后显示输入内容
// if(i!=x || i!=x+1)
LcdClearLine(i,j);
}
case 0: DisStart = y; //只显示不清除其它内容
DisEnd = poz;
break;
case 1: DisStart = 0;
DisEnd = 184;
break; //清除本行原有内容并显示,保留滚动条
case 4: DisStart = 0; //清除本行原有内容并显示
DisEnd = 192; //不保留滚动条
break;
// case 5:
case 0x0A:
DisStart = y; //只显示不清除其它内容并在字符上面补画一横线,用于画表用
DisEnd = poz;
for(i=DisStart;i<DisEnd;i++)
{
Buff[0][i] |= 0x01;
}
break;
case 0x0B:
DisStart = y; //只显示不清除其它内容并在字符下面补画一横线,用于画表用
DisEnd = poz;
for(i=DisStart;i<DisEnd;i++)
{
Buff[1][i] |= 0x80;
}
break;
case 0x0C:
DisStart = y; //只显示不清除其它内容并在字符上下面都补画一横线,用于画表用
DisEnd = poz;
for(i=DisStart;i<DisEnd;i++)
{
Buff[0][i] |= 0x01;
Buff[1][i] |= 0x80;
}
break;
default:DisStart = 0;DisEnd = 184; break;//=case 1
}
for(j=0;j<2;j++)
{
val = x & 0x07 | 0xB8;
SendPos = DisStart;
if(SendPos<64)
{
LcdWriteCommand(val,LcdChip1); //设置行起始位置 页地址
LcdWriteCommand(0x40|SendPos,LcdChip1); //列地址设置指令
if(DisEnd<64)
{
for(i=SendPos;i<DisEnd;i++)
LcdWriteData(Buff[j][SendPos++],LcdChip1);
x++;
continue;
}
else
{
for(i=SendPos;i<64;i++)
LcdWriteData(Buff[j][SendPos++],LcdChip1);
}
}
if(SendPos<128)
{
LcdWriteCommand(val,LcdChip2); //设置行起始位置 页地址
LcdWriteCommand(0x40|(SendPos-64),LcdChip2); //列地址设置指令
{
if(DisEnd<128)
{//第三屏没有数据
for(i=SendPos;i<DisEnd;i++)
LcdWriteData(Buff[j][SendPos++],LcdChip2);
x++;
continue;
}
else
{//第三屏有数据
for(i=SendPos;i<128;i++)
LcdWriteData(Buff[j][SendPos++],LcdChip2);
}
}
}
if(SendPos>127)
{
LcdWriteCommand(val,LcdChip3); //设置行起始位置 页地址
LcdWriteCommand(0x40|(SendPos-128),LcdChip3); //列地址设置指令
for(i=SendPos;i<DisEnd;i++) //送第三屏数据
LcdWriteData(Buff[j][SendPos++],LcdChip3);
x++;
}
}
}
void ShowPicture(uchar startrow,uchar startcol,uchar endrow,uchar endcol,uchar *dat)
{//startrow,endrow(行/页地址)必须是8的倍数,*dat是点阵数据,必须是纵向取模,字节倒序
uchar i,j,column,row,val;//row:行;column:列
uint m;
m=0;
row=(endrow-startrow)/8;
// PCO &= 0x7f;
for(j=0;j<row;j++)
{
val = (startrow/8+j)|0xB8;
column = startcol;
if(column<64)
{
LcdWriteCommand(val,LcdChip1); //设置起始行/页地址
LcdWriteCommand(0x40|column,LcdChip1); //列地址设置指令
if(endcol<64)
{
for(i=column;i<endcol;i++)
{
LcdWriteData(dat[m++],LcdChip1);
}
continue;
}
else
{
for(i=column;i<64;i++)
{
LcdWriteData(dat[m++],LcdChip1);
column++;
}
}
}
if(column<128)
{
LcdWriteCommand(val,LcdChip2); //设置行起始位置 页地址
LcdWriteCommand(0x40|(column-64),LcdChip2); //列地址设置指令
{
if(endcol<128)
{//第三屏没有数据
for(i=column;i<endcol;i++)
LcdWriteData(dat[m++],LcdChip2);
continue;
}
else
{//第三屏有数据
for(i=column;i<128;i++)
{
LcdWriteData(dat[m++],LcdChip2);
column++;
}
}
}
}
if(column>127)
{
LcdWriteCommand(val,LcdChip3); //设置行起始位置 页地址
LcdWriteCommand(0x40|(column-128),LcdChip3); //列地址设置指令
for(i=column;i<endcol;i++) //送第三屏数据
LcdWriteData(dat[m++],LcdChip3);
}
}
// PCO |= 0x80;
}
//画矩形
void DisplayRectangle(uchar Dot_y1,uchar Dot_x1,uchar Dot_y2,uchar Dot_x2,uchar DisON)
{
unsigned char i,j;
for(i=Dot_y1;i<=Dot_y2;i++)
{
for(j=Dot_x1;j<=Dot_x2;j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -