用8051与1601LCD设计的整数计算器Word下载.docx
《用8051与1601LCD设计的整数计算器Word下载.docx》由会员分享,可在线阅读,更多相关《用8051与1601LCD设计的整数计算器Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
voidcalc_evaluate()
chardatakey;
intdatai;
charxdatanumber[MAX_DISPLAY_CHAR];
charxdata*bufferptr;
//清除缓冲
for(i=0;
i<
=MAX_DISPLAY_CHAR;
i++)
number[i]='
'
bufferptr=number;
while
(1)
{
key=calc_getkey();
if(calc_testkey(key))
{
if(bufferptr!
=&
number[MAX_DISPLAY_CHAR-2])
{
*bufferptr=key;
calc_display(number);
bufferptr++;
}
}
else
if(lasttoken=='
0'
)
lvalue=calc_asciidec(number);
else
rvalue=calc_asciidec(number);
//清除数字蝗虫
bufferptr=number;
for(i=0;
i++)
number[i]='
//处理操作符
currtoken=key;
if(currtoken=='
C'
)
calc_opfunctions(currtoken);
calc_opfunctions(lasetoken);
//清除输出缓冲
outpufbuffer[i]='
if(currtoken!
0x3d)
lasttoken=currtoken;
lastpress=key;
}
//-------------------------------------------
//根据运算符按键进行运算处理
//--------------------------------------------
voidcalc_opfunctions(chartoken)
chardataresult;
switch(token)
{
case'
+'
:
if(currtoken=='
||isdigit(lastpress))
lvalue+=rvalue;
result=calc_chkerror(lvalue);
elseresult=SLEEP;
break;
-'
lvalue-=rvalue;
*'
lvalue*=rvalue;
/'
lvalue/=rvalue;
//取消
case'
lvalue=0;
rvalue=0;
result=OK;
break;
default:
result=SLEEP;
}
calc_output(result);
//--------------------------------------------------------
//检查待显示数据的上界和下界
//例如,99999999and-99999999
intcalc_chkerror(longnum)
if(num>
=-99999999&
&
num<
=99999999)
returnOK;
else
returnERROR;
//-----------------------------------------------------------
//根据操作状态输出
switch(status)
caseOK:
calc_deaplay(calc_decascii(lvalue));
break;
caseSLEEP:
break;
caseERROR:
calc_display("
Exception"
);
break;
default:
//----------------------------------------------------
//将ASCII字符串转换为浮点数
longcalc_asciidec(char*buffer)
{
longdatavalue;
longdatadigit;
value=0;
while(*buffer!
digit=*buffer-'
value=value*10+digit;
buffer++
returnvalue;
//将浮点数转换为ASCII字符串
char*calc_decascii(longnum)
longdatatemp=num;
charxdata*avvayptr=&
outputbuffer[MAX_DISPLAY_CHAR];
longdatadivisor=10;
longdataresult;
chardataremainder,asciival;
//如果计算结果为0。
,则在缓冲中插入0并结束
if(!
temp)
*arrayptr='
gotodone;
}
if(temp<
0)//处理负数
outputbuffer[0]='
temp-=2*temp;
sizeof(outputbuffer);
remainber=temp%divisor;
result=temp/divisor;
if((!
remainder)&
(!
result))
*arrayptr='
else
asciival=remainder+'
*arrayptr=asciival;
temp/=10;
//为“—”号保留位置
if(arrayptr!
outputbuffer[1])
arrayptr--;
done:
returnoutputbuffer;
//------------------------------------------------
//测试按键时数字还是操作符,如果是数字则返回1.是操作符时返回0
charcalc_testkey(charkey)
if(isdigit(key))
return1;
else
teturn0;
//调用input例程搜索按键,并返回按键的ASCII码值
charcalc_getkey()
chardatamykey;
do
mykey=input();
while(mykey==0);
returnmykey;
//调用Output和Clearscreen例程向LCD输出ASCII
voidcalc_display(charbuf[MAX_DISPLAY_CHAR])
intdatai=0;
clearscreen();
for(i;
if(buf[i]!
output(buf[i]);
//----------------------calc.h---------------------
//本例头文件
//-------------------------------------------------
typedefunsignedshortWORD;
typedefunsignedcharBYTE;
//定义适合屏幕显示的ASCII字符的最大个数
#defineMAX_DISPLAY_CHAR9
//错误处理状态
enumERROR{OK=0,SLEEP=1,ERROR=2};
//函数声明
voidcalc_evaluate();
voidcalc_opfunctions(chartoken);
charcalc_testkey(charch);
longcalc_asciidec(char*buffer);
char*calc_decascii(longnum);
intcalc_chkerror(longnum);
voidcalc_output(intstatus);
charcalc_getkey();
voidcalc_display(charbuf[MAX_DISPLAY_CHAR]);
voidinitialise();
charinput();
charoutput(charch);
voidclearscreen;
//---------------------------lcd.c-------------------------
//单行液晶显示程序
//---------------------------------------------------------
#include<
absacc.h>
#defineucharunsignedchar
#defineLCD_CMD_WR0x00
#defineLCD_DATA_WWR0x01
#defineLCD_BUSY_RD0x02
#defineLCD_DATA_RD0x03
#defineLCD_PAGE0x80
#defineLCD_CLS1
#defineLCD_HOME2
#defineLCD_SETMODE4
#defineLCD_SETVISIBLE8
#defineLCD_SHIFT16
#defineLCD_SETFUNCTION32
#defineLCD_SETCGADDR64
#defineLCD_SETDDADDR128
sbitbflag=ACC^7;
//忙标志位
voidwrcmd(uchar);
voidoutput(char);
voidbusywait();
//初始化LCD
voidinitialise()
wrcmd(0x30);
//1行8位
wrcmd(LCD_SETVISIBLE+4);
//显示开,关光标
wrcmd(LCD_SETDDADDR+15);
//从右边开始显示
wrcmd(LCD_SETMODE+3);
//递增左移
//清屏并将显示位置起点设置在最右边
voidclearscreen()
wrcmd(LCD_CLS);
//向LCD写命令
voidwrcmd(ucharcmd)
ucharvolatilepdata*p=LCD_CMD_WR;
P2=LCD_PAGE;
*p=cmd;
//上面三行可用下面的代码替换
//XBYTE[0x8000]=cmd;
busywait();
//向LCD写一个字符
voidoutput(charch)
charvolatilepdata*p=LCD_DATA_WR;
*p=ch;
//XBYTE[0x8001]=ch;
//忙等待
voidbusywait()
ucharvolatilepdata*p=LCD_BUSY_RD;
//上面两行可改成:
//ucharvolatilepdata*p=0x8002;
ACC=*p;
while(bflag==1);
//上述所有代码也可用以下代码替换
/*
ACC=XBYTE[0x8002];
*/
//------------------keypad.c-------------------
//键盘扫描函数charinput();
返回按键的ASCII码
//---------------------------------------------
intrins.h>
charcodekeycodes[]=
7'
'
8'
9'
4'
5'
6'
1'
2'
3'
};
chardatakeyflags[16];
//获取键盘按键子程序
charinput()
char*pKeyflag=keyflags;
//标识按键指针
charRowAddr=0xef;
//键盘行地址11101111
charColData=0;
//列数据
chari,j,Tmp=0;
4;
P2=RowAddr;
//在P2端口设置行地址
_nop_();
Tmp=P1&
0x0f;
//从P1端口读取列数据
for(j=0;
j<
j++)
ColData=Tmp;
//保存当前列数据
if((Tmp&
0x01)==0x00)//如果有键按下
Tmp=*pKeyflag;
*pKeyflag=1;
//标识按键
if(Tmp==0)//有新按键按下
P2=0xff;
returnkeycodes[pKeyflag-keyflags];
else*pKeyflag=0;
pKeyflag++;
Tmp=ColData>
>
1;
RowAddr<
<
=1;
P2=0xff;
return0;