51单片机c语言编写计算器仿真,51单片机计算器Proteus仿真+C语言代码

#include

#include

#include

#include

#include

#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;

}

好的,下面是一个简单的计算器C语言程序,可以在51单片机上实现,同时也可以在Proteus仿真运行: ```c #include <reg51.h> // 51单片机头文件 sbit ADD=P3^0; // 加法按键 sbit SUB=P3^1; // 减法按键 sbit MUL=P3^2; // 乘法按键 sbit DIV=P3^3; // 除法按键 sbit CLR=P3^4; // 清零按键 sbit OK=P3^5; // 确认按键 unsigned char num1,num2; // 两个操作数 unsigned char op; // 操作符 unsigned char result; // 运算结果 void delay(unsigned int i) // 延时函数 { unsigned int j,k; for(j=i;j>0;j--) { for(k=110;k>0;k--); } } void display(unsigned char dat) // 数码管显示函数 { P2=dat; // 将数码管的值赋给P2口 delay(5); // 延时一段时间,使数码管显示刷新 } void main() { while(1) { if(ADD==0) // 加法按键按下 { op='+'; delay(10); // 延时去抖 while(ADD==0); // 等待按键释放 } else if(SUB==0) // 减法按键按下 { op='-'; delay(10); // 延时去抖 while(SUB==0); // 等待按键释放 } else if(MUL==0) // 乘法按键按下 { op='*'; delay(10); // 延时去抖 while(MUL==0); // 等待按键释放 } else if(DIV==0) // 除法按键按下 { op='/'; delay(10); // 延时去抖 while(DIV==0); // 等待按键释放 } else if(CLR==0) // 清零按键按下 { num1=0; num2=0; op=0; result=0; display(0xff); // 数码管全灭 delay(10); // 延时去抖 while(CLR==0); // 等待按键释放 } else if(OK==0) // 确认按键按下 { switch(op) // 根据操作符进行运算 { case '+': result=num1+num2; break; case '-': result=num1-num2; break; case '*': result=num1*num2; break; case '/': result=num1/num2; break; } num1=0; num2=0; op=0; display(result); // 显示运算结果 delay(10); // 延时去抖 while(OK==0); // 等待按键释放 } else // 数字键按下 { if(op==0) // 如果操作符为0,表示正在输入第一个操作数 { num1=num1*10+P1; // 将输入的数字累加到num1 display(num1); // 显示num1 delay(10); // 延时去抖 while(P1!=0xff); // 等待按键释放 } else // 否则表示正在输入第二个操作数 { num2=num2*10+P1; // 将输入的数字累加到num2 display(num2); // 显示num2 delay(10); // 延时去抖 while(P1!=0xff); // 等待按键释放 } } } } ``` 这个程序实现了简单的加减乘除计算,同时也有清零和确认功能。在程序,通过检测按键的状态来进行相应的操作。同时,也使用了延时函数和数码管显示函数来实现计算器的基本功能。 在Proteus仿真,可以使用51单片机模拟器来运行这个程序。将程序烧录到单片机,然后将数码管和按键连接到相应的引脚上即可。在仿真,可以通过按下按键来模拟输入数字和操作符,然后观察数码管的显示结果来验证计算器的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值