1、//-----------------Main.c--------------
//名称:用8051与1601LCD设计的整数计算器
//---------------------------------------
#include
2、stpress; static xdata char outputbuffer[MAX_DISPLAY_CHAR];//输出缓冲 //---------------------------------------------- //主程序 //------------- void main() { //变量初始化 lvalue=0; rvalue=0; currtoken='='; lasttoken='='; //初始化LCD initialise(); calc_putput(OK); calc_evaluate(); } //---
3、 //获取按键值并进行计算处理 //----------------------------------------- void calc_evaluate() { char data key; int data i; char xdata number[MAX_DISPLAY_CHAR]; char xdata *bufferptr; //清除缓冲 for(i=0;i<=MAX_DISPLAY_CHAR;i++) number[i]=' '; bufferptr=numb
4、er; 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
5、 rvalue=calc_asciidec(number); //清除数字蝗虫 bufferptr=number; for(i=0;i<=MAX_DISPLAY_CHAR;i++) number[i]=' '; //处理操作符 currtoken=key; if(currtoken=='C') calc_opfunctions(currtoken); else calc_opfunctions(lasetoken); //清除输出缓冲 for(i=0;i<=M
6、AX_DISPLAY_CHAR;i++) outpufbuffer[i]=' '; bufferptr=number; if(currtoken!0x3d) lasttoken=currtoken; } lastpress=key; } } //------------------------------------------- // 根据运算符按键进行运算处理 //-------------------------------------------- void calc_opfunctions (char
7、token) { char data result; switch(token) { case '+':if(currtoken=='='||isdigit(lastpress)) { lvalue+=rvalue; result=calc_chkerror(lvalue); } else result=SLEEP; break; case '-':if(currtoken=='='||isdigit(lastpress)) { lvalue-=rvalue; result=calc_chkerror(lv
8、alue); } else result=SLEEP; break; case '*':if(currtoken=='='||isdigit(lastpress)) { lvalue*=rvalue; result=calc_chkerror(lvalue); } else result=SLEEP; break; case '/':if(currtoken=='='||isdigit(lastpress)) { lvalue/=rvalue; result=calc_chkerror(lvalue);
9、 } else result=SLEEP; break; //取消 case 'C':lvalue=0; rvalue=0; currtoken='0'; lasttoken='0'; result=OK; break; default:result=SLEEP; } calc_output(result); } //-------------------------------------------------------- // 检查待显示数据的上界和下界 //
10、 例如,99999999 and -99999999 //-------------------------------------------------------- int calc_chkerror (long num) { if(num>=-99999999&&num<=99999999) return OK; else return ERROR; } //----------------------------------------------------------- // 根据操作状态输出 //--------------------
11、 { switch(status) { case OK:calc_deaplay(calc_decascii(lvalue)); break; case SLEEP: break; case ERROR:calc_display("Exception"); break; default:calc_display("Exception") break; } } //----------------------------------
12、 //将ASCII字符串转换为浮点数 //---------------------------------------------------- long calc_asciidec (char *buffer) { long data value; long data digit; value=0; while(*buffer!=' ') { digit=*buffer-'0'; value=value*10+digit; buffer++ } return value; } //-------
13、 //将浮点数转换为ASCII字符串 //---------------------------------------------------- char *calc_decascii(long num) { long data temp=num; char xdata *avvayptr=&outputbuffer[MAX_DISPLAY_CHAR]; long data divisor=10; long data result; char data remainder,a
14、sciival;
int data i;
//如果计算结果为0。,则在缓冲中插入0并结束
if(!temp)
{
*arrayptr='0';
goto done;
}
if(temp<0) //处理负数
{
outputbuffer[0]='-';
temp-=2*temp;
}
for(i=0;i 15、 *arrayptr=' ';
else
{
asciival=remainder+'0';
*arrayptr=asciival;
}
temp/=10;
//为“—”号保留位置
if(arrayptr!=&outputbuffer[1])
arrayptr--;
}
done:return outputbuffer;
}
//------------------------------------------------
//测试按键时数字还是操作符,如果是数字则返回1.是操作符时返回0
//----------- 16、
char calc_testkey (char key)
{
if(isdigit(key))
return 1;
else
teturn 0;
}
//------------------------------------------------
//调用input例程搜索按键,并返回按键的ASCII码值
//------------------------------------------------
char calc_getkey()
{
char data myke 17、y;
do
{
mykey=input();
}
while(mykey==0);
return mykey;
}
//------------------------------------------------
//调用Output和Clearscreen例程向LCD输出ASCII
//------------------------------------------------
void calc_display (char buf[MAX_DISPLAY_CHAR])
{
int data i=0;
clearscreen();
f 18、or(i;i<=MAX_DISPLAY_CHAR;i++)
{
if(buf[i]!=' ')
output(buf[i]);
}
}
//----------------------calc.h---------------------
//本例头文件
//-------------------------------------------------
typedef unsigned short WORD;
typedef unsigned char BYTE;
//------------------------------------------ 19、
//定义适合屏幕显示的ASCII字符的最大个数
//------------------------------------------------
#define MAX_DISPLAY_CHAR 9
//------------------------------------------------
//错误处理状态
//------------------------------------------------
enum ERROR {OK=0,SLEEP=1,ERROR=2};
//----------------------------------- 20、
//函数声明
//------------------------------------------------
void calc_evaluate();
void calc_opfunctions (char token);
char calc_testkey (char ch);
long calc_asciidec (char *buffer);
char *calc_decascii (long num);
int calc_chkerror (long num);
void calc_output (int status) 21、
char calc_getkey();
void calc_display(char buf[MAX_DISPLAY_CHAR]);
void initialise();
char input();
char output(char ch);
void clearscreen;
//---------------------------lcd.c-------------------------
//单行液晶显示程序
//---------------------------------------------------------
#include 22、
#include 23、CD_SETVISIBLE 8
#define LCD_SHIFT 16
#define LCD_SETFUNCTION 32
#define LCD_SETCGADDR 64
#define LCD_SETDDADDR 128
sbit bflag=ACC^7;//忙标志位
void wrcmd(uchar);
void output(char);
void busywait();
//------------------------------------------------
//初始化LCD
//------------ 24、
void initialise()
{
wrcmd(0x30); //1行8位
wrcmd(LCD_SETVISIBLE+4); //显示开,关光标
wrcmd(LCD_SETDDADDR+15); //从右边开始显示
wrcmd(LCD_SETMODE+3); // 递增左移
}
//------------------------------------------------
//清屏并将显示位置起点设置在最右边
//-------------------------- 25、
void clearscreen()
{
wrcmd(LCD_CLS);
wrcmd(LCD_SETDDADDR+15);
}
//------------------------------------------------
//向LCD写命令
//------------------------------------------------
void wrcmd(uchar cmd)
{
uchar volatile pdata *p=LCD_CMD_WR;
P2=LCD_PAGE;
*p=cmd; 26、
//上面三行可用下面的代码替换
//XBYTE[0x8000]=cmd;
busywait();
}
//------------------------------------------------
//向LCD写一个字符
//------------------------------------------------
void output(char ch)
{
char volatile pdata *p=LCD_DATA_WR;
P2=LCD_PAGE;
*p=ch;
//上面三行可用下面的代码替换
//XBYTE[0x8001]=c 27、h;
busywait();
}
//------------------------------------------------
//忙等待
//------------------------------------------------
void busywait()
{
uchar volatile pdata *p=LCD_BUSY_RD;
P2=LCD_PAGE;
//上面两行可改成:
//uchar volatile pdata *p=0x8002;
do
{
ACC=*p;
}
while(bflag==1);
/ 28、/上述所有代码也可用以下代码替换
/*
do
{
ACC=XBYTE[0x8002];
}
while(bflag==1);
*/
}
//------------------keypad.c-------------------
//键盘扫描函数char input();返回按键的ASCII码
//---------------------------------------------
#include 29、',
'4','5','6','*',
'1','2','3','-',
'C','0','=','+'
};
char data keyflags[16];
//------------------------------------------------
//获取键盘按键子程序
//------------------------------------------------
char input()
{
char *pKeyflag=keyflags; //标识按键指针
char RowAddr=0xef; 30、 //键盘行地址1110 1111
char ColData=0; //列数据
char i,j,Tmp=0;
for(i=0;i<4;i++)
{
P2=RowAddr; //在P2端口设置行地址
_nop_();
Tmp=P1&0x0f; //从P1端口读取列数据
for(j=0;j<4;j++)
{
ColData=Tmp; //保存当前列数据
if((Tmp&0x01)==0x00) //如果有键按下
{
Tmp=*pKeyflag;
*pKeyflag=1; //标识按键
if(Tmp==0) //有新按键按下
{
P2=0xff;
return keycodes[pKeyflag-keyflags];
}
}
else *pKeyflag=0;
pKeyflag++;
Tmp=ColData>>1;
}
RowAddr<<=1;
}
P2=0xff;
return 0;
}






