简单计算器(51单片机程序)

合集下载

51单片机简易计算器

51单片机简易计算器

P3=0xf7;
0x7b:
temp=P3; temp=temp&0xf0; if(temp!=0xf0) {
delay(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) {
temp=P3; switch(temp) {
case 0xe7:
case 0xd7:
//5
case 0xbd:num1=10*num1+3;num=num1;break;
//6
case 0x7d:// -
num2=num1;num1=0;
flag=2;break;
} while(temp!=0xf0) { temp=P3; temp=temp&0xf0; }
}
}
P3=0xfb; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delay(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb:
break;
num1=10*num1+4; num=num1;
case 0xdb: break;
num1=10*num1+5; num=num1;
case 0xbb: break;
num1=10*num1+6; num=num1;
case // *
num2=num1; num1=0;
flag=3; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } }

基于51单片机的简易计算器

基于51单片机的简易计算器

基于51单片机的简易计算器简介用51做的一个建议计算器,能计算7位数*7位数,小数点保留三位,其他不多说,上图和程序,由于时间关系,程序没完全优化,解决了按一次计算符号后再按符号键无效的问题。

1.硬件电路单片机部分+矩阵键盘+1602显示图3-1所示为简易计算器的电路原理图。

P3口用于键盘输入,接4*4矩阵键盘,键值与键盘的对应表如表----所示,p0口和p2口用于显示,p2口用于显示数值的高位,po口用于显示数值的低位。

图3-1 简易计算器电路原理图PCB键值与功能对应表键值0 1 2 3 4 5 6 7 8 9 + - ×/ = ON/C功能0 1 2 3 4 5 6 7 8 9 + - ×÷= 清零说明矩阵键盘有16个按键,满足对简易计算器的计算实现,显示部分采用LCD1602,第一行显示计算的数值符号,第二行显示计算结果。

最大能计算7位数*7位数的值,可以计算负数,小数点结果保留有三位,在每次按下计算符号后,接着只能按下数字,再按下符号键无效,也就是每次计算只能按一个计算符号,如输入错误需按N清零键,或者复位单片机。

2 .计算器的软件设计#include<reg52.h>#include<intrins.h>#define uchar unsigned charsbit lcden=P2^2;sbit lcdrs=P2^0;sbit lcdrw=P2^1;sbit lcdbf=P0^7;uchar temp,key,i,j,flag,fh,k;long a,b,c;uchar code table[]={1,2,3,0,4,5,6,0,7,8,9,0,0,0,0,0};uchar code table2[]="123+456-789*000/";void delay(uchar ms){uchar x,y;for(x=ms;x>0;x--)for(y=110;y>0;y--);}/*-------------对LCD1602的操作-----------*/bit busy(void)//判断忙碌{bit res;lcdrs=0;lcdrw=1;lcden=1;_nop_();_nop_();res=lcdbf;lcden=0;return res;}void write_inst (uchar cmd)//写命令{while(busy()==1); //忙碌就等待lcdrs=0;lcdrw=0;lcden=0;_nop_();_nop_();P0=cmd;_nop_();_nop_();lcden=1;_nop_();_nop_();lcden=0;}void write_com(uchar com)//写地址{write_inst(com|0x80);}void write_date(uchar dat) //写数据{while(busy()==1);lcdrs=1;lcdrw=0;lcden=0;P0=dat;_nop_();_nop_();lcden=1;_nop_();_nop_();lcden=0;}void init() //初始化{lcden=1;write_inst(0x38);//显示8位2行delay(5);write_inst(0x0c);//显示开,光标关,不闪烁delay(5);write_inst(0x06);//增量方式不位移delay(5);write_inst(0x80);//检测忙碌信号delay(5);write_inst(0x01);//delay(5);}/*------------键盘扫描-----------*/void keyscan()//键盘扫描{P3=0xfe;if(P3!=0xfe){delay(20);if(P3!=0xfe){temp=P3&0xf0;switch(temp){case 0xe0:key=0;break;case 0xd0:key=1;break;case 0xb0:key=2;break;case 0x70:key=3;break;}}while(P3!=0xfe);if(key==0||key==1||key==2){if(j!=0)write_inst(0x01);j=0;}if(flag==0){a=a*10+table[key];}if(flag==1){b=b*10+table[key];}write_date(table2[key]);}else{if(k==0){flag=1;k=1;fh=1;write_date(table2[key]);}}P3=0xfd;if(P3!=0xfd){delay(20);if(P3!=0xfd){temp=P3&0xf0;switch(temp){case 0xe0:key=4;break;case 0xd0:key=5;break;case 0xb0:key=6;break;case 0x70:key=7;break;}}while(P3!=0xfd);if(key==4||key==5||key==6){if(j!=0){write_inst(0x01);j=0;}if(flag==0){a=a*10+table[key];}if(flag==1){b=b*10+table[key];}write_date(table2[key]); }else{if(k==0){flag=1;k=1;fh=2;write_date(table2[key]);}}}P3=0xfb;if(P3!=0xfb){delay(20);if(P3!=0xfb){temp=P3&0xf0;switch(temp){case 0xe0:key=8;break;case 0xd0:key=9;break;case 0xb0:key=10;break;case 0x70:key=11;break;}}while(P3!=0xfb);if(key==8||key==9||key==10){if(j!=0){write_inst(0x01);j=0;}if(flag==0){a=a*10+table[key];}if(flag==1){b=b*10+table[key];}write_date(table2[key]); }else{if(k==0){flag=1;k=1;fh=3;write_date(table2[key]);}}}P3=0xf7;if(P3!=0xf7){delay(20);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:key=12;break;case 0xd0:key=13;break;case 0xb0:key=14;break;case 0x70:key=15;break;}}while(P3!=0xf7);switch(key){case 12:{write_inst(0x01);a=0;b=0;flag=0;fh=0;j=0;k=0;} break;case 13:{if(flag==0){a=a*10;write_date(0x30);P1=0;}else if(flag==1){b=b*10;write_date(0x30);}} break;case 14:{j=1;if(fh==1){write_com(0x4f);write_inst(0x04);c=a+b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fh=0;k=0; }else if(fh==2){write_com(0x4f);write_inst(0x04);if((a-b)>0)c=a-b;elsec=b-a;if(c==0)write_date(0x30+0);while(c!=0){write_date(0x30+c%10);c=c/10;}if((a-b)*(-1)>0)write_date(0x2d);write_date(0x3d);a=0;b=0;flag=0;fh=0;k=0;}else if(fh==3){write_com(0x4f);write_inst(0x04);c=a*b;if(c==0)write_date(0x30+0);while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fh=0;k=0;}else if(fh==4){write_com(0x4f);write_inst(0x04);i=0;c=(long)(((float)a/b)*1000); //计算c的数据if(c==0)write_date(0x30+0);while(c!=0){write_date(0x30+c%10);c=c/10;i++;if(i==3)write_date(0x2e); //写数据}if((a/b)<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fh=0;k=0;}} break;case 15:{if(k==0){write_date(table2[key]);flag=1;k=1;fh=4;}} break;}}}void main(){init();i=0;j=0;a=0;b=0;c=0;k=0;flag=0;fh=0;while(1){keyscan();}}3.本设计的操作1.软件概述Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。

51单片机计算器程序

51单片机计算器程序

#include <reg51.h>#include <intrins.h>unsigned char data digit;unsigned char data index;unsigned char data buf[16];unsigned char code table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};unsigned int temp_dat;unsigned long int temp1,temp2,temp;unsigned int flag,flag1,key_times,key_flag,key_temp;unsigned char key_scan();void delay(void);void key_proc();void sys_init();void dis_result();void dis_init();void result_proc();void start_proc();void dat_proc(unsigned int key_dat);void char_proc(unsigned char i);void delayms(unsigned char ms);void main(){sys_init();while(1){key_proc();dis_result();}}void sys_init(){P0=0xff;P2=0x00;TMOD=0x01;TH0=0xfc;TL0=0x17;digit=0x00;index=0;temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;key_temp=0;dis_init();IE=0x82;TR0=1;}void dis_init(){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[10];}void dis_result(){if((temp<=4294967295)&&(temp>999999999)) {buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[temp/1000000000];buf[7]=table[(temp%1000000000)/100000000];buf[8]=table[((temp%1000000000)%100000000)/10000000];buf[9]=table[(((temp%1000000000)%100000000)%10000000)/1000000];buf[10]=table[((((temp%1000000000)%100000000)%10000000)%1000000)/100000];buf[11]=table[(((((temp%1000000000)%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000) /1000];buf[13]=table[(((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000 )%1000)/100];buf[14]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)/10];buf[15]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)%10];}if((temp<=999999999)&&(temp>99999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[temp/100000000];buf[8]=table[(temp%100000000)/10000000];buf[9]=table[((temp%100000000)%10000000)/1000000];buf[10]=table[(((temp%100000000)%10000000)%1000000)/100000];buf[11]=table[((((temp%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[(((((temp%100000000)%10000000)%1000000)%100000)%10000)/1000]; buf[13]=table[((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) /10];buf[15]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) %10];}if((temp<=99999999)&&(temp>9999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[temp/10000000];buf[9]=table[(temp%10000000)/1000000];buf[10]=table[((temp%10000000)%1000000)/100000];buf[11]=table[(((temp%10000000)%1000000)%100000)/10000];buf[12]=table[((((temp%10000000)%1000000)%100000)%10000)/1000];buf[13]=table[(((((temp%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=9999999)&&(temp>999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[temp/1000000];buf[10]=table[(temp%1000000)/100000];buf[11]=table[((temp%1000000)%100000)/10000];buf[12]=table[(((temp%1000000)%100000)%10000)/1000];buf[13]=table[((((temp%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((temp%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[(((((temp%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=999999)&&(temp>99999)){buf[0]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[temp/100000];buf[11]=table[(temp%100000)/10000];buf[12]=table[((temp%100000)%10000)/1000];buf[13]=table[(((temp%100000)%10000)%1000)/100];buf[14]=table[((((temp%100000)%10000)%1000)%100)/10];buf[15]=table[((((temp%100000)%10000)%1000)%100)%10]; }if((temp<=99999)&&(temp>9999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[temp/10000];buf[12]=table[(temp%10000)/1000];buf[13]=table[((temp%10000)%1000)/100];buf[14]=table[(((temp%10000)%1000)%100)/10];buf[15]=table[(((temp%10000)%1000)%100)%10];}else if((temp<=9999)&&(temp>999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[temp/1000];buf[13]=table[(temp%1000)/100];buf[14]=table[((temp%1000)%100)/10];buf[15]=table[((temp%1000)%100)%10]; }else if((temp<=999)&&(temp>99)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[temp/100];buf[14]=table[(temp%100)/10];buf[15]=table[(temp%100)%10];}else if((temp<=99)&&(temp>9)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[13]=table[10];buf[14]=table[temp/10];buf[15]=table[temp%10];}else if(temp<=9){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[temp];}}unsigned char key_scan(){unsigned char code_h,code_l;P1=0xf0;if((P1&0xf0)!=0xf0){delayms(2);if((P1&0xf0)!=0xf0) //两次判断,确认有键按下{code_h=0xfe; //低四位为行地址,对每一行进行扫描,即将每一行依次赋值0while((code_h&0x10)!=0x00){P1=code_h;if((P1&0xf0)!=0xf0){code_l=(P1&0xf0|0x0f);return((~code_h)+(~code_l)); //取反之后,高四位与低四位都只有一个1,相加不会进位}elsecode_h=((code_h<<1)|0x01); //依次进行扫描}}}return(0);}void key_proc(){unsigned char key_value;key_value=key_scan();switch(key_value){case 0x18: dat_proc(7);break; //7case 0x28: dat_proc(4);break; //4case 0x48: dat_proc(1);break; //1case 0x14: dat_proc(8);break; //8case 0x24: dat_proc(5);break; //5case 0x44: dat_proc(2);break; //2case 0x84: dat_proc(0);break; //0case 0x12: dat_proc(9);break; //9case 0x22: dat_proc(6);break; //6case 0x42: dat_proc(3);break; //3case 0x82: result_proc();break; //=case 0x11: char_proc(4);break; ///case 0x21: char_proc(3);break; //*case 0x41: char_proc(2);break; //-case 0x81: char_proc(1);break; //+case 0x88: start_proc();break; //ondefault :break;}}void dat_proc(unsigned int key_dat){if(key_times==0)temp=key_dat;else{if(flag==0)temp=(temp1*10+key_dat);else if(flag==1)temp=(temp2*10+key_dat);}if(flag==0)temp1=temp;else if(flag==1)temp2=temp;delayms(200);key_times++;}void char_proc(unsigned char i){key_times=0;key_flag=i;if(temp==0)flag=0;else{flag=1;}}void result_proc(){unsigned char flag_value;flag_value=key_flag;switch(flag_value){case 1: temp=(temp1+temp2);break;case 2: temp=(temp1-temp2);break;case 3: temp=(temp1*temp2);break;case 4: temp=(temp1/temp2);break;}key_times=0;flag=0;}void start_proc(){temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;}void time0() interrupt 1 using 2 {TH0=0xfc;TL0=0x17;P2=0x00;P0=buf[index];P2=digit;digit=digit++;index++;index&=0x0f;}void delayms(unsigned char ms) {unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}D0D1D2D3D4D5D6D7P3.1Q1CSDAQ2INT1Q3LCDENQ4WRQ6RDQ7Q0Q5Q4Q7Q5Q6Q 3Q 0Q 1Q 2D 0D 7D 6D 5D 4D 3D 2D 1W 0W 1W 2W 3W 4W 5W 6W 7D 0D 1D 2D 3D 4D 5D 6D 7W 8W 10W 11W 12W 13W 14W 15W 9W0W1W2W3W4W5W6W7W8W9W10W11W12W13W14W15XTAL218XTAL119ALE 30EA31PSEN 29RST9P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.0/T21P1.1/T2EX 2P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD17P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U3AT89C52234567891RP1RESPACK-812365489=7+CONABCD1243A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U174HC138A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U274HC138U4NOTU5NOTU6NOTU7NOTU8NOTU9NOTU10NOTU11NOTU12NOTU13NOTU14NOTU15NOTU16NOTU17NOTU19NOTU20NOTU22NOT。

51单片机实现计算器程序

51单片机实现计算器程序

#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^2;//数据和命令端sbit LCD_EN=P2^0;//使能端sbit LCD_RW=P2^1;sbit CS1=P2^4;sbit CS2=P2^3;uint keytime,keyno[10];uint result,date1,date2,w_date1,w_date2;uint KeyNO1,opercha;uint date10n;uint date10n_d[16];uchar code hz[]={/*-- 文字: 数--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x92,0x54,0x38,0xFF,0x38,0x54,0x52,0x80,0xF0,0x1F,0x12,0x10,0xF0,0x10,0x00,0x42,0x42,0x2A,0x2E,0x13,0x1A,0x26,0x02,0x40,0x20,0x13,0x0C,0x33,0x60,0x20,0x00,/*-- 文字: 据--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x08,0x08,0xFF,0x88,0x40,0xFE,0x92,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,0x02,0x42,0x81,0x7F,0x40,0x30,0x0F,0xFC,0x44,0x44,0x47,0x44,0x44,0xFC,0x00,0x00,/*-- 文字: 结--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,/*-- 文字: 果--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x3E,0x2A,0x2A,0x2A,0xFE,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x09,0x11,0x31,0x11,0x00};uchar code sz[]={0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0 0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, //2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02, //4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00, //5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00, //6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00, //7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00, //8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00, //90x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00, //: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00//.};/*******************************名称:delay()输入:延时数输出: 无功能:延时********************************/void delay(uint x){int y,z;for(y=x;y>0;y--)for (z=120;z>0;z--);}void write_c(uchar c) //写指令端{LCD_RW=0;LCD_RS=0;LCD_EN=1;P0=c;LCD_EN=0;delay(1);LCD_EN=1;}void write_d(uchar d)//写数据{LCD_RW=0;LCD_RS=1;LCD_EN=1;P0=d;LCD_EN=0;delay(1);LCD_EN=1;}void pianxuan(screen) //片选{switch(screen){case 0:CS1=0;CS2=0;break;case 1:CS1=1;CS2=0;break;case 2:CS1=0;CS2=1;break;case 3:CS1=1;CS2=1;break;}}void qinping(screen)//清屏,从第一行第一列开始{uint x,y; //页的设置位pianxuan(screen);//选择哪个清屏for(x=0xb8;x<0xc0;x++){write_c(x);//页初始值为0XB8到0xc0共八页write_c(0x40);//列的初始地址为0x40,共64列for(y=0;y<64;y++){write_d(0x00);//选择全部清屏}}}/*LCD显示汉字字库函数*/void lcd_display_hanzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*32;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*16)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<16;i++){write_d(hz[mun++]);}write_c(0x40+(lie*16));write_c(0xb8+(page*2)+1);for (i=0;i<16;i++){write_d(hz[mun++]);}}void lcd_display_shuzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*16;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*8)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<8;i++){write_d(sz[mun++]);}write_c(0x40+(lie*8));write_c(0xb8+(page*2)+1);for (i=0;i<8;i++){write_d(sz[mun++]);}}void LCD_init(){write_c(0x3f);// 显示开启write_c(0xc0); //显示起始行,从第一位开始,从0到63 write_c(0xb8);// 设置页得地址从0到7write_c(0x40); //设置列的地址,从第一位开始,从0到63 }/*******************************名称:GET_key()输入:无输出: 按键的相应数目功能:扫描按键********************************/uchar GET_key(){uchar Tmp,KeyNO;P1 = 0xf0;delay(1);Tmp = P1;switch(Tmp){case 0xe0: KeyNO = 3; break;case 0xd0: KeyNO = 2; break;case 0xb0: KeyNO = 1; break;case 0x70: KeyNO = 0;}P1 = 0x0f;delay(1);Tmp = P1;switch(Tmp){case 0x0e: KeyNO+= 12; break;case 0x0d: KeyNO+= 8; break;case 0x0b: KeyNO+= 4; break;case 0x07: KeyNO+= 0; break;default: break;}return(KeyNO);}void write_key(){uchar i,j,m,n;m = 7;n = 7;KeyNO1 = GET_key();if (KeyNO1>=0 && KeyNO1<=9){keytime++;}if (KeyNO1>=10 && KeyNO1<=13){/* keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date1=keyno[keytime];else{for (k=0; k<keytime-j; k++){w_date1=keyno[keytime--]*10;}}date1=date1+w_date1;}*/keytime = 0;opercha = KeyNO1;}if (!(opercha>=10 && opercha<=13)){date1=0;if ((keytime-1) < 10 ){keyno[keytime-1] = KeyNO1;if (keytime-1>=0 && keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0){w_date1=keyno[i-1];}else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,0,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date1=date1+w_date1;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date1=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}}}if ( (opercha>=10 && opercha<=13) && (KeyNO1 != 14) ) {date2=0;if ((keytime-1)<10 && (keytime-1)>=0){keyno[keytime-1] = KeyNO1;if (keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,1,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date2=date2+w_date2;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}}}/*if (KeyNO1 == 15){keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date2=keyno[keytime];else{for (i=0; i<keytime-j; i++){w_date2=keyno[keytime--]*10;}}date2=date2+w_date2;}} */if (opercha>=10 && opercha<=13){m=7;if (KeyNO1 == 14){switch(opercha){case 10:result=date1+date2;break;case 11:result=date1-date2;break;case 12:result=date1*date2;break;case 13:result=date1/date2;break;default:break;}for (i=1; ;i++){date10n=1;for (j=0; j<i-1; j++){date10n=date10n*10;}date10n_d[i-1]=(result / date10n) % 10;if (date10n*10>result){j=i;break;}}P3=result / date10n;for (i=0;i<j;i++){lcd_display_shuzi(1,2,m,date10n_d[i]);m--;}/* lcd_display_shuzi(1,2,7,result);P3 =opercha; */}}}void main(){keytime=0;date1=0;date2=0;w_date1=0;w_date2=0;result=0;opercha=0;KeyNO1=16;date10n=1;LCD_init();qinping(0);lcd_display_hanzi(2,0,0,0); //LCD显示汉字"数" //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数lcd_display_hanzi(2,0,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,0,4,1); //LCD显示数字"1"lcd_display_shuzi(2,0,5,10);//LCD显示符号":"lcd_display_hanzi(2,1,0,0); //LCD显示汉字"数"lcd_display_hanzi(2,1,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,1,4,2); //LCD显示数字"2"lcd_display_shuzi(2,1,5,10);//LCD显示符号":"lcd_display_hanzi(2,2,0,2); //LCD显示汉字"结"lcd_display_hanzi(2,2,1,3); //LCD显示汉字"果"lcd_display_shuzi(2,2,4,10);//LCD显示符号":"while(1){P1 = 0x0f;if (P1 != 0x0f){delay(1);if (P1 != 0x0f){write_key();while (P1 != 0x0f);}}}}。

怎样用51单片机做计算器啊?

怎样用51单片机做计算器啊?

怎样用51单片机做计算器啊?原理图51单片机简易计算器程序:#include <reg51.h>#include <math.h>#define uchar() unsigned char()#define uint unsigned int//---------定义引脚--------------------bit clr=0;bit ok=0;bit xiaoshu=0;bit jiego=0;bit first_1=1;bit first_2=1;sbit dout = P3^2;sbit load = P2^0;sbit din = P2^1;sbit dclk = P2^2;sbit beer=P0^1;sbit LCD1602_RS=P2^3;sbit LCD1602_RW=P2^4;sbit LCD1602_E=P2^5;//---------定义变量-------------------- uchar() ch451_key=0xff;uchar yun_sign;uchar xiabiao=0;uchar tab[32];uchar tab1[]={"welcome to use!"};uchar tab2[]={" make by JunRu!"};uchar tab3[]={"ERR0R"};float opr_1=0,opr_temp=0,end=0,a;//---------声明函数--------------------void ch451_init(void); //CH451初始化void ch451_write(uint command);//写命令或数据到ch451uchar ch451_read()(void); //读按键值uchar get_char(void);void LCD_init(void);//初始化;void delay(unsigned int k);//延时程序void LCD_inter_command(unsigned char command);//写入控制字void LCD_inter_dat(unsigned char dat);//写入要显示的数据void set_xy(unsigned char x,unsigned char y);//找地址void write(unsigned char date);//写入字符void lcdbusy();//查忙时void display()(void);void spec(void);void get_end(void);void hun_he(uchar n);//-------- 主函数----------------------void main(){uchar i;LCD_init();//LCD初始化;ch451_init();//CH451初始化EA = 1;//打开中断LCD_inter_command(0x01);//清屏for(i=0;i<=14;i++){LCD_inter_dat(tab1[i]);beer=0;delay(4000);//延时beer=1;}LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=14;i++){LCD_inter_dat(tab2[i]);beer=0;delay(4000);//延时beer=1;}delay(0xffff);delay(0xffff);LCD_inter_command(0x01);while(1){if(ok){display()();ok=0;clr=1;}}}//----------子函数--------------------void hun_he(uchar n){int j;switch(n){case '+':opr_temp=opr_temp+opr_1;break;case '-':opr_temp=opr_temp-opr_1;break;case '*':opr_temp=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{opr_temp=opr_temp/opr_1;}break;}default:break;}}void ch451_init(void)//CH451初始化{EX0 = 1;din = 0;din = 1;ch451_write(0x403); //开显示ch451_write(0x580); //BCD译码方式}void ch451_write(uint command)//写命令或数据到ch451 { uchar i;load = 0;for(i=0;i<12;i++){din = command&1;dclk = 0;command>>=1;dclk = 1;}load = 1;EX0 = 1;}uchar ch451_read()(void)//读按键值{ uchar key=0x07;uchar i;EX0=0;load = 0;for(i=0;i<4;i++) //将0111读入{din = key &1;dclk = 0;key>>=1;dclk =1;}load = 1;key = 0;for(i=0;i<7;i++) //从CH451读出按键值{key<<=1;key|= dout;dclk =1;}EX0 =1;return key;}void EX0_ISR(void)interrupt 0 //中断程序{uchar temp;ch451_key=ch451_read()(); //将读出的按键值赋给变量spec();if(clr) {LCD_inter_command(0x01);clr=0;}temp=get_char();if(temp){tab[xiabiao++]=temp; LCD_inter_dat(temp);}if(xiabiao>=16)LCD_inter_command(0xc0);//若大于16,则从第2行开始显示if(ok) get_end();beer=0;delay(3000);beer=1;}uchar get_char(void){uchar dis=0;uint temp=0,temp1=0;switch(ch451_key){case 0x40:dis='1';break;case 0x41:dis='2';break;case 0x42:dis='3';break;case 0x48:dis='4';break;case 0x49:dis='5';break;case 0x4A:dis='6';break;case 0x50:dis='7';break;case 0x51:dis='8';break;case 0x52:dis='9';break;case 0x58:dis='0';break;case 0x43:dis='+';break;case 0x4B:dis='-';break;case 0x53:dis='x';break;case 0x5B:dis='/';break;case 0x44:dis='!';break;case 0x5A:dis='=';ok=1; //遇到“=”,开始运算break;case 0x59:dis='.';break; //小数点case 0x5C: //删除键LCD_inter_command(0x01);xiabiao=0;break;default: break;}return dis;}void spec(void) //特殊功能键{switch(ch451_key){case 0x4C:LCD_inter_command(0x10);{if(xiabiao>0)xiabiao-=1;}break; //左移case 0x54:LCD_inter_command(0x14);{xiabiao+=1;}break; //右移default:break;}}void delay(unsigned int k)//延时程序{while (k--);}void LCD_inter_command(unsigned char command)//写入控制字{delay(5000);LCD1602_RS=0;LCD1602_RW=0;LCD1602_E=1;P1=command;LCD1602_E=0;lcdbusy();}void LCD_init(void)//初始化;{delay(5000);LCD_inter_command(0x01);//清屏delay(5000);LCD_inter_command(0x38);//设置为8位的数据接口,两行显示,5、7点字符delay(5000);LCD_inter_command(0x0E);//显示打开,光标开并闪烁delay(5000);}void LCD_inter_dat(unsigned char dat)//写入要显示的数据{delay(5000);LCD1602_RS=1;LCD1602_RW=0;LCD1602_E=1;P1=dat;LCD1602_E=0;lcdbusy();}void lcdbusy()//查忙{P1=0xFF;LCD1602_RS=0;LCD1602_RW=1;LCD1602_E=1;while((P1&0x80)==1);}void display()(void) //转化在LCD上显示计算结果{int temp=end; //浮点数int i;uint xiao_temp;uint xx; //浮点数的整数部分if (end>-32769&&end<32768){xx=fabs(end);xiao_temp=(fabs(end)-xx)*1000;//取出浮点数的小数部分LCD_inter_command(0xc0);if(end<0) LCD_inter_dat('-');beer=0;delay(4000); beer=1;//判断是否为负数,若是则显示负号if(xx>9999) LCD_inter_dat((xx/10000)%10+'0'); beer=0;delay (4000);beer=1;if(xx>999) LCD_inter_dat((xx/1000)%10+'0');beer=0;delay(40 00);beer=1; //在LCD上显示千位的数if(xx>99)LCD_inter_dat((xx/100)%10+'0'); beer=0;delay(400 0);beer=1;//百位if(xx>9)LCD_inter_dat((xx/10)%10+'0');beer=0;delay(4000); b eer=1;//十位LCD_inter_dat(xx%10+'0');beer=0;delay(4000); beer=1;//个位if(xiao_temp!=0) //显示小数部分{LCD_inter_dat('.');beer=0;delay(4000);beer=1;LCD_inter_dat((xiao_temp/100)%10+'0');beer=0;delay(4000); beer=1;LCD_inter_dat((xiao_temp/10)%10+'0');beer=0;delay(4000);b eer=1;LCD_inter_dat(xiao_temp%10+'0');beer=0;delay(4000);beer= 1;}}else {LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=4;i++){ LCD_inter_dat(tab3[i]);beer=0;delay(4000);//延时beer=1;}}}void get_end(void)//计算子程序{ float xiaoshu=1;uchar fu_flag=0;uchar xiao_flag=0;uchar lianji_sign;uchar i=0;uchar j;uchar n;//正负标记符while(i<=xiabiao){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1*=10;opr_1+=tab[i++]-0x30;n='+';}switch(tab[i]){case '.': xiao_flag=1;break;//遇到小数点跳到“if(xiao_flag)”里case '!': fu_flag=1;break;case '+': xiaoshu=1;yun_sign='+';if(opr_temp==0){end=opr _temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='+'; br eak;case '-': xiaoshu=1;yun_sign='-';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign );opr_1=0;lianji_sign='-'; break;case 'x': xiaoshu=1;yun_sign='x';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='*';brea k;case '/': xiaoshu=1;yun_sign='/';if(opr_temp==0){end=opr_ temp=opr_1;}else hun_he(lianji_sign);a=opr_1;opr_1=0;lianji_sig n='/';break;case '=':switch(yun_sign)//进行运算{case '+':end=opr_temp+opr_1;break;case '-':end=opr_temp-opr_1;break;case 'x':end=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{end=opr_temp/opr_1;}break;}default:break;}ok=1;//开始进行显示,标志位置1xiabiao=0;//小数的标志位清零break;default:break;}i++;if(xiao_flag)//表示小数{while(tab[i]<=0x39&&tab[i]>=0x30){xiaoshu*=0.1;switch(n){case '+': opr_1=opr_1+(tab[i++]-0x30)*xiaoshu;break; case '-': opr_1=opr_1-(tab[i++]-0x30)*xiaoshu; break ; default:break; }xiao_flag=0;}}if(fu_flag){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1=-opr_1*10;opr_1=-(opr_1+(tab[i++]-0x30));n='-';fu_flag=0;}}}opr_1=0;opr_temp=0; xiabiao=0; xiaoshu=1;下方为原理图:。

