📄 lcd.c
字号:
void inline disable()
{
asm(" setc INTM");
}
//系统初始化子程序
void initial()
{
asm(" setc SXM"); // 抑制符号位扩展
asm(" clrc OVM"); // 累加器中结果正常溢出
asm(" clrc CNF"); // B0被配置为数据存储空间
asm(" setc INTM"); // 禁止所有中断
*SCSR1=0x81FE; // CLKIN=6M,CLKOUT=4*CLKIN=24M
*WDCR=0x0E8; // 不使能看门狗,因为SCSR2中的WDOVERRIDE
// 即WDC位复位后的缺省值,故可以用
// 软件禁止看门狗
*IMR=0x0000; // 禁止所有中断
*IFR=0x0FFFF; // 清除全部中断标志,"写1清0"
*MCRC=*MCRC&0x0e3FF; // IOPF2,F3,F4端口配置为一般的I/O功能
*PFDATDIR=0x0FFe3; //IOPF2,F3,F4端口配置为输出低电平
*MCRA=*MCRA&0x00c7; // 配置IOPA[3-5],IOPB[0-7]为一般I/O口功能
*PADATDIR=0x0FF00; // IOPA[3-4]为输出,且全部为0
disable(); // 总中断禁止
}
//读液晶显示器的状态子程序,形参E代表处理的液晶的边(E1或E2边)
void LCDSTA1(E)
int E;
{
int E1FLAG,i=0;
*PBDATDIR=*PBDATDIR&0x0000; //IOPB口为输入
if(E==1)
*PADATDIR=0x0FF18; //E1=1
else *PADATDIR=0x0FF20; //E2=1
*PFDATDIR=0x0FF08; // LCD_RW = 1;
// LCD_DI = 0;
while(1)
{
*PFDATDIR=*PFDATDIR|0x0FF10; //LCD_E = 1;
for(i=0; i<2; i++){}
*PFDATDIR=*PFDATDIR&0x0FFef; //LCD_E = 0;
E1FLAG=*PBDATDIR&0x0080; // 读液晶状态
if(E1FLAG==0x0000)break; //若液晶空闲,则停止等待
}
}
//对液晶显示器发指令子程序,形参E代表处理的液晶的边(E1或E2)
void TRANS1(TRANS,E) //该函数采用形参和实参的方式传递数值,TRANS为一个形参
int TRANS,E;
{ int i=0;
LCDSTA1(E); //判断液晶是否为忙
*PBDATDIR=*PBDATDIR|0x0FF00; //IOPB口为输出
if(E==1) *PADATDIR=0x0FF18; //E1=1,
else *PADATDIR=0x0FF20; //E2=1,
*PFDATDIR=0x0FF10; //LCD_RW = 0;
//LCD_DI = 0;
//LCD_E = 1;
*PBDATDIR=(*PBDATDIR&0x0FF00)|TRANS; //需要写入的命令字送入数据线
for(i=0; i<2; i++){}
*PFDATDIR=*PFDATDIR&0x0FFef; //LCD_E = 0;
}
//对液晶显示器写数据子程序,注意在此子程序中列地址没有加1,需要用户在外对其进行操作,形参E代表处理的液晶的边(E1或E2)
void WRITE1(WRITE,Yaddress,E) //WRITE代表需要写入的数据,Yaddress代表需要的列地址
int WRITE,Yaddress,E;
{
int i=0;
TRANS1(Yaddress,E); //设置列地址
LCDSTA1(E); //查询液晶是否空闲
*PBDATDIR=*PBDATDIR|0x0FF00; //IOPB口为输出
if(E==1) *PADATDIR=0x0FF18; //E1=1
else *PADATDIR=0x0FF20; //E1=0,E2=1
*PFDATDIR=0x0FF14;// LCD_RW = 0;
//LCD_DI = 1;
//LCD_E = 1;
*PBDATDIR=(*PBDATDIR&0x0FF00)|WRITE; //写入数据
for(i=0; i<2; i++){}
*PFDATDIR=*PFDATDIR&0x0FFef; //LCD_E = 0;
}
//开E1显示子程序,形参E代表处理的液晶的边(E1或E2)
void DISP1(E)
int E;
{
int E1FLAG,i=0;
while(1)
{
TRANS1(0x03F,E); //送出控制字
LCDSTA1(E); //判断液晶是否为忙
*PBDATDIR=*PBDATDIR&0x00ff; //IOPB口为输入
if(E==1) *PADATDIR=0x0FF18; //E1=1
else *PADATDIR=0x0FF20; //E1=0,E2=1
*PFDATDIR=0x0FF18;// LCD_RW = 1;
//LCD_DI = 0;
//LCD_E = 1;
for(i=0; i<2; i++){}
*PFDATDIR=*PFDATDIR&0x0ffef; //LCD_E = 0;
E1FLAG=*PBDATDIR&0x0020; // 读液晶状态
if(E1FLAG==0x0000) break; //如果液晶被打开,则退出循环
}
}
//E1边清屏子程序,形参E代表处理的液晶的边(E1或E2)
void CLEAR1(int E)
{
int PAGENUM,Yaddress; //定义所需要的局部变量
for (PAGENUM=0x0B8; PAGENUM<=0x0BF; PAGENUM++)
{
TRANS1(PAGENUM,E); //设置相应的页地址
for(Yaddress=0x40; Yaddress<=0x7F; Yaddress++)
{
WRITE1(0x00,Yaddress,E); //向相应的列送0以清屏
}
}
}
//关E1显示子程序,形参E代表处理的液晶的边(E1或E2)
void DISOFF1(int E)
{
int E1FLAG,i=0;
while(1)
{
TRANS1(0x3E,E); //送出控制字
LCDSTA1(E); //判断液晶是否为空闲
*PBDATDIR=*PBDATDIR&0x00FF; //IOPB口为输入
if(E==1) *PADATDIR=0x0FF18; //E1=1
else *PADATDIR=0x0FF20; //E1=0
*PFDATDIR=0x0FF18;// LCD_RW = 1;
//LCD_DI = 0;
//LCD_E = 1;
for(i=0; i<2; i++){}
*PFDATDIR=*PFDATDIR&0x0FFef; //LCD_E = 0;
E1FLAG=*PBDATDIR&0x0020; // 读液晶状态
if(E1FLAG==0x0020) break; //如液晶关闭,则退出循环
}
}
//LCD的E1初始化子程序,形参E代表处理的液晶的边(E1或E2)
void LCD1INIT(int E)
{
DISOFF1(E); //关显示E1
TRANS1(0x0A4,E); //不静态显示驱动
TRANS1(0x0A9,E); //占空比为1/32
TRANS1(0x0E2,E); //复位
TRANS1(0x0A0,E); //ADC选择正常输出
CLEAR1(E); //清屏
DISP1(E); //开显示
}
// 汉字显示子程序,入口为存储汉字库的数组的首地址,页地址和起始列地址
// 和选中的E1或E2的边数
DISPLAY1(n,E,PAGADD,Yaddress)
int n,PAGADD,Yaddress,E; // 定义所需要的局部变量
{
int K;
char TEMP;
TRANS1(0x0C0,E); // 从第0行开始显示
TRANS1(PAGADD,E); // 送需要显示的页地址
n=n*16;
for(K=0;K<8;K++,Yaddress++)
{
TEMP=table1[K+n];
WRITE1(TEMP,Yaddress,E); // 送需要显示的数据字节
}
Yaddress=Yaddress-8; // 恢复列地址
PAGADD=PAGADD+1; // 页地址加1
TRANS1(PAGADD,E);
for(;K<16;K++,Yaddress++)
{
TEMP=table1[K+n];
WRITE1(TEMP,Yaddress,E); // 送需要显示的数据字节
}
TRANS1(0x0c0,E);
PAGADD=PAGADD-1;
TRANS1(PAGADD,E);
}
char TabASCII[80]=//0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,.?!:;()
{
048,049,050,051,052,053,054,055,056,057,//数字“0123456789”
065,066,067,068,069,070,071,072,073,074,075,076,077,078,079,080,081,082,083,084,085,086,087,088,089,090,//大写字母“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
097,098,099,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,//小写字母“a-z”
096,250,063,033,058,059,040,041,032,000
}
bool DISPLAY(int RowNum,int ColNum,int i)//显示函数,将屏幕划分为4行(0-3)16列(0-15)显示字符,
{
if(i=70) ColNum++;//是空格
if(i=71)//是换行符
{
RowNum=0;
ColNum=++;
}
if(RowNum==4)RowNum=0;
if(ColNum==16)ColNum=0;
if(RowNum>4||ColNum>16) return;
int E;//边,一共有两个驱动器控制,即边数为2
int PageAddress;//页地址
int ColAddress;//列地址
if(ColNum<8) E=1;//设置边数
else E=2;
switch(RowNum)//设置页地址
{
case 0:PageAddress=0xB8;
case 0:PageAddress=0xBA;
case 0:PageAddress=0xBC;
case 0:PageAddress=0xBF;
}
if(E==1) ColAddress=0x40+ColNum;//设置列地址
else ColAddress=0x40+ColNum-8;
DISPLAY1(i,E,PageAddress,ColAddress);
RowNum++;
ColNum++;
}
bool DispChar(char m_c)
{
int i;
for(i=0;i<80;i++)
{
if (TabASCII[i]==m_c)
{
DISPLAY(RowNum,ColNum,i);
return;
}
}
}
// 主程序
main()
{
initial(); // 系统初始化
LCD1INIT(1); // LCD的E1边初始化
LCD1INIT(2); // LCD的E2边初始化
DISPLAY1(0,1,0xBA,0x47);//重
DISPLAY1(1,1,0xBA,0x67);//庆
DISPLAY1(2,2,0xBA,0x47);//大
DISPLAY1(3,2,0xBA,0x67);//学
for( ; ; ){}
}
// 如若因干扰引起中断的误执行,则执行此中断服务程序
void interrupt nothing()
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -