LCDE==P2.7LCD使能
DB==P0数据位
RD==P2.6写模式选择
WR==P2.5读写使能
指令码:二进制十六进制
清屏:100000000x80;
光标归位:X10000000x40或0xC0
。。。。。。。。
读状态输入:RS=L,RW=H,E=H 输出:DB0~DB7=状态字
写指令输入:RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码输出:无
读数据输入:RS=H,RW=H,E=H 输出:DB0~DB7=数据
写数据输入:RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据输出:无
上次写的驱动:
#include<reg52.h>
#include"LCD1602.h"
#include<stdio.h>
#include<calculateTheExpress.h>
#include<string.h>
#include<keyEventProcess.h>
#include<math.h>
sbit lcdrs =P3^0;//数据/命令选择端(H/L)
sbit lcdrw =P3^1;//读/写选择端(H/L)
sbit lcden =P3^2;//使能信号端
char theDisplayLength=0,//保存应该在当前显示的位数
cursorPosition=0;//保存光标所在显示屏的位置
charstartAddress=0,endAddress=0;//保存显示的起始和结束地址
char LCDBuffer[16]={""};
char ctrlStr[7]={".4f"};
void delayms(int xms) //延时X毫秒
{
int i, j;
for(i=xms;i>0;i--)
for(j=121;j>0;j--);
}
void write_com(char com)//写命令
{
lcdrs=0;
P0=com;
delayms(1);
lcden=1;
delayms(1);
lcden=0;
}
void write_data(char mydata)////写数据
{
lcdrs=1;
P0=mydata;
delayms(1);
lcden=1;
delayms(1);
lcden=0;
}
void initLCD()//初始化
{
lcdrw=0;
lcden=0;
write_com(0x38);//设置16x2显示,5x7点阵,8位数据接口
write_com(0x0e);//00001dcb,d=1开显示,c=1显示光标,b=1光标闪烁
write_com(0x06);//000001ns,n=1字符后地址指针加一,且光标加
//s=1写字符,正屏显示左移(n=1)
write_com(0x80);//设置数据地址指针(0-27H,40-67H)
write_com(0x01);//01,显示清屏:1,数据指针清零。2,所有显示清零
//02,显示回车:1,数据指针清零。
startAddress=0;
endAddress=-1;
}
void write_position(char position)//字符要显示在LCD哪个位置
{
lcdrs=0;
lcdrw=0;
lcden=0;
P0=position;
delayms(1);
lcden=1;
delayms(1);
lcden=0;
}
///功能函数部分
void displayOneCharacter(char mydata,char position)
{
write_position(position);
write_data(mydata);
}
void loadAndDisplay(bit judge)
{
if(judge==0)
{
//显示上面的16个字符
displayOneCharacter(LCDBuffer[0],0x80);
displayOneCharacter(LCDBuffer[1],0x81);
displayOneCharacter(LCDBuffer[2],0x82);
displayOneCharacter(LCDBuffer[3],0x83);
displayOneCharacter(LCDBuffer[4],0x84);
displayOneCharacter(LCDBuffer[5],0x85);
displayOneCharacter(LCDBuffer[6],0x86);
displayOneCharacter(LCDBuffer[7],0x87);
displayOneCharacter(LCDBuffer[8],0x88);
displayOneCharacter(LCDBuffer[9],0x89);
displayOneCharacter(LCDBuffer[10],0x8A);
displayOneCharacter(LCDBuffer[11],0x8B);
displayOneCharacter(LCDBuffer[12],0x8C);
displayOneCharacter(LCDBuffer[13],0x8D);
displayOneCharacter(LCDBuffer[14],0x8E);
displayOneCharacter(LCDBuffer[15],0x8F);
}
if(judge==1)
{
//显示下面的16个字符
displayOneCharacter(LCDBuffer[0],0xC0);
displayOneCharacter(LCDBuffer[1],0xC1);
displayOneCharacter(LCDBuffer[2],0xC2);
displayOneCharacter(LCDBuffer[3],0xC3);
displayOneCharacter(LCDBuffer[4],0xC4);
displayOneCharacter(LCDBuffer[5],0xC5);
displayOneCharacter(LCDBuffer[6],0xC6);
displayOneCharacter(LCDBuffer[7],0xC7);
displayOneCharacter(LCDBuffer[8],0xC8);
displayOneCharacter(LCDBuffer[9],0xC9);
displayOneCharacter(LCDBuffer[10],0xCA);
displayOneCharacter(LCDBuffer[11],0xCB);
displayOneCharacter(LCDBuffer[12],0xCC);
displayOneCharacter(LCDBuffer[13],0xCD);
displayOneCharacter(LCDBuffer[14],0xCE);
displayOneCharacter(LCDBuffer[15],0xCF);
}
}
void setCursorPosition(char position) //移动光标位置
{
char i;
write_com(0x02);//光标归位
for(i=0;i<position;i++)
{
write_com(0x14);//右移
}
}
//下面的代码用于动态显示字符的,主要的东西在上面
void moveLeftOneStep(void)//左右移动
{
if(cursorPosition==0)//表明要通过翻页左移
{
if(startAddress!=0)//表明还可左移一次 剩下情况没法移动
{
startAddress--;//确定显示的结束位置
if(expressLength-startAddress>=16)//表明显示满了
{
endAddress=startAddress+15;
return;
}
else//表明后面还有几个空要填满
{
endAddress=expressLength-1;
}
}
}
else//表明无需翻页
{
cursorPosition--;
}
}
void moveRightOneStep(void)
{
if(startAddress+cursorPosition==endAddress+1)
return;
if(cursorPosition==15)//表明要考虑是否进行翻页
{
if(startAddress+16<expressLength)//可翻页
//表明 startAddress+15得到的是LCD最后一位对应express的地址 再加1表示长度
{
startAddress++;
endAddress=startAddress+15;
displayExpress();
}
else if(startAddress+16==expressLength)//表明当前已是最后一个字符
{
startAddress++;
endAddress=startAddress+14;//光标处应该是空
displayExpress();
}
else//表明光标处并没有显示字符
{
return;
}
}
else//表明无需翻页
{
if(cursorPosition==endAddress+1)//已到最后一个位置,光标不能再动了
{
return;
}
cursorPosition++;
endAddress=expressLength-1;
setCursorPosition(cursorPosition);
}
}
voidmoveLeft(void)//startAddress+cursorPosition是光标对应express中的地址
{
if(startAddress+cursorPosition==0)//跳转到最后
{
if(expressLength>15)
{
endAddress=expressLength-1;
startAddress=endAddress-14;
}
cursorPosition=endAddress-startAddress+2;
}
if(startAddress+cursorPosition-1>=0&&express[startAddress+cursorPosition-1]=='n')//tan,sin,ln
{
if(startAddress+cursorPosition-6>=0&&express[startAddress+cursorPosition-6]=='a'&&express[startAddress+cursorPosition-6+1]=='r')//arctan,arcsin……
{
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
}
else if(express[startAddress+cursorPosition-2]=='l')//表明为ln
{
moveLeftOneStep();
moveLeftOneStep();
}
else //表明为sin或tan
{
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
}
}
elseif(startAddress+cursorPosition-1>=0&&startAddress+cursorPosition-1>=0&&express[startAddress+cursorPosition-1]=='g')//lg
{
moveLeftOneStep();
moveLeftOneStep();
}
elseif(startAddress+cursorPosition-1>=0&&express[startAddress+cursorPosition-1]=='s')
{
if(startAddress+cursorPosition-6>=0&&express[startAddress+cursorPosition-6]=='a'&&express[startAddress+cursorPosition-6+1]=='r')//arctan,arcsin……
{
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
}
else
{
moveLeftOneStep();
moveLeftOneStep();
moveLeftOneStep();
}
}
else//表明为单个字符
{
moveLeftOneStep();
}
}
void moveRight(void)
{
if(endAddress-startAddress+1==cursorPosition)//表明光标到了最后
{
if(expressLength>15)
{
endAddress=15;
startAddress=0;
}
cursorPosition=0;
}
elseif(express[startAddress+cursorPosition]=='s'||express[startAddress+cursorPosition]=='t'||express[startAddress+cursorPosition]=='c')//sin,tan
{
moveRightOneStep();
moveRightOneStep();
moveRightOneStep();
}
elseif(express[startAddress+cursorPosition]=='a')//arctan,arcsin之类的
{
moveRightOneStep();
moveRightOneStep();
moveRightOneStep();
moveRightOneStep();
moveRightOneStep();
moveRightOneStep();
}
else if(express[startAddress+cursorPosition]=='l')//lg,ln
{
moveRightOneStep();
moveRightOneStep();
}
else//表明为单字符
moveRightOneStep();
}
void displayExpress(void)//从startAddress显示到endAddress
{
char i;
write_position(0x80);//从这里开始显示
for(i=startAddress;i<=endAddress;i++)
{
write_data(express[i]);
}
for(i=endAddress+1;i<16+startAddress;i++)//后面的写空格
{
write_data(' ');
}
}
void insertOneAndDisplay(void)
{
expressLength++;
if(cursorPosition>=0&&cursorPosition<15)//表明是在和前面当中插入的startAddress可以不变
{
//查看当前显示状态
if(endAddress-startAddress==15)//表明当前已经满显了
{
endAddress--;
}
else//表明未满显
{
endAddress++;
}
cursorPosition++;
}
else if(cursorPosition==15)//表明光标在显示器第16个显示单元处 此时 startAddress得变
{
if(endAddress-startAddress==15)//表明当前已经满显未满显的情况已在isModifyInput中处理
{
startAddress++;
endAddress++;
}
}
}
void deleteOneAndDisplay(void)
{
moveExpressForward(cursorPosition+startAddress,1);
expressLength--;
if(cursorPosition==0)
{
startAddress--;
//确定endAddress的位置
if(expressLength-startAddress>=16)//表明显示满了
{
endAddress=startAddress+15;
}
else//表明后面还有几个空要填满
{
endAddress=expressLength-1;
}
}
else
{
cursorPosition--;//光标位置要--
//确定endAddress的位置
if(expressLength-startAddress>=16)//表明显示满了
{
endAddress=startAddress+15;
}
else//表明后面还有几个空要填满
{
endAddress=expressLength-1;
}
}
}
void deleteAndDisplay(void)
{
if(startAddress==0&&cursorPosition==0)//表明没法删除了
{
return;
}
if(express[cursorPosition-1+startAddress]=='s')//表明为cos
{
if(cursorPosition-6+startAddress>=0&&express[cursorPosition-6+startAddress]=='a')
{
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
}
else
{
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
}
}
else if(express[cursorPosition-1+startAddress]=='n')//表明为sin tan或者ln
{
if(express[cursorPosition-2+startAddress]=='l')//表明为ln
{
deleteOneAndDisplay();
deleteOneAndDisplay();
}
elseif(cursorPosition-6+startAddress>=0&&express[cursorPosition-6+startAddress]=='a')//表明为arcsin或者acrtan运算
{
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
}
else//表明为sin、tan
{
deleteOneAndDisplay();
deleteOneAndDisplay();
deleteOneAndDisplay();
}
}
else if(express[cursorPosition-1+startAddress]=='g')
{
deleteOneAndDisplay();
deleteOneAndDisplay();
}
else//表明删除一个
{
deleteOneAndDisplay();
}
}
void displayInputExpress(void)//输入时调用的
{
if(keyCode=='=')
{
return;
}
if(cursorPosition==15&&startAddress+1<=100)
{
startAddress++;
endAddress=14+startAddress;
return;
}
else //仅能提供第一次输入时的显示
{
endAddress=expressLength-1;
cursorPosition++;
return;
}
warning("error 1");
}
void displayModifyExpress(void)
{
if(keyCode=='=')
{
return;
}
if(keyCode==129||keyCode==130||keyCode==131)//表明为三个字符要输入
{
insertOneAndDisplay();
insertOneAndDisplay();
insertOneAndDisplay();
}
else if(keyCode==139||keyCode==140)
{
insertOneAndDisplay();
insertOneAndDisplay();
}
elseif(keyCode>=141&&keyCode<=142)
{
insertOneAndDisplay();
insertOneAndDisplay();
insertOneAndDisplay();
insertOneAndDisplay();
insertOneAndDisplay();
insertOneAndDisplay();
}
else
{
insertOneAndDisplay();
}
}
void dispaly_dataA(void);
void dispaly_dataA(void)
{
if(dataA>=pow(10,36))
{
warning("Answer Over Flow!");
dataA=0;
dispaly_dataA();
}
else
{
sprintf(LCDBuffer,"g",dataA);
loadAndDisplay(1);
}
}
void warning(char *p)
{
sprintf(LCDBuffer,"s",p);
loadAndDisplay(0);
delayms(500);
sprintf(LCDBuffer,"s"," ");//清屏
loadAndDisplay(0);
displayExpress();
}
void moveLogo(void)//把字符向前移动
{
unsigned char i,temp;
temp=LCDBuffer[0];
for(i=0;i<15;i++)
{
LCDBuffer[i]= LCDBuffer[i+1];//前移动
}
LCDBuffer[15]=temp;
}
void showLogo(void)
{
char i;
strcpy(LCDBuffer," HuaQiang_PCB");//上次参加比赛时用的Logo
for(i=0;i<19;i++)
{
loadAndDisplay(0);
moveLogo();
delayms(100);
}
}
不足之处在于忙查询有点小问题,大家可以修改下!