如压缩包
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit pinRS=P2^0;
- sbit pinRW=P2^1;
- sbit pinE=P2^2;
- #define pindata P0
- #define clearscreen() writeinstruc(0x01)
- #define cursorreturn() writeinstruc(0x02)
- #define inputmode(temp) writeinstruc(temp)
- //temp取值如下:
- //0x04:减量方式,不移位
- //0x05:减量方式,移位
- //0x06:增量方式,不移位
- //0x07:增量方式,移位
- #define dispcontrol(temp) writeinstruc(temp)
- //temp取值如下:
- //0x08:显示关,光标关,闪烁关
- //0x0c:显示关,光标关,闪烁关
- //0x0d:显示开,光标关,闪烁开
- //0x0e:显示开,光标开,闪烁关
- //0x0f:显示开,光标开,闪烁开
- #define dispshift(temp) writeinstruc(temp)
- //temp取值如下:
- //0x10:光标左移
- //0x14:光标右移
- //0x18:显示整体左移
- //0x1c:显示整体右移
- #define functionset(temp) writeinstruc(temp)
- //temp取值如下:
- //0x20:4位,1行,5*7
- //0x24:4位,1行,5*10
- //0x28:4位,2行,5*7
- //0x2c:4位,2行,5*10
- //0x30:8位,1行,5*7
- //0x34:8位,1行,5*10
- //0x38:8位,2行,5*7
- //0x3c:8位,2行,5*10
- #define setCGRAM_Add(address) writeinstruc(0x40|address)
- #define setDDRAM_Add(address) writeinstruc(0x80|address)//短延时
- //void shortdelay(uchar i);
- //长延时
- //void longdelay(uint i);
- //P2口初始化
- //void initP2(bit i);
- //寄存器选择信号
- //void setRS(bit i);
- //读写操作控制
- //void setRW(bit i);
- //使能信号
- //void setE(bit i);
- //读BF以及AC的值
- //uint read_BF_AC();
- //判忙
- //bit statuscheck();
- //写指令函数
- //void writeinstruc(uint instruc);
- //写数据到RAM
- //void writedata(uint data1);
- //从RAM中读数据函数
- //uint readdata(void);
- //显示程序 X为行号,Y为列号,date为要显示的数据
- //void dispcharacter(int x,uint y,uint data1);
- //LCD复位函数
- //void LCDreset();
- #define uchar unsigned char
- uchar k=0,result1;
- void shortdelay(uchar i)//短延时
- {
- for(;i>0;i--);
- }
- //长延时
- void longdelay(uint i)
- {
- uint j;
- for(;i>0;i--)
- {for(j=100;j>0;j--);}
- }
- //延时程序
- void delay(int i)
- {int j;
- for(;i>0;i--)
- for(j=0;j<100;j++);
- }
- //初试状态
- void io_init()
- {P1=0xff;
- }
- //?---------------------------键盘扫描部分-----------------------------//
- unsigned char key_scan()
- { unsigned char key;
- unsigned char temp;
- uint flag;
- io_init();
- P1=0xf0;
- flag=0;
- loop: temp=P1^0xf0;
- while(temp)
- {
- P1=0xfe;
- delay(1);
- if((P1&0xfe)!=0xfe)
- switch(P1)
- {
- case 0xee: key=0x11;flag=1;break;//读7键和值
- case 0xde: key=0x12;flag=1;break;
- case 0xbe: key=0x13;flag=1;break;
- case 0x7e: key=0x14;flag=1;break;//读除键的值
- }
- if(flag)
- goto exit;
- else
- P1=0xfd;
- delay(1);
- if((P1&0xfd)!=0xfd)
- switch(P1)
- {
- case 0xed: key=0x21;flag=1;break;
- case 0xdd: key=0x22;flag=1;break;
- case 0xbd: key=0x23;flag=1;break;
- case 0x7d: key=0x24;flag=1;break; //读4到乘的键值
- }
- if(flag)
- goto exit;
- else
- P1=0xfb;
- delay(1);
- if((P1&0xfb)!=0xfb)
- switch(P1)
- {
- case 0xeb: key=0x31;flag=1;break;
- case 0xdb: key=0x32;flag=1;break;
- case 0xbb: key=0x33;flag=1;break;
- case 0x7b: key=0x34;flag=1;break;//读1到减的键值
- }
- if(flag)
- goto exit;
- else
- P1=0xf7;
- delay(1);
- if((P1&0xf7)!=0xf7)
- switch(P1)
- {
- case 0xe7: key=0x41;flag=1;break;//后退
- case 0xd7: key=0x42;flag=1;break;//0
- case 0xb7: key=0x43;flag=1;break;//等于
- case 0x77: key=0x44;flag=1;break;//加
- }
-
- exit: return key;
- }
- if(temp==0)
- goto loop;
- }
- //---------------------------------键盘扫描完--------------------------------------------//
- //---------------------------------显示初始化?----------------------------------------//
- //P0口初始化
- void initpindata(bit i)
- {
- if(i==1) pindata=0xff;
- else pindata=0X00;
- }
- //寄存器选择信号
- void setRS(bit i)
- {
- if(i==1) pinRS=1;
- else pinRS=0;
- }
- //读写操作控制
- void setRW(bit i)
- {
- if(i==1) pinRW=1;
- else pinRW=0;
- }
- //使能信号
- void setE(bit i)
- {
- if(i==1) pinE=1;
- else pinE=0;
- }
- //读BF以及AC的值
- uint read_BF_AC()
- {
- uint temp;
- initpindata(1);
- setRS(0);
- setRW(1);
- setE(1);
- shortdelay(1);
- temp=pindata;
- shortdelay(10);
- setE(0);
- return(temp);
- }
- //判忙
- bit statuscheck()
- {
- return((bit)(read_BF_AC()&0x80));
- }
- //写指令函数
- void writeinstruc(uint instruc)
- {
- while(statuscheck());
- initpindata(0);
- setRS(0);
- setRW(0);
- setE(0);
- pindata=instruc;
- //short delay(1);
- setE(1);
- shortdelay(10);
- setE(0);
- }
- //写数据到RAM
- void writedata(uint data1)
- {
- initpindata(0);
- setRS(1);
- setRW(0);
- setE(0);
- pindata=data1;
- setE(1);
- shortdelay(10);
- setE(0);
- }
- //从RAM中读数据函数
- uint readdata(void)
- {
- uint temp;
- initpindata(1);
- setRS(1);
- setRW(1);
- setE(1);
- shortdelay(1);
- temp=pindata;
- shortdelay(10);
- setE(0);
- return(temp);
- }
- //显示程序 X为行号,Y为列号,date为要显示的数据
- void dispcharacter(int x,uint y,uint data1)
- {
- uint temp;
- while(statuscheck());
- temp=y&0x0f;
- x&=0x01;
- if(x) temp|=0x40;
- setDDRAM_Add(temp);
- writedata(data1);
- // writedata(data1);
- }
- //LCD复位函数
- void LCDreset()
- {
- clearscreen();
- cursorreturn();
- }
- //LCD初始化
- void initLCD()
- {
- LCDreset();
- inputmode(0x06);//增量方式,不移位
- dispcontrol(0x0c);//显示开,光标关,闪烁关
- functionset(0x38);//8位,2行,5*7
- }
- //-----------------------------------准备工作完成-----------------------------------//
- //-----------------------------------计算器-----------------------------------------//
- compute(char key1,i)
- {
- signed char m,n,c,act;
- long int num1,num2,result;
- signed char str[4][4]={{'7','8','9','/'},
- {'4','5','6','*'},
- {'1','2','3','-'},
- {'c','0','=','+'}};
- signed char str1[11],string1[2];
- m=(key1&0xf0);
- m=m/16;
- m=m-1;
- n=key1&0x0f;
- n=n-1;
- c=str[m][n];
- sprintf(string1,"%c",c);
- strcat(str1,string1);
- if((c=='+')||(c=='-')||(c=='*')||(c=='/'))
- {
- act=c;
- num1=atoi(str1);
- memset(str1,0,11);
- memset(string1,0,2);
- }
- if(c=='=')
- {
- num2=atoi(str1);
- switch(act)
- {
- case'+':
- { if(k==0)
- {result=num1+num2;k++;break;}
- else
- {result+=num2;k++;break;}
- }
- case'-':
- {if(k==0)
- {result=num1-num2;k++;break;}
- else
- {result-=num2;k++;break;}
- }
- case'*':
- {if(k==0)
- {result=num1*num2;k++;break;}
- else
- {result*=num2;k++;break;}
- }
- case'/':
- {if(k==0)
- {result=num1/num2;k++;break;}
- else
- { result/=num2;k++;break;}
- }
- }
- }
- if(c=='c')
- {
- act=0;
- num1=str1[0];
- num1=str1[8];
- memset(str1,0,11);
- memset(string1,0,2);
- num1=str1[0];
- num1=str1[8];
- k=0;
- }
- longdelay(350);
- switch(key1) //显示部分
- {case 0x11: dispcharacter(0,i,'7');i++;break;
- case 0x12: dispcharacter(0,i,'8');i++; break;
- case 0x13: dispcharacter(0,i,'9');i++; break;
- case 0x14: dispcharacter(0,i,'/');i++;break;
- case 0x21: dispcharacter(0,i,'4');i++;break;
- case 0x22: dispcharacter(0,i,'5');i++;break;
- case 0x23: dispcharacter(0,i,'6');i++;break;
- case 0x24: dispcharacter(0,i,'*');i++;break;
- case 0x31: dispcharacter(0,i,'1');i++;break;
- case 0x32: dispcharacter(0,i,'2');i++;break;
- case 0x33: dispcharacter(0,i,'3');i++;break;
- case 0x34: dispcharacter(0,i,'-');i++;break;
- case 0x41: clearscreen(); break;
- case 0x42: dispcharacter(0,i,'0');i++;break;
- case 0x43: dispcharacter(0,i,'=');i++;
- m=result/10000;
- result1=result%10000;
- if(m!=0||result==0)
- {
- n=0;
- m=m+'0';
- dispcharacter(0,i,m);i++;
- }
- m=result1/1000;
- result1=result1%1000;
- if(m!=0||n==0)
- {
- m=m+'0';
- n=0;
- dispcharacter(0,i,m);i++;
- }
- m=result1/100;
- result1=result1%100;
- if(m!=0||n==0)
- {
- m=m+'0';
- n=0;
- dispcharacter(0,i,m);i++;
- }
- m=result1/10;
- result1=result1%10;
- if(m!=0||n==0)
- {
- m=m+'0';
- n=0;
- dispcharacter(0,i,m);i++;
- }
- m=result1;
- if(m!=0||n==0)
- m=m+'0';
- dispcharacter(0,i,m);i++;break;
- case 0x44: dispcharacter(0,i,'+');i++;break;
- }
- return(i);
- }
- //---------------------------------------------------------------------------------//
- //-------------------------------------主函数---------------------------------------//
- void main()
- {
- char key1,i;
- start:initpindata(0);
- P2=0X00;
- initLCD();
- i=0;
- scan:key1=key_scan();
- i=compute(key1,i);
- if(key1==0x41)
- goto start;
- else
- goto scan;
- }
复制代码
所有资料51hei提供下载:
简易计算器.zip
(207.35 KB, 下载次数: 111)
|