基于51单片机的计算器(附Proteus仿真图且程序有详细注释)

基于51单片机的计算器(附Proteus仿真图且程序有详细注释)
case 0x7b: key=11;flag1=1;display(7,0);break;
}
while(temp!=0xf0)
{
temp=P1;temp=temp&0xf0;
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
x--;
delay(3);
}
}
}
else if ((flag1==1)&&(flag2==1))
{
for(i=7;i>=px3;i--)
{
display(i,RESUIT[i]);
delay(3);
}
}
}
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xee: key=0;flag=1;break;
case 0xde: key=1;flag=1;break;
case 0xbe: key=2;flag=1;break;
{
k=k*10;
}
x1=x1+k;
}
x1=x1+DATA1[px1-1];
for(i=0;i<(px2-1);i++) //把第二个数组中的数处理成十进制数
{
k=DATA2[i];
for(j=0;j<(px2-i-1);j++)

做一个计算器_用51单片机做一个简单的计算器小程序

做一个计算器_用51单片机做一个简单的计算器小程序

做⼀个计算器_⽤51单⽚机做⼀个简单的计算器⼩程序⼀:硬件仿真图分别为8位数码管和4位数码管注意:本仿真案例有偿提供,请点击⽂章最下⽅的阅读原⽂,查看仿真图和程序下载地址。

本仿真仅供参考,如有需要修改电路和程序,请联系管理员有偿修改。

当然,如果你动⼿能⼒强,完全可以按照本⽂提供的电路图和程序源码⾃⾏搭建。

硬件部分⽐较简单,当键盘按键按下时它的那⼀⾏、那⼀列的端⼝为低电平。

因此,只要扫描⾏、列端⼝是否都为低电平就可以确定是哪个键被按下。

本计算器是以80C51单⽚机为核⼼构成的简易计算器系统。

该系统通过单⽚机控制,实现对4*4键盘扫描进⾏实时的按键检测,并把检测数据和计算结果存储下来,显⽰在LED数码管上,并可实现清零。

整个系统主要可分为四个主要功能模块:功能模块⼀:实时键盘扫描;功能模块四:清零整个计算器系统的⼯作过程为:⾸先初始化参数,送LED低位显⽰“0”,功能键位不显⽰。

然后扫描键盘看是否有键输⼊,若有,读取键码。

判断键码是数字键、清零键还是“+” 、“—” 、“*” “/” ,是数值键则送LED显⽰并保存数值,是清零键则做清零处理,是功能键则⼜判断是“=”、清零、还是运算键,若是“=”则计算最后结果并送LED显⽰,若是运算键则保存相对运算程序的⾸地址,若是清零键则跳转回初始化阶段使所有值清零。

⼆、主程序流程图程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。

将操作数分别转化为字符串存储,操作符存储为字符形式。

然后调⽤compute()函数进⾏计算并返回结果。

具体程序及看注释还有流程图。

三:键盘扫描程序流程图四:显⽰程序流程图五:程序源码#include#include /* isdigit()函数 */#include /* atoi()函数 */#define uchar unsigned char#define uint unsigned intuchar operand1[9], operand2[9]; /* 操作数 */uchar operator; /* 操作符 */void delay(uint);uchar keyscan();void disp(void);void buf(uint value);uint compute(uint va1,uint va2,uchar optor);uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; /* 字符码表 */uchar dbuf[8] = {10,10,10,10,10,10,10,10}; /* 显⽰缓存 */ /* 延时函数 */void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*******************************************键盘扫描程序将按键转化为字符并作为输出'$','#'分别表⽰清零键和没有键按下*******************************************/uchar keyscan(){uchar skey; /* 按键值标记变量 *//***********************扫描键盘第1⾏while((P1 & 0xf0) != 0xf0) /* 有按键按下 */ {delay(3); /* 去抖动延时 */while((P1 & 0xf0) != 0xf0) /* 仍有键按下 */{switch(P1) /* 识别按键并赋值 */{case 0xee: skey = '7'; break;case 0xde: skey = '8'; break;case 0xbe: skey = '9'; break;case 0x7e: skey = '/'; break;default: skey = '#';}while((P1 & 0xf0) != 0xf0) /* 等待按键松开 */;}}/***********************扫描键盘第2⾏************************/P1 = 0xfd;while((P1 & 0xf0) != 0xf0){delay(3);while((P1 & 0xf0) != 0xf0){switch(P1){case 0xed: skey = '4'; break;case 0xdd: skey = '5'; break;case 0xbd: skey = '6'; break;case 0x7d: skey = '*'; break;while((P1 & 0xf0) != 0xf0) ;}}/***********************扫描键盘第3⾏************************/P1 = 0xfb;while((P1 & 0xf0) != 0xf0) {delay(3);while((P1 & 0xf0) != 0xf0) {switch(P1){case 0xeb: skey = '1'; break; case 0xdb: skey = '2'; break; case 0xbb: skey = '3'; break; case 0x7b: skey = '-'; break; default: skey = '#';}while((P1 & 0xf0) != 0xf0) ;}}/***********************扫描键盘第4⾏************************/P1 = 0xf7;while((P1 & 0xf0) != 0xf0) {delay(3);{case 0xe7: skey = '$'; break;case 0xd7: skey = '0'; break;case 0xb7: skey = '='; break;case 0x77: skey = '+'; break;default: skey = '#';}while((P1 & 0xf0) != 0xf0);}}return skey;}void main(){uint value1, value2, value; /* 数值1,数值2,结果 */uchar ckey, cut1 = 0, cut2 = 0; /* ckey键盘输⼊字符 */ uchar operator; /* 运算符 */uchar i, bool = 0;init: /* goto语句定位标签 */buf(0); /* 初始化 */disp();value = 0;cut1 = cut2 = 0;bool = 0;for(i = 0;i < 9;i++){operand1[i] = '\0';operand2[i] = '\0';} /* 初始化 */while(1){ /* isdigit函数,字符是阿拉伯数字返回⾮0值,否则返回0 */if(isdigit(ckey)){switch(bool){case 0:operand1[cut1] = ckey;operand1[cut1+1] = '\0';value1 = atoi(operand1); /* atoi函数,将字符串转化为,int整数 */ cut1++;buf(value1);disp();break;case 1:operand2[cut2] = ckey;operand2[cut2+1] = '\0';value2 = atoi(operand2);cut2++;buf(value2);disp();break;default: break;}}else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/'){bool = 1;operator = ckey;buf(0);dbuf[7] = 10;disp();{value = compute(value1,value2,operator);buf(value);disp();while(1) /* 计算结束等待清零键按下 */ {ckey = keyscan();if(ckey == '$') /* 如果有清零键按下跳转到开始 */ goto init;else{buf(value);disp();}}}else if(ckey == '$'){ goto init;}}disp();}}/******************************************运算函数输⼊:操作数和操作符输出:计算结果*******************************************/uint compute(uint va1,uint va2,uchar optor){uint value;switch(optor){case '*' : value = va1*va2; break; case '/' : value = va1/va2; break; default : break;}return value;}/******************************************* 更新显⽰缓存输⼊:⽆符号整数输出:将输⼊送⼊显⽰缓存*******************************************/ void buf(uint val){uchar i;if(val == 0){dbuf[7] = 0;i = 6;}elsefor(i = 7; val > 0; i--){dbuf[i] = val % 10;val /= 10;}for( ; i > 0; i--)dbuf[i] = 10;}/******************************************* 显⽰函数*******************************************/ void disp(void)bsel=0x01;for(n=0;n<8;n++) {P2=bsel;P0=table[dbuf[n]]; bsel=_crol_(bsel,1); delay(3);P0=0xff;}}。

51单片机简易计算器

51单片机简易计算器

***************51单片机简易计算器************按键介绍:| 7 | 8 | 9 | + |-------------| 4 | 5 | 6 | -|-------------| 1 | 2 | 3 | * |-------------| 0 | = | C | / |操作说明:按下第一个数(0—9)后再按运算符(+ - * /),最后按=显示结果,按C 可以清除全屏加最大:9999+9999=19998乘最大:9999*9999=99980001除:1/9=0.1111保留小数点后四位#include <REGX52.H>#define uint unsigned int#define uchar unsigned char/******************LCD1602**********************/#define LCD_RS P2_4//定义LCD_RS端口#define LCD_RW P2_5//定义LCD_RW端口#define LCD_EN P2_6//定义LCD_EN端口#define LCD_DA P0//定义LCD_DA端口(数据端)#define KEY P3//定义矩阵按键为P3口#define Speak P2_3//定义蜂鸣器端口#define LED P2_2//定义指示灯#define KEY_1P2_0//定义按键为P1.7口(开/关蜂鸣器、LED灯) #define LED1P1//定义流水指示灯/**************定义显示数据数组*************/uchar code table[]= {" "};/****************定义动画数组***************/uchar code table1[]={" Welcome to "};uchar code table2[]={" 51 MCU Counter "};/*************定义流水灯显示数组************/uchar code table3[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//从低位往高位(流水)uchar code table4[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//从高位往低位(流水)uchar code table5[]={0x7e,0xbd,0xdb,0xe7};//从两边往中间(流水)uchar code table6[]={0xe7,0xdb,0xbd,0x7e};//从中间往两边(流水)/***************定义运算数据***************/long int data_a=0;//第一个数long int data_b=0; //第二个数long int data_c=0;//计算结果uchar dispaly[10]; //显示缓冲uchar i,j;//定义i,juchar flag=1;//定义开/关蜂鸣器、LED灯标志位,初始化为1uchar n=1;//定义n为1(默认8位LED显示流水状态1)uchar k=0;//定义kuchar num=0;//定义时间基数初始值为0uchar key=0xff; //键值初始化uchar a=0;//第1个数可以按1-4次(在主函数中体现)uchar b=5; //第2个数可以按1-4次(在主函数中体现)uchar x=0; //定义x=0/***************延时函数*********************/void delay(uint time)//延时函数{uint i,j;for(i=time;i>0;i--)for(j=110;j>0;j--);}/***************蜂鸣器响延时函数************/void delay_fmq(uint time)//蜂鸣器响延时函数{uint x,y;for(x=time;x>0;x--)for(y=5;y>0;y--);}/************LED灯闪烁并且蜂鸣器响***********/void spk()//LED灯闪烁并且蜂鸣器响{LED=0;//LED亮for(j=0;j<100;j++)//利用for语句延时{Speak=0;//蜂鸣器为低电平delay_fmq(5);//延时Speak=1;//蜂鸣器为高电平delay_fmq(5);//延时}LED=1;//LED灭}/***************1602液晶写指令*****************/void write_com(uchar com) //1602液晶写指令(参照LCD1602时序图) {LCD_RS=0; //写指令LCD_RW=0;//写液晶LCD_DA=com; //写入指令comdelay(2); //延时LCD_EN=1; //使能1602delay(2); //延时LCD_EN=0;//使能1602}/****************1602液晶写数据***************/void write_date(uchar date) //1602液晶写数据(参照LCD1602时序图) {LCD_RS=1; //写数据LCD_RW=0; //写液晶LCD_DA=date; //写入数据datedelay(2);//延时LCD_EN=1; //使能1602delay(2); //延时LCD_EN=0;//使能1602}/****************指定x,y写入字符函数*********/void W_lcd(unsigned char x,unsigned char y,unsigned char Data){if(y==0)//如果y=0{write_com(0x80 + x);//第一行}else//否则y=1{write_com(0xc0 + x);//第二行}write_date(Data); //写入数据}/****************指定x,y写入字符串函数********/void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s){if(y==0)//如果y=0{write_com(0x80 + x);//第一行}else//否则y=1{write_com(0xC0 + x);//第二行}while(*s){write_date(*s);//写入数据s++;//s++}}/*****************初始化液晶******************/void LCD_init() //初始化液晶{write_com(0x38); //8 位总线,双行显示,5X7 的点阵字符write_com(0x0c); //开显示,无光标,光标不闪烁write_com(0x01); //清屏}/*****************开机动画********************/void cartoon()//开机动画{spk();//蜂鸣器响,LED亮write_com(0x80);//写指令准备显示第1行第1个for(i=0;i<16;i++)//for语句循环16次{write_date(table1[i]);//写数据" Welcome to "delay(100);//延时一下(为了数字、字母一个一个显示) }write_com(0xc0);//写指令准备显示第2行第1个for(i=0;i<16;i++)//for语句循环16次{write_date(table2[i]);//写数据" 51 MCU Counter "delay(100);//延时一下(为了数字、字母一个一个显示) }spk();//蜂鸣器响,LED亮delay(200);}/*************反转法键盘扫描******************/short keycheckdown()//反转法键盘扫描{short temp1,temp2,temp,a=0xff;KEY=0xf0;//输入行值(或列值)delay(20);//延时temp1=KEY;//读列值(或行值)KEY=0xff;delay(20);//延时KEY=0x0f;//输入列值(或行值)delay(20);//延时temp2=KEY;//读行值(或列值)KEY=0xff;temp=(temp1&0xf0)|(temp2&0xf);//将两次读入数据组合switch(temp)//通过读入数据组合判断按键位置{/************第一行按键7 8 9 + *********/case 0xee :a=7; //按键7if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xed :a=8; //按键8if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xeb :a=9; //按键9if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xe7 :a=0x0a;//按键+if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回/************第二行按键4 5 6 - *********/case 0xde :a=4; //按键4if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xdd :a=5; //按键5if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xdb :a=6; //按键6if(flag==1)//若flag为1,则蜂鸣器响,LED亮spk();}break; //返回case 0xd7 :a=0x0b;//按键-if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回/************第三行按键1 2 3 * *********/case 0xbe :a=1; //按键1if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xbd :a=2; //按键2if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xbb :a=3; //按键3if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xb7 :a=0x0c;//按键*if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();break; //返回/************第四行按键0 = C / *********/case 0x7e :a=0;//按键0if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x7d :a=0x0e;//按键=if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x7b :a=0x0f;//按键Cif(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x77 :a=0x0d;//按键/if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回default :a=0xff;//没有键按下}return a;//返回按键值}/******************显示数据a******************/ void display_a() //显示数据a{dispaly[3]=data_a%10000/1000; //千位dispaly[2]=data_a%1000/100; //百位dispaly[1]=data_a%100/10; //十位dispaly[0]=data_a%10; //个位write_com(0x80+0); //显示数据aif(data_a>999){write_date('0'+dispaly[3]);//显示千位}if(data_a>99){write_date('0'+dispaly[2]);//显示百位}if(data_a>9){write_date('0'+dispaly[1]); //显示十位}write_date('0'+dispaly[0]); //显示个位}/******************显示数据b******************/ void display_b() //显示数据b{write_com(0x80+7); //第一行dispaly[3]=data_b%10000/1000; //千位dispaly[2]=data_b%1000/100; //百位dispaly[1]=data_b%100/10; //十位dispaly[0]=data_b%10; //个位if(data_b>999){write_date('0'+dispaly[3]);//显示千位}if(data_b>99){write_date('0'+dispaly[2]); //显示百位}if(data_b>9){write_date('0'+dispaly[1]); //显示十位}write_date('0'+dispaly[0]); //显示个位}/******************计算结果*******************/void display_c(x){if(data_c<100000000&&data_c>-1)//溢出时显示错误{dispaly[8]=data_c%1000000000/100000000; //万万dispaly[7]=data_c%100000000/10000000; //千万dispaly[6]=data_c%10000000/1000000; //百万dispaly[5]=data_c%1000000/100000; //十万dispaly[4]=data_c%100000/10000; //万dispaly[3]=data_c%10000/1000; //千dispaly[2]=data_c%1000/100; //百dispaly[1]=data_c%100/10; //十dispaly[0]=data_c%10; //个write_com(0x80+0x40+7); //第二行if(x==4){if(data_c>99999999){write_date('0'+dispaly[8]);//显示万万}if(data_c>9999999){write_date('0'+dispaly[7]);//显示千万}if(data_c>999999){write_date('0'+dispaly[6]);//显示百万}if(data_c>99999){write_date('0'+dispaly[5]);//显示十万}write_date('0'+dispaly[4]); //万write_date('.');write_date('0'+dispaly[3]); //千write_date('0'+dispaly[2]); //百write_date('0'+dispaly[1]); //十write_date('0'+dispaly[0]); //个}else{if(data_c>99999999){write_date('0'+dispaly[8]);//显示万万}if(data_c>9999999){write_date('0'+dispaly[7]);//千万}if(data_c>999999){write_date('0'+dispaly[6]);//百万}if(data_c>99999){write_date('0'+dispaly[5]);//十万}if(data_c>9999){write_date('0'+dispaly[4]);//万}if(data_c>999){write_date('0'+dispaly[3]);//千}if(data_c>99){write_date('0'+dispaly[2]);//百}if(data_c>9){write_date('0'+dispaly[1]);//十}write_date('0'+dispaly[0]); //个}}else //溢出时显示错误{write_com(0x80+0x40+11); //第二行write_date('E'); //显示Ewrite_date('r'); //显示Rwrite_date('r');//显示Rwrite_date('o');//显示Owrite_date('r');//显示R}}/****************加减乘除运算*****************/void eql(uchar yunsuan)//加减乘除运算{switch(yunsuan)//功能键选择{case 1:data_c=data_a+data_b;//加法break; //返回case 2:if(data_a>=data_b)//若a>b{data_c=data_a-data_b;//减法}else//否则a<b{data_c=data_b-data_a;//减法W_lcd(5,1,'-');//带上负号}break; //返回case 3:data_c=(data_a*data_b);//乘法break;//返回case 4:if(data_b==0)//如果被除数为0{LCD_Write_String(1,1,"Error");//除法溢出时显示错误}else{data_c=(data_a*10000)/data_b;//除法}break;//返回case 0: break;//不做运算返回}}/****************定时器0初始化****************/void Time0_init()//定时器0初始化{TMOD=0x01;//定时器0为方式1TL0=(65536-50000)%256;TH0=(65536-50000)/256;//12M晶振定时时间50msET0=1;//开定时器0中断EA=1;//开总中断TR0=1;//开启定时器0}/****************开/关指示函数***************/void K_G_ZS()//开/关指示函数{if(KEY_1==0)//若按键按下{delay(20);//延时去抖if(KEY_1==0)//再次确认按键是否按下{flag=!flag;//flag取反}//flag=0关闭蜂鸣器响和LED亮。

基于51单片机的简易计算器c程序

基于51单片机的简易计算器c程序

/*...............菜鸟一枚,不好勿喷→_→............................【简易计算器的功能简介】【时间紧,先做个简易的吧,复杂的算法太难,没那么多时间写【现在也不太会→_→】,以后再研究→_→】此程序是完全基于开发板的,可在板子上直接测试【程序跑飞的概率比较大,还不太明白是哪的问题】可实现总数小于等于九位【long int】的数字的加减乘除运算【每次只能进行一项】,可清楚修改输入的数据,由于键盘等因素显示【4X4】,没有小数点键,故无法直接进行小数运算,进行除法运算时,小数点后最多可保留6位,第7位进行四舍五入。

显示器采用1602,输入或修改时开光标并闪烁,输入数据超出9位,有警告提示,加上运算符总的输入不超过15位【超过10输入逻辑已经错误】。

显示结果时关光标【重复按下时结果不变】,显示结果后,也可对输入端进行修改,按下等于键再次显示结果。

2015/1 qq:1036894850 */#include"reg52.h"#include"stdio.h"#define uchar unsigned charsbit rs=P2^4;//lcd的控制线口sbit rw=P2^5;sbit ep=P2^6;uchar ip[15];//存输入的数据,15位【理论上10位就够了】'$'记运算符'*'记为负号uchar sign;//存运算符int k=0,equ=0,sk=0,ksk=0,sg=0;void write_data(uchar dat); //给1602写数据void write_com(uchar com);void lcdinit();void delay(int z);void warn();void key_deal(uchar key);void sdeal(uchar i);void key_sub_deal();void key_equ_deal();void key_del_deal();uchar scankey();void main(){uchar key=0xff;lcdinit(); //1602初始化,结果输出位显示0,数据输入位光标闪烁。

基于51单片机的计算器设计程序代码(汇编)

基于51单片机的计算器设计程序代码(汇编)

DBUF EQU 30HTEMP EQU 40HYJ EQU 50H ;结果存放YJ1 EQU 51H ;中间结果存放GONG EQU 52H ;功能键存放ORG 00HSTART:MOV R3,#0 ;初始化显示为空MOV GONG,#0MOV 30H,#10HMOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HMLOOP:CALL DISP ;PAN调显示子程序WAIT:CALL TESTKEY ;判断有无按键JZ WAITCALL GETKEY ;读键INC R3 ;按键个数CJNE A,#0,NEXT1 ;判断是否数字键LJMP E1 ;转数字键处理NEXT1:CJNE A,#1,NEXT2LJMP E1NEXT2:CJNE A,#2,NEXT3LJMP E1NEXT3:CJNE A,#3,NEXT4LJMP E1NEXT4:CJNE A,#4,NEXT5LJMP E1NEXT5:CJNE A,#5,NEXT6LJMP E1NEXT6:CJNE A,#6,NEXT7LJMP E1NEXT7:CJNE A,#7,NEXT8LJMP E1NEXT8:CJNE A,#8,NEXT9LJMP E1NEXT9: CJNE A,#9,NEXT10LJMP E1NEXT10: CJNE A,#10,NEXT11 ;判断是否功能键LJMP E2 ;转功能键处理NEXT11:CJNE A,#11,NEXT12LJMP E2NEXT12:CJNE A,#12,NEXT13LJMP E2NEXT13:CJNE A,#13,NEXT14LJMP E2NEXT14:CJNE A,#14,NEXT15LJMP E2NEXT15: LJMP E3 ;判断是否清除键E1: CJNE R3,#1,N1 ;判断第几次按键LJMP E11 ;为第一个数字N1:CJNE R3,#2,N2LJMP E12 ;为第二个数字N2:CJNE R3,#3,N3LJMP E13 ;为第三个数字N3: LJMP E3 ;第四个数字转溢出E11:MOV R4,A ;输入值暂存R4 MOV 34H,A ;输入值送显示缓存MOV 33H,#10HMOV 32H,#10HLJMP MLOOP ;等待再次输入E12:MOV R7,A ;个位数暂存R7 MOV B,#10MOV A,R4MUL AB ;十位数ADD A,R7MOV R4,A ;输入值存R4MOV 32H,#10H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE13:MOV R7,AMOV B,#10MOV A,R4MUL ABJB OV,E3 ;输入溢出ADD A,R7JB CY,E3 ;输入溢出MOV R4,AMOV 32H,33H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE3: MOV R3,#0 ;按键次数清零MOV R4,#0 ;输入值清零MOV YJ,#0 ;计算结果清零MOV GONG,#0 ;功能键设为零MOV 30H,#10H ;显示清空MOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HLJMP MLOOPE2: MOV 34H,#10HMOV 33H,#10HMOV 32H,#10HMOV R0,GONG ;与上次功能键交换MOV GONG,AMOV A,R0CJNE A,#10,N21 ;判断功能键LJMP JIA ;”+"N21: CJNE A,#11,N22LJMP JIAN ;"-"N22:CJNE A,#12,N23LJMP CHENG ;"*”N23:CJNE A,#13,N24LJMP CHU ;”/”N24:CJNE A,#0,N25LJMP FIRST ;首次按功能键N25:LJMP DEN ;”=”N4:LJMP E3FIRST: MOV YJ,R4 ;输入值送结果MOV R3,#0 ;按键次数清零LJMP DISP1 ;结果处理JIA:MOV A,YJ ;上次结果送累加器ADD A,R4 ;上次结果加输入值JB CY,N4 ;溢出MOV YJ,A ;存本次结果MOV R3,#0 ;按键次数清零LJMP DISP1JIAN:MOV A,YJSUBB A,R4 ;上次结果减输入值JB CY,N4 ;负数溢出MOV YJ,AMOV R3,#0LJMP DISP1CHENG:M OV A,YJMOV B,AMOV A,R4MUL AB ;上次结果乘输入值JB OV,N4 ;溢出MOV YJ,ALJMP DISP1CHU:MOV A,R4MOV B,AMOV A,YJDIV AB ;上次结果除输入值MOV YJ,AMOV R3,#0LJMP DISP1DEN:MOV R3,#0LJMP DISP1DISP1:MOV B,#10MOV A,YJ ;结果送累加器DIV AB ;结果除10MOV YJ1,A ;暂存”商”MOV A,B ;取个位数MOV 34H,A ;个位数送显示缓存MOV A,YJ1JZ DISP11 ;结果是否为一位数MOV B,#10MOV A,YJ1DIV ABMOV YJ1,AMOV A,BMOV 33H,A ;十位送显示缓存MOV A,YJ1JZ DISP11 ;结果是否为二位数MOV 32H,A ;百位数送显示缓存DISP11: LJMP MLOOPDISP:MOV R0,#DBUF ;显示子程序MOV R1,#TEMP+4MOV R2,#5DP10:MOV DPTR,#SEGTABMOV A,@R0MOVC A,@A+DPTRMOV @R1,AINC R0DEC R1DJNZ R2,DP10MOV R0,#TEMPDP12:MOV A,@R0MOV P0,Aclr P2。

51单片机实现的简易计算器

51单片机实现的简易计算器

51单片机实现的简易计算器1. 4X4键盘输入,点阵字符型液晶显示。

2. 由于所采用的浮点程序库的限制(MCU平台只找到这个……),浮点运算采用3字节二进制补码表示,有效数字6位。

对于输入输出,采用3字节BCD码浮点数格式,有效数字只有4位,因此最终有效数字只有4位。

3. 可进行连续输入,例如:1.23+4.56*8.23/234.8 ,但是运算结果为从左到右,这也是8位简易计算器的方式。

4. 可进行错误判断,溢出、除零等错误将显示一个字符E 。

5. 由于键盘只有16个按键,安排如下:+---------------+| 7 | 8 | 9 | + || 4 | 5 | 6 | - || 1 | 2 | 3 | * || 0 | . | = | / |+---------------+6. 按键的缺少导致取消了一些特殊函数,即开根号,三角函数(sin, cos, tan, ctg)的实现,由于这些函数在浮点程序库中均已提供,如果硬件允许,在原来的框架上添加这些附加功能是很容易的(可以看作和+, -, *, /等价的按键操作,调用不同的子程序进行运算即可)7. 按两次= 等于清灵。

因为按键实在太少,才采用了这个做法。

8. 相应举例:按键结果说明- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -123+= 123 按下等号而没有第二个操作数,保留第一个操作数并认为此次运算结束(等号的功能)123+321/111 4.0 等价于(123+321) / 1112.3+5.4=/0.1+ 77 等号后直接按 / ,则将前面的运算结果作为第一个操作数1/0= E 错误显示9. 不足使用3字节的浮点数表示,不可避免的带来了数表示的不精确,加上有效数字比较少,因此计算结果很容易产生误差,尤其是进行连续多次运算后,结果和精度较高的科学计算器的误差会很快达到0.01以上,当然这个差距和所测试的用例也有关系,4位有效数字导致了数字123456只能表示为123400,最后两位有效数字被摒弃了。

51单片机简易计算器代码

51单片机简易计算器代码

#include"reg52.h"#define uchar unsigned char#define uint unsigned intsbit busy=P0^7;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}char i,j,temp,num;long a,b,c; //a,第一个数b,第二个数c,得数uchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar codetable1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0 x2b-0x30}; //按键显示编码表sbit lcden=P2^2;sbit lcdwrite=P2^1;sbit lcdrs=P2^0;//lcd的写指令void write_com(uchar com){lcdrs=0;lcden=0;P0=com;delay(1);lcden=1;delay(1);lcden=0;}//lcd的写数据void write_date(uchar da){lcdrs=1;lcden=0;P0=da;delay(1);lcden=1;delay(1);lcden=0;}//初始化void init() //初始化{uchar num;num=-1;lcdwrite=0;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);delay(500);//延时0.5swrite_com(0x01);i=0;j=0;a=0; //第一个参与运算的数b=0; //第二个参与运算的数c=0;flag=0; //flag表示是否有符号键按下,fuhao=0; // fuhao表征按下的是哪个符号}void keyscan() // 键盘扫描程序{P3=0xfe;if(P3!=0xfe){delay(10); //延迟20msif(P3!=0xfe){temp=P3&0xf0;switch(temp){case 0xe0:num=0; break;case 0xd0:num=1; break;case 0xb0:num=2; break;case 0x70:num=3; break;}}while(P3!=0xfe);if(num==0||num==1||num==2)//如果按下的是'7','8'或'9{if(j==1)//确认一次计算完毕,清屏{ write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'/'{flag=1;fuhao=4;//4表示除号已按}i=table1[num];write_date(0x30+i);}P3=0xfd;if(P3!=0xfd){delay(10);if(P3!=0xfd){temp=P3&0xf0;switch(temp){case 0xe0:num=4; break;case 0xd0:num=5; break;case 0xb0:num=6; break;case 0x70:num=7; break;}}while(P3!=0xfd);if(num==4||num==5||num==6)//如果按下的是'4','5'或'6'{if(j==1){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'X'{flag=1;fuhao=3;//3表示乘号已按}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(10);if(P3!=0xfb){temp=P3&0xf0;switch(temp){case 0xe0:num=8; break;case 0xd0:num=9; break;case 0xb0:num=10; break;case 0x70:num=11; break;}}while(P3!=0xfb);if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'{if(j==1){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else if(num==11)//如果按下的是'-'{flag=1;fuhao=2;//2表示减号已按}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(10);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:num=12; break;case 0xd0:num=13; break;case 0xb0:num=14; break;case 0x70:num=15; break;}}while(P3!=0xf7);switch(num){case 12://按下的是"清零"{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}break;case 13://按下的是"0"{if(flag==0)//没有按过符号键{a=a*10;write_date(0x30);}if(flag==1)//如果按过符号键{b=b*10;write_date(0x30);}}break;case 14:{j=1;if(fuhao==1){write_com(0x80+0x4f);//按下加号键,光标前进至第二行最后一个显示处write_com(0x04); //设置从后住前写数据c=a+b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d); //写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x80+0x4f);//按下减号按键write_com(0x04); //设置从后住前写数据if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d); //写负号"-"write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3)//按下乘号按键{write_com(0x80+0x4f);write_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4)//按下除号按键{write_com(0x80+0x4f);write_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;i++;if(i==3) //精确到小数点后3位write_date(0x2e); //写小数点2e}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}break;}}}main(){init();while(1) {keyscan(); }}。

(完整)基于51单片机的简易计算器设计

(完整)基于51单片机的简易计算器设计

(完整)基于51单片机的简易计算器设计基于51单片机的简易计算器设计计算器作为一种常见的电子设备,既能满足日常生活的计算需求,又能帮助人们提高工作效率。

本文将介绍基于51单片机的简易计算器的设计。

该计算器具备加减乘除的基本计算功能,并支持用户输入和结果显示。

下面将从材料准备、电路连接和程序设计三个方面详细介绍该计算器的设计。

一、材料准备在设计计算器之前,我们需要准备以下材料:1. 51单片机开发板:用于控制计算器的整个运行过程;2. 液晶显示屏:用于显示用户输入的数字和计算结果;3. 数字按键:用于用户输入数字和运算符;4. 连接线:用于连接51单片机开发板、液晶显示屏和数字按键。

二、电路连接1. 连接液晶显示屏和51单片机开发板:将液晶显示屏的VCC、GND、SCL和SDA引脚分别与开发板上对应的引脚连接。

2. 连接数字按键和51单片机开发板:将数字按键的引脚依次与开发板上的IO口引脚连接,其中有一根引脚需要连接到开发板的中断口。

三、程序设计1. 初始化设置:在程序开始时,进行液晶显示屏和数字按键的引脚初始化设置,以及相应的中断设置。

2. 输入处理:通过数字按键输入,获取用户输入的数字和运算符,并将其保存到相应的变量中。

3. 运算处理:根据用户输入的运算符,对相应的数字进行加、减、乘、除的运算,并将结果保存到一个变量中。

4. 结果显示:将运算结果显示在液晶显示屏上,以便用户查看计算结果。

5. 重置处理:在每次运算结束后,对相关变量进行重置,以便下一次计算。

通过以上程序设计,我们可以完成基于51单片机的简易计算器的设计。

在实际使用过程中,用户只需要通过数字按键输入相应的数字和运算符,计算器就可以自动进行运算,并将结果显示在液晶显示屏上,方便用户进行查看。

总结本文介绍了基于51单片机的简易计算器的设计。

通过合理的材料准备、电路连接和程序设计,我们可以实现一个具备加减乘除功能的计算器。

该计算器不仅能满足人们日常的计算需求,还能帮助提高工作效率。

基于51单片机的简易计算器设计

基于51单片机的简易计算器设计

基于51单片机的简易计算器设计设计一个基于51单片机的简易计算器,主要功能包括加减乘除四则运算和百分数计算。

下面是设计的详细步骤:1.硬件设计:-使用51单片机作为主控芯片。

-连接16x2的LCD显示屏,用于显示输入和计算结果。

-连接16个按键开关,用于输入运算符和数字。

-连接4个LED灯,用于指示四则运算的选择。

2.软件设计:-初始化LCD显示屏,并显示欢迎信息。

-监听按键输入,在接收到输入后,根据输入的按键值判断操作类型。

-如果按键值对应数字键,保存输入的数字,并在LCD上显示当前输入的数字。

-如果按键值对应四则运算符(+、-、*、/),保存当前输入的数字,并保存运算符。

-如果按键值对应等号(=),根据保存的数字和运算符进行相应的运算,计算结果保存并显示在LCD上。

-如果按键值对应清零(C),将所有保存的数据清空,并显示初始状态。

-如果按键值对应百分号(%),将当前数字除以100并显示在LCD上。

3.主要函数说明:- void init_lcd(:初始化LCD显示屏。

- void display_lcd(char* str):将指定字符串显示在LCD上。

- void clear_lcd(:清空LCD显示屏。

- char get_key(:获取按键输入的值。

- void calculate(:根据保存的数字和运算符进行计算。

- void add_digit(char digit):将输入的数字添加到当前数字中。

- void set_operator(char op):保存运算符。

- void clear_data(:清空所有保存的数据。

4.主要流程:-初始化LCD显示屏并显示欢迎信息。

-在循环中监听按键输入,并根据输入的按键值进行相应的操作。

-根据不同的按键值,调用不同的函数进行处理。

-最后计算结果显示在LCD上。

以上是基于51单片机的简易计算器设计的详细步骤和主要函数说明。

你可以根据这个设计框架进行具体的代码实现。

51单片机简易计算器设计

51单片机简易计算器设计

51单片机简易计算器设计一、引言计算器是一种通过输入和输出数字信号进行数学运算的电子设备。

在现代社会,人们对计算器有着广泛的需求,因此设计一款简单而实用的计算器对于我们理解计算器的工作原理和学习单片机编程非常有帮助。

本文将介绍一种基于51单片机的简易计算器设计,涵盖了相关的硬件设计和软件编程。

二、设计思路本计算器设计的主要思路如下:1.使用数码管显示输入的数字和计算结果。

2.使用按键输入数字和操作符。

3.通过软件编程实现数字的输入、运算和结果的显示。

三、硬件设计1.数码管:使用4位共阴数码管,通过BCD-7段译码器将数字信号转化为数码管显示。

2.按键:使用独立按键输入数字和操作符。

3.电源:使用适当的电源电路提供电压和电流。

四、软件设计1.初始化:设置数码管显示方式、按键输入方式和端口状态。

2.输入数字:通过按键输入数字,并将数字显示在数码管上。

可以采用按键扫描的方式实现,每次按键触发时读取按键值,并将对应的数字显示在数码管上。

3.输入操作符:通过按键输入操作符,并将操作符显示在数码管上。

同样采用按键扫描的方式实现。

4.数字运算:根据输入的操作符和数字进行相应的运算,得出结果。

5.显示结果:将运算结果显示在数码管上。

五、程序流程图具体的程序流程图如下:六、程序实现以下是51单片机计算器的简单代码实现:```C#include<reg51.h>sbit LED=P1^0;sbit KEY=P3^0;void delay(int n)int i=0, j=0;for(i=0; i<n; i++)for(j=0; j<123; j++);void mainwhile(1)if(KEY==0)LED=0;elseLED=1;delay(10);}```七、测试和结果在硬件设计完成并烧录完程序后,我们可以进行测试。

通过按下按键,观察数码管是否正确显示输入的数字和运算结果。

如果显示正确,则说明程序设计成功。

51单片机简易计算器

51单片机简易计算器

51单片机简易计算器程序及原理图因本人初学单片机程序过于简单请见谅程序:#include <reg51.h>sbit P3_0=P3^0;sbit P3_1=P3^1;sbit P3_2=P3^2;sbit P3_3=P3^3; //端口的定义Unsigned char code led_number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x 77,0x7c,0x39,0x5e,0x79,0x71,0x00 }; //LED灯的数据unsigned char m[5]={0};unsigned char temp;unsigned char i;unsigned int u,k,n,s;unsigned int t[3]={0};void clear(void) //对端口数据清零{for(i=0;i<4;i++){m[i]=0;}}void weiyi(void) //端口数据位移函数{for(i=4;i>0;i--){m[i]=m[i-1];}}void dengyu(void) //等于号里面的运算{switch(n){case 1:k = u + t[0];t[0] = k;break;case 2:k = t[0]-u;t[0] = k;break;case 3:k = t[0]*u;t[0] = k;break;case 4:k = t[0]/u;t[0] = k;break;}m[3]= t[0]/1000;m[2]= t[0]%1000/100;m[1]= t[0]%100/10;m[0]= t[0]%10;}void delay500us(unsigned char cnt) //延时函数{unsigned char i;do{for(i=0;i<60;i++);}while(--cnt);}void display(unsigned char led1,unsigned char led2,unsigned char led3,unsigned char led4) //数码管动态显示程序{ P2=0x00;P3=0XFF;P2=led_number[led1];P3_3=0;delay500us(50); //每隔25毫秒扫描一个端口P3=0XFF;P2=0x00;P2=led_number[led2];P3_2=0;delay500us(50); //每隔25毫秒扫描一个端口P3=0XFF;P2=0x00;P2=led_number[led3];P3_1=0;delay500us(50); //每隔25毫秒扫描一个端口P2=0x00;P3=0XFF;P2=led_number[led4];P3_0=0; //每隔25毫秒扫描一个端口delay500us(50);P3=0XFF; //端口关闭}void main() //主程序{while(1){P1=0xf0;temp=P1;if(temp!=0xf0) //按键扫描{delay500us(20); //消抖动temp = P1;if(temp!=0xf0){P1=0xfe;temp=P1;weiyi();if((temp&0xf0)!=0xf0){switch(temp){case 0xbe: m[0]=9;break;case 0xde: m[0]=8;break;case 0xee: m[0]=7;break;case 0x7e: //除号键clear();n=4;break;default:break;}}P1=0xfd;temp=P1;if((temp&0xf0)!=0xf0){switch(temp){case 0xbd: m[0]=6;break;case 0xdd: m[0]=5;break;case 0xed: m[0]=4;break;case 0x7d: //乘号键clear();n=3;break;default:break;}}P1=0xfb;temp=P1;if((temp&0xf0)!=0xf0){switch(temp){case 0xbb: m[0]=3;break;case 0xdb: m[0]=2;break;case 0xeb: m[0]=1;break;case 0x7b: //减号键clear();n=2;break;default:break;}}P1=0xf7;temp=P1;if((temp&0xf0)!=0xf0){switch(temp){case 0xd7:m[0]=0;break;case 0x77: //加号键clear();n=1;break;case 0xb7:dengyu();break;case 0xe7: //清零按键t[0] = 0;n = 0;clear();break;default:break;}}}}P1=0xf0;while(P1!=0xf0){while(P1!=0xf0);//等待放开按键delay500us(50);}if(n!=3&&n!=2&&n!=4&&n!=1){t[0] = m[3]*1000+m[2]*100+m[1]*10+m[0]*1; (第一次数据输入相加)}u = m[3]*1000+m[2]*100+m[1]*10+m[0]*1;(第二次数相加)display(m[0],m[1],m[2],m[3]);}}原理图:。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
for(i=0;i<8;i++)
{
con[i]=0;
tem[i]=0;
}
count=-1;
flag=0;
} break;
case 0x7b://equal
{
switch(flag)
count++;
switch(temp)
{
case 0xed:
{ num=4;
if(count<8)
con[count]=num;
} break;
case 0xdd:
{ num=5;
if(count<8)
}
for(j=0;j<8;j++)
{
con[j]=0;
tem[j]=0;
} break;
case 0xde:
{ num=1;
if(count<8)
con[count]=num;
} break;
case 0xbe:
{ num=2;
if(count<8)
con[count]=num;
for(i=0;i<8;i++)
{
tem1[i]=tem[i];
}
for(j=0;j<8;j++)
{
con[j]=0;
tem[j]=0;
}
count=-1;
} break;
}
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{ delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
}
}break;
case 2:
{
dat=jian(tem1,tem);
for(i=0;i<8;i++)
{
tem[i]=dat[i];
}
}break;
tem[1]=(uchar)(dat_long%10000000%1000000%100000%10000%1000%100/10);
tem[0]=(uchar)(dat_long%10000000%1000000%100000%10000%1000%100%10);
con[count]=num;
} break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
} break;
case 0x7e:
{ num=3;
if(count<8)
con[count]=num;
} break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
void keyboardscan();
uchar *jia(uchar *rat0,uchar *rat1);
uchar *jian(uchar *rat0,uchar *rat1);
ulint cheng(uchar *rat0,uchar *rat1);
ulint chu(uchar *rat0,uchar *rat1);
con[count]=num;
} break;
case 0xbd:
{ num=6;
if(count<8)
con[count]=num;
} break;
case 0x7tem[j]=0;
}
count=-1;
} break;
case 0xb7://times
{
flag=3;
count-=1;
for(i=0;i<8;i++)
{
tem1[i]=tem[i];
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{ count++;
temp=P1;
switch(temp)
{
case 0xe7://plus
{
flag=1;
count-=1;
}
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{ delay(5);
while(temp!=0xf0)
{ delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{ temp=P1;
count++;
switch(temp)
{
case 0xeb:
{ num=8;
tem[6]=(uchar)(dat_long%10000000/1000000);
tem[5]=(uchar)(dat_long%10000000%1000000/100000);
tem[4]=(uchar)(dat_long%10000000%1000000%100000/10000);
tem[3]=(uchar)(dat_long%10000000%1000000%100000%10000/1000);
tem[2]=(uchar)(dat_long%10000000%1000000%100000%10000%1000/100);
tem[1]=(uchar)(dat_long%10000000%1000000%100000%10000%1000%100/10);
case 3:
{
dat_long=cheng(tem1,tem);
tem[7]=(uchar)(dat_long/10000000);
tem[6]=(uchar)(dat_long%10000000/1000000);
tem[5]=(uchar)(dat_long%10000000%1000000/100000);
}break;
case 4:
{ if(tem==0)
break;
else
{ dat_long=chu(tem1,tem);
tem[7]=(uchar)(dat_long/10000000);
}
}
}
void keyboardscan()
{
uchar temp,num,i,j,*dat;
ulint dat_long;
P1=0xfe;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{ delay(5);
temp=P1;
else
{
for(i=0;i<=count;i++)
{
tem[i]=con[count-i];
}
for(j=0;j<8;j++)
{
P2=tab[j];
P0=table[tem[j]];
delay(1);
}
{ case 1:
{ dat=jia(tem1,tem);//这里一定要定义一个指针dat来接受返回值,
//不能定义一个数组用数组名(如dat[8])来接受返回值,因为指针是可以变化的,而数组名是固定的;
for(i=0;i<8;i++)
{
tem[i]=dat[i];
if(count<8)
con[count]=num;
} break;
case 0xdb:
{ num=9;
if(count<8)
con[count]=num;
} break;
case 0xbb://reset
tem[0]=(uchar)(dat_long%10000000%1000000%100000%10000%1000%100%10);
}
}break;
default:break;
}
// flag=0;
count=-1;
tem[4]=(uchar)(dat_long%10000000%1000000%100000/10000);
tem[3]=(uchar)(dat_long%10000000%1000000%100000%10000/1000);
tem[2]=(uchar)(dat_long%10000000%1000000%100000%10000%1000/100);
uchar con[8];
uchar tem[8];
uchar tem1[8];
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
相关文档
最新文档