51单片机的完整计算器程序
51单片机数码管显示计算器程序
定义位变量 定义液主函数 *51 单片机数码管显示计算器程序计算器程序#include<reg52.h>#include <intrins.h>#include<string.h> #include <math.h>#include <stdio.h>#define uchar unsigned char #define uint unsigned int ucharkey,sym,sumsz[13],adders=0; // 定义变量float sum,number1=0,number2=0; // 定义变量 bit flag=0; //标志位 sbit lcdrs=P2A 5; // 定义液晶的读 10 口 sbit lcdwr=P2W; // 晶的写I0 口 sbit lcden=P2A7; // 定义液晶的使能I0 口 uchar lcd_s[]={'0','1','2','3','4','5','6','7','8','9','+','-','*',0xfd,'.','='};//void keyscan(); // 函数声明void delayms(uchar z);void write_com(uchar com); void write_data(uchar dat); void init(); void delay(int z); bit buzz(); void yuans();void clear();/***********************void main()init(); // 液晶初始化while(1) // 循环函数keyscan(); // 调用键盘扫描函数键盘扫面*************************/ void keyscan()uchar temp=0;P1=0xfe; // 第1 次判断函数temp=P1;temp=temp&0xf0;if(temp!=0xf0)delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; // 确定按键按下,执行if 函数switch(temp)case 0xee:key=1;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;// 显示字符1,并记入相加的变量case 0xde:key=2;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;// 显示字符2,并记入相加的变量case 0xbe:key=3;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;// 显示字符3,并记入相加的变量case 0x7e: key=10;write_data(lcd_s[key]);sym='+';flag=1; break;// 示‘+'号,并将sym付‘ +'}while((P1&0xf0)!=0xf0); // 等待按键释放}}P1=0xfd; // 第2 次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; // 确定按键按下,执行if 函数switch(temp){case 0xed:key=4;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;// 显示字符4,并记入相加的变量case 0xdd:key=5;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;// 显示字符5,并记入相加的变量case 0xbd:key=6;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break; // 显示字符6,并记入相加的变量case 0x7d: key=11;write_data(lcd_s[key]);sym='-';flag=1; break;//示‘-'号,并将sym付‘-'}while((P1&0xf0)!=0xf0);}}P1=0xfb; // 第3 次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0)delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; // 确定按键按下,执行if 函数switch(temp){case 0xeb:key=7;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;// 显示字符7,并记入相加的变量case 0xdb:key=8;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;// 显示字符8,并记入相加的变量case 0xbb:key=9;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break; // 显示字符9,并记入相加的变量case 0x7b: key=12;write_data(lcd_s[key]);sym='*';flag=1; break;//示‘ * '号,并将sym付‘ *'}while((P1&0xf0)!=0xf0); // 等待按键释放}P1=0xf7; // 第4 次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; // 确定按键按下,执行if 函数switch(temp){case 0xe7: key=0;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} elsenumber2=number2*10+key;break;// 显示字符0,并记入相加的变量case 0xd7: key=14;clear(); break;// 调用清零函数case 0xb7: key=15;yuans();flag=1;adders--;break;// 调用运算函数case 0x77: key=13;write_data(lcd_s[key]);sym='/';flag=1; break;//示‘/ '号,并将sym付‘ /'}液晶写数据程序 { while((P1&0xf0)!=0xf0); // 等待按键释放液晶****************************/void write_com(uchar com) //液晶写指令程序{while(buzz()) ; lcdrs=0; // lcdwr=0; // lcden=0;P0=com; // _nop_();_nop_();_nop_();_nop_();lcden=1; // _nop_();_nop_();_nop_();_nop_();lcden=0; // void write_data(uchardat) // while(buzz());lcdrs = 1;液晶初始化程序 {lcdwr = 0;lcden = 0; P0 = dat; _nop_(); _nop_(); _nop_(); _nop_(); lcden = 1; _nop_(); _nop_(); _nop_(); _nop_(); lcden = 0;} void init() // lcden=0; // write_com(0x38); // write_com(0x0c); // write_com(0x06); // write_com(0x01); // } bit buzz() // 液晶测忙程序 { bit b; lcdwr=1; // lcdrs=0; //延时子程序 {延时函数 lcden=1;_nop_();_nop_();_nop_();_nop_();b=(bit)(P&0x80);lcden=0;return b;void delay(int z) // int i;while(z--){for(i = 0; i< 250; i++){_nop_();_nop_();_nop_();_nop_();}}}/********************* voiddelayms(uchar z) // 延时毫秒程序 {运算程序uchar i,j;for(i=z;i>0;i--) for(j=110;j>0;j--); }void clear() // 清零程序{ uchar i;for(i=0;i<16;i++) // 对液晶写入空格 { write_com(0x80+i);write_data(' ');}for(i=0;i<15;i++){write_com(0x80+0x40+i);write_data(' ');}write_data('0');write_com(0x80);flag=0;number1=0;number2=0;adders=0; // 将数据变量清零}void yuans() // 运算函数 { uchar i,j,temp1; /*********************** 运算*********************************/ /******************** 清零函数******************************************* */两数相加两数相减两数相乘两数相除 switch(sym){ case '+':number1+=number2;break; // case '-':number1-=number2;break; // case '*':number1*=number2;break; //case '/':number1/=number2;break; // }sprintf(sumsz,"%10.2f",number1); // j=strlen(sumsz); write_com(0x80+0x40+16-j); for(i=0;i<j;i++) // 显示结果 { temp1=sumsz[i];write_data(temp1);delay(10);}number2=0; write_com(0x80+adders-1); }。
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单片机实现计算器程序
#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单片机计算器程序
}
else if(ch1[k]=='*')
{
ch1[k-2]=ch1[k-2]*ch1[k-1];
k=k-2;
}
else if(ch1[k]=='/')
{
ch1[k-2]=ch1[k-2]/ch1[k-1];
k=k-2;
}
k++;f--;
}
}
}
}
/*void compute()
{
uchar i=0;
0xe7,0xeb,0xed,0xee,
};
uchar mode[17];
uchar show[16];
uint ch1[16];
/*void T0Server() interrupt 1
{
EA=0;
}
void delay_50ms()
{
TMOD=0x01;//定时器0方式1
TL0=0XAF;
TH0=0X3C;//50mS
k=k-2;
}
else if(ch1[k]=='-')
{
ch1[k-2]=ch1[k-2]-ch1[k-1];
k=k-2;
}
else if(ch1[k]=='*')
{
ch1[k-2]=ch1[k-2]*ch1[k-1];
k=k-2;
}
else if(ch1[k]=='/')
{
ch1[k-2]=ch1[k-2]/ch1[k-1];
k=k-2;
}
k++;
f--;
if(show[f]=='=')a2=0;
怎样用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单片机计算器1602显示程序
delay_jsq(5);
if(P2!=0xfb)
{
if(P2!=0xfb)
{
temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=8;
break;
case 0xd0:num=9;
break;
case 0xb0:num=10;
break;
case 0x70:num=11;
case 0x70:num=7;
break;
}
}
while(P2!=0xfd);
if(j!=0)
{
write_lcd1602(0x01,0);
delay(1);
j=0;
}
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
{
if(flag1==0)//没有按过符号键
break;
}
}
}
}
void main()
{
ini_lcd1602();
while(1)
{
keyscan_4_4();
}
}
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
num_1=0;
i=0;
j=0;
a=0; //第一个参与运算的数
b=0; //第二个参与运算的数
c=0;
flag1=0; //flag1表示是否有符号键按下,
fuhao=0; // fuhao表征按下的是哪个符号
基于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单片机程序)
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;
51单片机计数器程序c语言
下面是一个51单片机计数器的简单程序,使用C语言编写。
c
#include <reg51.h>
// 定义计数器的值
volatile unsigned int counter = 0;
// 定义外部中断0的服务函数
void INT0_Handler() interrupt 0 {
// 清除外部中断0标志位
EX0 = 0;
// 计数器值加1
counter++;
}
void main() {
// 设置外部中断0触发方式为下降沿触发
IT0 = 1;
// 使能外部中断0
EX0 = 1;
// 全局中断使能
EA = 1;
while(1) {
// 在此处添加处理计数器值的代码,例如:
// if (counter >= 100) {
// // 计数器值达到100,执行某些操作
// counter = 0; // 计数器清零
// }
}
}
此代码实现了51单片机的外部中断0的计数器功能。
当INT0引脚检测到下降沿时,会触发外部中断0,并执行INT0_Handler()函数,使counter值加1。
在main()函数中,可以添加处理counter值的代码。
例如,当counter值达到某个阈值时,可以执行特定的操作。
注意,这只是一个基础的示例,具体的代码可能会因具体硬件和应用需求而略有不同。
51单片机简易计算器可算小数
51单片机简易计算器#include<reg51.h>#include<math.h>#define uchar unsigned char #define uint unsigned int sbit beep=P2^3;sbit dula=P2^6;sbit wela=P2^7;sbit rw=P1^1;sbit rs=P1^0;sbit lcden=P2^5;void yunsuan();void keyinput(char s);void write_data(char ddata);void write_com(char command);void display(long a);void init();void dealerror();void dataoverflow();void welcome();char code table1[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};char code table2[]="789/456*123-.0=+";char j,k,temp,temp1,temp2,key,mchar,m,flag2=0,flag3=0; long x,y,num;int operators,input,iny;char error[5]="error";char overflow[8]="overflow";char welcome_[16]="welcome to use !";void delay(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=10;b>0;b--);}void delay_ms(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}void write_com(uchar com)//写命令{P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void write_data(uchar date)//写数据{P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}long ming(int x){long m;switch(x){case 9:m=1000000000;return m;break; case 8:m=100000000;return m;break; case 7:m=10000000;return m;break; case 6:m=1000000;return m;break; case 5:m=100000;return m;break; case 4:m=10000;return m;break; case 3:m=1000;return m;break;case 2:m=100;return m;break;case 1:m=10;return m;break; case 0:m=1;return m;break; }}void display(long a){long d;int i,flag1=0,temp,c=-1;init();if(a<0){a=a*c;write_data('-');}for(i=9;i>=0;i--){d=ming(i);temp=a/d;a=a%d;if((temp==0)&&(flag1==0)) ;else{write_data(0x30+temp);flag1=1;}if(i==2){write_data('.');flag1=1;}}}void init()//LCD初始化{rw=0;dula=0;wela=0;write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口delay(20);write_com(0x0e); //显示模式设置delay(20);write_com(0x06); //显示模式设置:光标右移,字符不移delay(20);write_com(0x01); //清屏幕指令,将以前的显示内容清除delay(20);}void yunsuan() // 运算{if (iny){switch(operators){case 1:x=x+y;num=x;if(num<10000000000&&num>-10000000000){display(num);}elsedataoverflow();break;case 2:x=x-y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 3:x=x*y;num=x/100;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 4:if (y==0)dealerror();else{if(y<100){x=x*100;y=y*100;}y=y/100;x=x/y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();}break;}y=0;}}void dealerror()//除数为0{int i=0;write_com(0x01);for(i=0;i<5;i++)write_data(error[i]);}void dataoverflow()//数值溢出{int i=0;write_com(0x01);for(i=0;i<8;i++)write_data(overflow[i]);}void welcome()//欢迎界面{int i=0;write_com(0x01);for(i=0;i<16;i++)write_data(welcome_[i]);}void keyinput(char s) //键盘输入{if(s<='9'&&s>='0') //判断按下的键是否为数值{if(flag3==0)num=num*10+100*(s-'0');elsenum=num*10+10*(s-'0');if(flag2==1){num=num/10;flag3=1;}if (operators>0){y=num;iny=1;}elsex=num;if(num<10000000000&&num>-10000000000) //当前数值是否超出限定范围display(num);elsedataoverflow();}elseswitch(s){case '.':/*iny=0;operators=0;*/flag2=1;break;case '=':write_data(table2[14]); delay(10);yunsuan();iny=0;operators=0;num=0;flag2=0;flag3=0;break;case '+':if (operators) yunsuan();operators=1;write_data(table2[15]); num=0;flag2=0;flag3=0;break;case '-':if (operators) yunsuan(); operators=2;write_data(table2[11]); num=0;flag2=0;flag3=0;break;case '*':if (operators) yunsuan(); operators=3;write_data(table2[7]); num=0;flag2=0;flag3=0;break;case '/':if (operators) yunsuan(); operators=4;write_data(table2[3]); num=0;flag2=0;flag3=0;break;}}void main() //主函数{char i;char flag0=1;init();welcome();for(i=0;i<10;i++) delay_ms(100);init();while(1){P3=0xf0;temp1=P3;P3=0x0f;temp2=P3;temp=temp1|temp2; while(P3!=0x0f) {beep=0;}beep=1;for(i=0;i<16;i++) {if(temp==table1[i]) {m=table2[i];flag0=0;}}if(flag0==0) {keyinput(m); flag0=1;}}}。
整数加减乘除计算器-C51单片机
C51单片机-整数加减乘除计算器本程序是基于技能大赛设备,所使用的模块为显示模块、主机模块和指令模块。
此计算器适合10位以内的加减乘除运算,除法没有小数位,只取整数位。
此程序仅供参考,可以相互学习使用。
/* ---简易整数计算器--- */#include<reg52.h> //包含AT89s52头文件#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/* ---1602液晶控制引脚--- */sbit rs=P2^0;sbit rw=P2^1;sbit e=P2^2;#define port P0 //1602数据端口#define port3 P3 //矩阵键盘uchar code tab[]="0123456789+-*/=c";ulong a1,a2,aa; //没有小数点的长整型变量uchar jsf; //运算符/* ---微秒延时--- */void delay(uint i){while(i--);}/* ---1602液晶各子函数--- */ void busy1602(){port=0xff;rs=0;rw=1;e=1;e=1;while(port&0x80);e=0;}void writecom(uchar com){busy1602();rs=0;rw=0;port=com;e=1;e=0;}void writedat(uchar dat){busy1602();rs=1;rw=0;port=dat;e=1;e=0;}void showstr(bit row,uchar col,uchar *s) //显示字符串{uchar i;writecom(0x80+row*0x40+col);for(i=0;s[i]!=0;i++){writedat(s[i]);}}void shownum(bit row,uchar col,ulong num) //显示数字{writecom(0x04);writecom(0x80+row*0x40+col);if(num>=0)writedat(num%10+'0');if(num>9)writedat(num/10%10+'0');if(num>99)writedat(num/100%10+'0');if(num>999)writedat(num/1000%10+'0');if(num>9999)writedat(num/10000%10+'0');if(num>99999)writedat(num/100000%10+'0');if(num>999999)writedat(num/1000000%10+'0');if(num>9999999)writedat(num/10000000%10+'0');if(num>99999999)writedat(num/100000000%10+'0');if(num>999999999)writedat(num/1000000000%10+'0');if(num>4294967294)showstr(0,4,"rorrE");}void init1602() //1602 初始化{writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);/* ---按键扫描程序--- */uchar keyscan(){uchar key=16,i;for(i=0;i<4;i++){port3=0xfe<<i|0xfe>>(8-i); //循环左移switch(port3&0xf0){case 0xe0:key=4*i;break;case 0xd0:key=4*i+1;break;case 0xb0:key=4*i+2;break;case 0x70:key=4*i+3;break;}}return key;}/* ---运算--- */void js()switch(jsf){case '+':aa=a1+a2;break;case '-':if(a1>=a2)aa=a1-a2;else if(a1<a2)aa=a2-a1;break;case '*':aa=a1*a2;break;case '/':if(a2==0)aa=' ';else aa=a1/a2; break;}}void main(){uchar k;bit b=0,a;init1602();showstr(0,3,"jisuanqi");while(1){if(keyscan()!=16&&b==0){delay(200);if(keyscan()!=16){b=1;k=keyscan();if(k==0||k==1||k==2||k==3||k==4||k==5||k==6||k==7||k==8||k= =9) //数字键{if(a==0){a1=a1*10+k;writecom(0x01);shownum(1,15,a1);}else{a2=a2*10+k;writecom(0x01);shownum(1,15,a2);}}else if(k==10||k==11||k==12||k==13) //+-*/键{a=1;writecom(0x01);switch(k){case 10:jsf='+';showstr(1,15,"+");break;case 11:jsf='-';showstr(1,15,"-");break;case 12:jsf='*';showstr(1,15,"*");break;case 13:jsf='/';showstr(1,15,"/");break;}}else if(k==14) //等号键{a=0;js();writecom(0x01);if(aa==' ')showstr(0,0,"Error"); //被除数为零不显示,第一行显示错误else shownum(1,15,aa);if(jsf=='-'&&a1<a2)showstr(1,0,"-"); // aa是负数,前边添加负号else showstr(1,0," ");}else if(k==15) //清零键{a=0;a1=a2=aa=0;jsf=0;writecom(0x01);shownum(1,15,0);}}}else if(keyscan()==16)b=0;}}。
51单片机数码管显示计算器程序
51单片机数码管显示计算器程序/***************************计算器程序***********************************/#include<reg52.h>#include <intrins.h>#include<string.h>#include <math.h>#include <stdio.h>#define uchar unsigned char #define uint unsigned int ucharkey,sym,sumsz[13],adders=0; // 定义变量float sum,number1=0,number2=0; // 定义变量 bit flag=0; // 定义位变量标志位 sbit lcdrs=P2^5; // 定义液晶的读IO口 sbit lcdwr=P2^6; // 定义液晶的写IO口 sbit lcden=P2^7; // 定义液晶的使能IO口 ucharlcd_s[]={'0','1','2','3','4','5','6','7','8','9','+','-','*',0xfd,'.','='};//void keyscan(); //函数声明void delayms(uchar z);void write_com(uchar com); void write_data(uchar dat); void init(); void delay(int z); bit buzz();void yuans();void clear();/***********************主函数*****************************/void main(){init(); //液晶初始化while(1) //循环函数{keyscan(); //调用键盘扫描函数}}/**********************键盘扫面*************************/ void keyscan(){uchar temp=0;P1=0xfe; //第1次判断函数temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; //确定按键按下,执行if函数switch(temp){case 0xee:key=1;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;//显示字符1,并记入相加的变量case 0xde:key=2;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;//显示字符2,并记入相加的变量case 0xbe:key=3;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;//显示字符3,并记入相加的变量case 0x7e: key=10;write_data(lcd_s[key]);sym='+';flag=1; break;//显示‘+’号,并将sym付‘+’}while((P1&0xf0)!=0xf0); //等待按键释放}}P1=0xfd; //第2次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; //确定按键按下,执行if函数switch(temp){case 0xed:key=4;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;//显示字符4,并记入相加的变量case 0xdd:key=5;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key; break;//显示字符5,并记入相加的变量case 0xbd:key=6;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} elsenumber2=number2*10+key;break; //显示字符6,并记入相加的变量case 0x7d: key=11;write_data(lcd_s[key]);sym='-';flag=1; break;//显示‘-’号,并将sym付‘-’}while((P1&0xf0)!=0xf0);}}P1=0xfb; //第3次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; //确定按键按下,执行if函数switch(temp){case 0xeb:key=7;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} elsenumber2=number2*10+key; break;//显示字符7,并记入相加的变量case 0xdb:key=8;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} elsenumber2=number2*10+key; break;//显示字符8,并记入相加的变量case 0xbb:key=9;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} elsenumber2=number2*10+key;break; //显示字符9,并记入相加的变量case 0x7b: key=12;write_data(lcd_s[key]);sym='*';flag=1; break;//显示‘*’号,并将sym付‘*’}while((P1&0xf0)!=0xf0); //等待按键释放}}P1=0xf7; // 第4次判断temp=P1;temp=temp&0xf0;if(temp!=0xf0){delayms(15);temp=P1;temp=temp&0xf0;if(temp!=0xf0){ temp=P1;adders++; //确定按键按下,执行if函数switch(temp){case 0xe7: key=0;write_data(lcd_s[key]);if(flag==0){number1=number1*10+key;} else number2=number2*10+key;break;//显示字符0,并记入相加的变量case 0xd7: key=14;clear(); break;//调用清零函数case 0xb7: key=15;yuans();flag=1;adders--;break;//调用运算函数case 0x77: key=13;write_data(lcd_s[key]);sym='/';flag=1; break;//显示‘/’号,并将sym付‘/’}while((P1&0xf0)!=0xf0); //等待按键释放}}}/*********************液晶****************************/ void write_com(uchar com) //液晶写指令程序 {while(buzz()) ; lcdrs=0; //lcdwr=0; //lcden=0;P0=com; //_nop_();_nop_();_nop_();_nop_();lcden=1; //_nop_();_nop_();_nop_();_nop_();lcden=0; //}void write_data(uchar dat) //液晶写数据程序 {while(buzz());lcdrs = 1;lcdwr = 0;lcden = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();lcden = 1;_nop_();_nop_();_nop_();_nop_();lcden = 0;}void init() // 液晶初始化程序 { lcden=0; //write_com(0x38); //write_com(0x0c); //write_com(0x06); //write_com(0x01); // }bit buzz() //液晶测忙程序 {bit b;lcdwr=1; //lcdrs=0; //lcden=1;_nop_();_nop_();_nop_();_nop_();b=(bit)(P&0x80);lcden=0;return b;}void delay(int z) // 延时子程序 {int i;while(z--){for(i = 0; i< 250; i++){_nop_();_nop_();_nop_();_nop_();}}}/*********************延时函数**********************************/ void delayms(uchar z) //延时毫秒程序 {uchar i,j;for(i=z;i>0;i--)for(j=110;j>0;j--); }/***********************运算*********************************/ /********************清零函数********************************************/void clear() //清零程序{ uchar i;for(i=0;i<16;i++) //对液晶写入空格{ write_com(0x80+i);write_data(' ');}for(i=0;i<15;i++){write_com(0x80+0x40+i);write_data(' ');}write_data('0');write_com(0x80);flag=0;number1=0;number2=0;adders=0; //将数据变量清零 }/**********************运算程序******************************/ void yuans() //运算函数 {uchar i,j,temp1;switch(sym){case '+':number1+=number2;break; //两数相加case '-':number1-=number2;break; //两数相减case '*':number1*=number2;break; //两数相乘case '/':number1/=number2;break; //两数相除}sprintf(sumsz,"%10.2f",number1); //j=strlen(sumsz);write_com(0x80+0x40+16-j);for(i=0;i<j;i++) //显示结果{ temp1=sumsz[i];write_data(temp1);delay(10);}number2=0;write_com(0x80+adders-1); }。
80c51单片机简易计算器源程序
80c51单片机简易计算器源程序#include#include#include#define uint unsigned int#define unch unsigned char#define D8279 XBYTE[0x7EFF]#define CTRL8279 XBYTE[0x7FFF]unchZXM[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unch n;unch result_flag;unch p;//浮点型数字的精确度unch Q;//小数点前一位数的字形码unch m;//存放键码unch key;//记录按下键盘后所代表的数字或运算符unch temp;//中间变量unch num;//实时记录数字和运算符在内的所有ASC码字符的个数unch num1;//实时记录数字的个数uint a[10]={0};//用于存放运算符两侧数的各个位unch i;//上面数组的循环控制变量unch aa;//小数运算时,记录小数点前面的个数unch bb;//记录小数点后面的变量long total_1,total_2;//total_1表示运算符左边的数,total_2表示运算符右边的数unch operator_flag;//要进行何种运算的标志变量float total_operation,total;//total_operation除法运算时用于存放结果的变量,total表示经过运算后的数float total1_point; //小数运算时用于记录运算符左边的小数float total2_point; //小数运算时用于记录运算符右边的小数unch point_flag;//小数运算的标志变量void Operation();void clear_array()//数组清除函数,用于清除运算符左边或右边的运算数的各个位{for(i=0;i<10;i++)a[i]=0;i=0;}void newset() //8279初始化//{CTRL8279=0x90; //写显示RAM,地址自动加一//CTRL8279=0x34; //定标//CTRL8279=0x10; //8个字符显示右边输入,编码扫描,键盘锁定//}void clear_ram()//总清除命令//{CTRL8279=0xd1;i=CTRL8279;i&=0x80; //读出8279的状态寄存器中显示的状态,重点读DU 位//while(i==0x80) //等待清除完成,直到DU位变成0,说明清除完毕,才可在写显示里写入字形码//{i=CTRL8279;i&=0x80;}}void key_scan() //独立键盘函数归零函数{clear_ram();newset();num=0; //记录数字个数的变量清0num1=0; //记录数字和符号个数的变量清0total_1=0; //运算符左边数暂存变量清0total_2=0;total1_point=0;total2_point=0;//运算符右边数暂存变量清0total=0; //运算结果暂存变量清0clear_array(); //数组清0D8279=0xbf;}void calculate_1() //求得运算符左边的那个数{unch j;long middle;for(j=0,middle=1;j<="">//这里多乘了10倍因为后面会先除以10在作乘法运算for(j=0;j<num1;j++)< bdsfid="137" p=""></num1;j++)<> {middle=middle/10; //每次乘数都要缩小10倍total_1=total_1+a[j]*middle; //将运算符左边的每个数字乘以相应的倍数再累加得到运算符左边的数并存放到total_1中}if(point_flag==1)//出现小数时,则计算得到其值{for(j=0,middle=1;j<bb;j++)< bdsfid="145"p=""></bb;j++)<>middle=middle*10;total1_point=1.0*total_1/middle;//totall_point为整数部分}num1=0; //确定完运算符左边的数后将统计数字个数的变量清0 }void calculate_2() //求得运算符右边的那个数{unch j;long middle;for(j=0,middle=1;j<="" p="">middle=middle*10; //确定最一开始每个数字要乘以的倍数//这里多乘了10倍因为后面会先除以10在作乘法运算for(j=0;j<num1;j++)< bdsfid="159" p=""></num1;j++)<> {middle=middle/10;//每次乘数都要缩小10倍total_2+=a[j]*middle;//将运算符左边的每个数字乘以相应的倍数//再累加得到运算符左边的那个数//并存放到total_2中}if(point_flag==1)//出现小数时则计算得到其值{for(j=0,middle=1;j<bb;j++)< bdsfid="169" p=""></bb;j++)<>middle=middle*10;total2_point=1.0*total_2/middle;}num1=0;//确定完运算符右边的数后将统计数字个数的变量清0 }////////******************用于显示经过运算后得到的整形结果的函数*******************************////////void display(long total_temp){unch j;long middle,temp;n=(long)(log10(total_temp))+1;//确定是几位数for(j=0,middle=1;j<="">middle=middle*10;//middle运算后为100000for(j=0;j<n-1;j++)< bdsfid="185" p=""></n-1;j++)<>{middle=middle/10;//middle每次缩小10倍,例如此处为10000temp=(long)(total_temp/middle);//将结果12345除以10000得到商1D8279=ZXM[temp];total_temp=total_temp-temp*middle; //12345-10000=2345,继续类似确定出每1位,}D8279=ZXM[total_temp]|0x80;}//////*************************用于显示经过运算后得到的浮点型结果的函数***********************/////////void display_decimals(float temp1,unch r){unch j,z[]={0};for(j=0;j<="">{z[j]=(long)(temp1*10);temp1=temp1*10-((long)(temp1*10));// 3.42-3=0.42}while(z[r-1]==0)r--; //如果最后一位是0,继续检测前面一位,直到检测非零值;for(j=0;j<r;j++)< bdsfid="208" p=""></r;j++)<>D8279=ZXM[z[j]];}int1( ) interrupt 2 //计算器矩阵键盘扫描中断函数,从左到右,从上到下{if(num==0) //若输入为第一个数字时,将显示器'0.'{newset();}CTRL8279=0x40; //发送读FIFO/RAM命令//m=D8279;switch(m){case 0x1d: key=7;a[i++]=7; //每按下一个数字就把该数字存入数组中,同时数组控制变量+1num++;num1++; //每按下一个数字,统计数字个数变量+1,统计数字和运算符个数变量+1D8279=0x07;break;case 0x1c: key=8;a[i++]=8;num++;num1++;D8279=0x7f;break;case 0x1b: key=9;a[i++]=9;num++;num1++;D8279=0x6f;break;case 0x1a: key='+';operator_flag=4;//运算符标志变量赋予不同值表示不同的运算方式bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x19: key='%';operator_flag=9;bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();bb=num1-aa; //确定小数点后有几位数clear_ram();Operation();result_flag=1;break;case 0x18: key='c';key_scan();break;case 0x15: key=4;a[i++]=4;//每按下一个数字就把该数字存入数组中,同时数组控制变量+1num++;num1++; //每按下一个数字,统计数字个数变量+1,统计数字和运算符个数变量+1D8279=0x66;break;case 0x14: key=5;a[i++]=5;num++;num1++;D8279=0x6d;break;case 0x13: key=6;a[i++]=6;num++;num1++;D8279=0x7d;break;case 0x12: key='-';operator_flag=3;//运算符标志变量赋予不同值表示不同的运算方式bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x11: key='z';operator_flag=8;//运算符标志变量赋予不同值表示不同的运算方式bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x10: key='^';operator_flag=5;bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();bb=num1-aa; //确定小数点后有几位数clear_ram();Operation();result_flag=1;break;case 0x0d: key=1;a[i++]=1;//每按下一个数字就把该数字存入数组中,同时数组控制变量+1num++;num1++;//每按下一个数字,统计数字个数变量+1,统计数字和运算符个数变量+1D8279=0x06;break;case 0x0c: key=2;a[i++]=2;num++;num1++;D8279=0x5b;break;case 0x0b: key=3;a[i++]=3;num++;num1++;D8279=0x4f;break;case 0x0a: key='*';operator_flag=2;//运算符标志变量赋予不同值表示不同的运算方式bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x09: key='!';operator_flag=10;bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();bb=num1-aa; //确定小数点后有几位数clear_ram();Operation();result_flag=1;break;case 0x08: key='k';operator_flag=6;bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x05: key=0;a[i++]=0;//每按下一个数字就把该数字存入数组中,同时数组控制变量+1num++;num1++;//每按下一个数字,统计数字个数变量+1,统计数字和运算符个数变量+1D8279=0x3f;break;case 0x04 :key=',';//相当于输入为0的程序重复执行a[i++]=0;num++;num1++;D8279=0x3f;a[i++]=0;num++;num1++;D8279=0x3f;break;case 0x03: key='.';num++;aa=num1;//确定小数点前有几位数CTRL8279=0x60+aa-1;Q=D8279;CTRL8279=0x80+aa-1;D8279=Q|0x80;point_flag=1;CTRL8279=0x90+aa;break;case 0x02: key='/';operator_flag=1; //运算符标志变量赋予不同值表示不同的运算方式bb=num1-aa; //确定小数点后有几位数calculate_1(); //按下一个运算符后就把其左侧的运算数计算出来clear_array(); //确定一个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();break;case 0x01: key='x';operator_flag=7;bb=num1-aa; //确定小数点后有几位数calculate_1();//按下一个运算符后就把其左侧的运算数计算出来clear_array();//确定1个运算数后数组清0aa=0;bb=0;point_flag=0;num++; //统计数字和运算符个数变量+1clear_ram();newset();bb=num1-aa; //确定小数点后有几位数clear_ram();Operation();result_flag=1;break;case 0x00: key='=';bb=num1-aa; //确定小数点后有几位数clear_ram();Operation();result_flag=1;break;}}float en(float y,unch c){unch i;float sum=y;if(c==0)return 1;for(i=0;i<c-1;i++)< bdsfid="432" p=""></c-1;i++)<> sum*=y;return sum;}long jiecheng(unsigned int c){unsigned long sum;sum=1;while(c!=0){sum=sum*c;c--;}return sum;}void jieguo(float total_operation){unch v,w;if((total_operation-(long)total_operation)==0.0){if((long)total_operation!=0)display(total_operation);elseD8279=0xbf;}else{if((long)total_operation!=0){display((long)total_operation);v=(long)log10((long)total_operation)+1;w=8-v;display_decimals(1.0*(total_operation-(long)total_operation),w);}else{D8279=0Xbf;w=7;display_decimals(total_operation,w);}}}//////////**********************显示结果函数*************************////////// void Operation(){ newset();calculate_2();if(total1_point==0)total1_point=1.0*total_1;if(total2_point==0)total2_point=1.0*total_2;if(operator_flag==1)//*************如果输入/运算符**************// {operator_flag=0;//按了=键后计算得到运算符右边的数total=total1_point/total2_point;//转为浮点型数据jieguo(total);}if(operator_flag==2)//*******如果输入*运算符*********//{operator_flag=0;total=total1_point*total2_point;//转为浮点型数据jieguo(total);}if(operator_flag==3)//*******如果输入-运算符***********//{operator_flag=0;total=total1_point-total2_point; //进行减法运算if(total<0) //如果为负数{D8279=0x40;total=total2_point-total1_point;}jieguo(total);}if(operator_flag==4)//********如果输入+运算符*********// { operator_flag=0;total=(total1_point+total2_point);//转为浮点型数据jieguo(total);}if(operator_flag==5)//********如果输入^运算符*********// { operator_flag=0;total=(total1_point*total1_point);//转为浮点型数据jieguo(total);}if(operator_flag==6)//********如果输入√运算符*********// { operator_flag=0;total=log10((long)(total2_point));//转为浮点型数据jieguo(total);}if(operator_flag==7)//********如果输入1/x运算符*********// { operator_flag=0;total=1/(total1_point);//转为浮点型数据jieguo(total);}if(operator_flag==8)//********如果输入ncf运算符*********// { operator_flag=0;total=en(total1_point,(int)total2_point);//转为浮点型数据jieguo(total);}if(operator_flag==9)//**********如果输入%*********//{operator_flag=0;total=(total1_point)/100;//转为浮点型数据jieguo(total);}if(operator_flag==10)//**********如果输入阶乘!*********// { operator_flag=0;total=jiecheng((int)total1_point);jieguo(total);}}void main(){clear_ram(); //总清除newset(); //8279初始化key_scan();IT1=0; //设置INT1中断方式为低电平EX1=1; //允许INT1中断EA=1; //CPU允许中断while(1); //等待中断//}。
51单片机100内的加减乘除计算器C语言程序
51单片机100内的加减乘除计算器C语言程序#include //包含文件#define uchar unsigned char#define uint unsigned intcharb[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80 ,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x8c,0xc1,0xce,0x91,0x89,0xc7,0xff }; // 共阴极字符码//延时函数,用于实现程序中的短暂延时,表示延时cnt个毫秒void delay(unsigned int cnt){unsigned char i;while(cnt--){for(i=220;i>0;i--);}}//键盘扫描程序uchar keyboardscan(void){uchar sccode,recode;P1=0xf0; //P1口附初值if((P1&0xf0)!=0xf0)//如果P1口电平不等于0xf0,表示有按键按下{delay(20); //延时20毫秒后再判断,看是否还有按键按下,次步为软件防抖if((P1&0xf0)!=0xf0)//继续判断是否有按键按下{sccode=0xfe; //进行逐行判断while((sccode&0x10)!=0){P1=sccode;if((P1&0xf0)!=0xf0){recode=(P1&0xf0|0x0f);switch((~sccode)+(~recode)){ // 下面是键盘的编码识别case 0x11: return(1); break;case 0x21: return(2); break;case 0x41: return(3); break;case 0x81: return(11); break;//返回对应的键值0~15case 0x12: return(4); break;case 0x22: return(5); break;case 0x42: return(6); break;case 0x82: return(12); break;case 0x14: return(7); break;case 0x24: return(8); break;case 0x44: return(9); break;case 0x84: return(13); break;case 0x18: return(10); break;case 0x28: return(15); break;case 0x48: return(16); break;case 0x88: return(14); break;default:break;}}elsesccode = (sccode。
整数加减乘除计算器-C51单片机
整数加减乘除计算器-C51单片机C51单片机-整数加减乘除计算器本程序是基于技能大赛设备,所使用的模块为显示模块、主机模块和指令模块。
此计算器适合10位以内的加减乘除运算,除法没有小数位,只取整数位。
此程序仅供参考,可以相互学习使用。
/* ---简易整数计算器--- */#include //包含AT89s52头文件#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/* ---1602液晶控制引脚--- */sbit rs=P2^0;sbit rw=P2^1;sbit e=P2^2;#define port P0 //1602数据端口#define port3 P3 //矩阵键盘uchar code tab[]="0123456789+-*/=c";ulong a1,a2,aa; //没有小数点的长整型变量uchar jsf; //运算符/* ---微秒延时--- */void delay(uint i){while(i--);}/* ---1602液晶各子函数--- */ void busy1602(){port=0xff;rs=0;rw=1;e=1;e=1;while(port&0x80);e=0;}void writecom(uchar com){busy1602();rs=0;rw=0;port=com;e=1;e=0;}void writedat(uchar dat){busy1602();rs=1;rw=0;port=dat;e=1;e=0;}void showstr(bit row,uchar col,uchar *s) //显示字符串{ uchar i;writecom(0x80+row*0x40+col);for(i=0;s[i]!=0;i++){writedat(s[i]);}}void shownum(bit row,uchar col,ulong num) //显示数字{ writecom(0x04);writecom(0x80+row*0x40+col);if(num>=0)writedat(num%10+'0');if(num>9)writedat(num/10%10+'0');if(num>99)writedat(num/100%10+'0');if(num>999)writedat(num/1000%10+'0');if(num>9999)writedat(num/10000%10+'0');if(num>99999)writedat(num/100000%10+'0');if(num>999999)writedat(num/1000000%10+'0');if(num>9999999)writedat(num/10000000%10+'0');if(num>99999999)writedat(num/100000000%10+'0'); if(num>999999999)writedat(num/1000000000%10+'0'); if(num>4294967294)showstr(0,4,"rorrE");}void init1602() //1602 初始化{writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);/* ---按键扫描程序--- */uchar keyscan(){uchar key=16,i;for(i=0;i<4;i++){port3=0xfe<>(8-i); //循环左移switch(port3&0xf0){case 0xe0:key=4*i;break;case 0xd0:key=4*i+1;break; case 0xb0:key=4*i+2;break; case 0x70:key=4*i+3;break; }}return key;}/* ---运算--- */void js()switch(jsf){case '+':aa=a1+a2;break; case '-':if(a1>=a2)aa=a1-a2; else if(a1< p="">break;case '*':aa=a1*a2;break; case '/':if(a2==0)aa=' '; else aa=a1/a2; break;}}void main(){uchar k;bit b=0,a;init1602();showstr(0,3,"jisuanqi"); while(1){if(keyscan()!=16&&b==0) {delay(200);if(keyscan()!=16){b=1;k=keyscan();if(k==0||k==1||k==2||k==3||k==4||k==5||k==6||k==7||k== 8||k= =9) //数字键{if(a==0){a1=a1*10+k;writecom(0x01);shownum(1,15,a1);}else{a2=a2*10+k;writecom(0x01);shownum(1,15,a2);}}else if(k==10||k==11||k==12||k==13) //+-*/键{a=1;writecom(0x01);switch(k){case 10:jsf='+';showstr(1,15,"+");break;case 11:jsf='-';showstr(1,15,"-");break;case 12:jsf='*';showstr(1,15,"*");break;case 13:jsf='/';showstr(1,15,"/");break;}}else if(k==14) //等号键{a=0;js();writecom(0x01);if(aa==' ')showstr(0,0,"Error"); //被除数为零不显示,第一行显示错误else shownum(1,15,aa);if(jsf=='-'&&a1<="" p="">else showstr(1,0," ");}else if(k==15) //清零键{a=0;a1=a2=aa=0;jsf=0;writecom(0x01);shownum(1,15,0);}}}else if(keyscan()==16)b=0;}}<>。
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]);}}原理图:。
基于51单片机的计算器程序
{jian=0;jia0=0;jian0=1;cheng0=0;chu0=0;}
if(cheng)
{cheng=0;jia0=0;jian0=0;cheng0=1;chu0=0;}
if(chu)
{chu=0; jia0=0;jian0=0;cheng0=0;chu0=1;}
if(a0!=16) s5=a0;
if(b0!=16) s4=b0;
if(c0!=16) s3=c0;
if(d0!=16) s2=d0;
if(e0!=16) s1=e0;
if(f0!=16) s0=f0;
}
void main()
{ uchar gongneng,yunsuan;
while(1)
{
keyscan();
gongneng=jia|jian|cheng|chu|dengyu|qingling;
if(gongneng==0)
{
display0();
}
else
{ yunsuan=jia|jian|cheng|chu;
switch(wei)
{
case 6:
qian=s5*100000+s4*10000+s3*1000+s2*100+s1*10+s0;break;
case 5:
qian=s5*10000+s4*1000+s3*100+s2*10+s1;break;
e0=16;
f0=16;
break;
case 5: e0=key;
f0=16;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MOV R0, #VARIABLE_LEDBUF
MOV R1, #4 ; 共4个八段管
MOV R2, #11111110B ; 从左边开始显示
LOOP:
MOV OUTBIT, #0FFH ; 关所有八段管
MOV R2, A ;
INC R0
DJNZ R1, LOOP
RET
;**************************************************行值局部程序*****************************************************************************
VARIABLE_REPLACE_POINT EQU 40H ;结果显示位置指针
;VARIABLE_RESULTB EQU 41H
;VARIABLE_RESULTC EQU 42H
;VARIABLE_RESULTD EQU 43H
VARIABLE_SIGN1 EQU 44H ;保存第一个符号位
S3 EQU 52H ;功能2实现:将十进制位数字(S6-S7),转化为个位数字,存储在(S1-S5)
S4 EQU 53H ;S1(最高位),S5(最低位)
S5 EQU 54H
S6 EQU 55H
S7 EQU 56H
KEY1 BIT P3.2
KEY2 BIT P3.3
DB 01h, 05h, 09h
DB 02h, 06h, 0Ah
DB 03h, 07h, 0Bh
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$子程序区$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
OUTSEG EQU P0 ; 段控制口
ROW_COLUMN EQU P1 ; 读键盘行线口
VARIABLE_DELAY1 EQU 30H ;延时变量
VARIABLE_DELAY2 EQU 31H
VARIABLE_LEDBUF_POINT EQU 4BH ;第一个输入数位置指针
VARIABLE_LEDBUF EQU 4CH ; 显示缓冲
S1 EQU 50H ;自定义数字电路入口与出口
S2 EQU 51H ;功能1实现:将分离个位数字(S1-S5),转化为十进制,存储在S6,S7
DE1:
MOV VARIABLE_DELAY2,#06FH
DE:
DJNZ VARIABLE_DELAY2,DE
DJNZ VARIABLE_DELAY1 ,DE1
RET
;***************************************************扫描按键程序*****************************************************************************
VARIABLE_STORE5 EQU 36H ;存储最后结果
VARIABLE_STORE6 EQU 37H
VARIABLE_INPUT1A EQU 38H ;第一个输入数保存地址
VARIABLE_INPUT1B EQU 39H
VARIABLE_RESULT_POINT EQU 48H ;第二个输入数状态指针,记录输入的位数
VARIABLE_PLACE1_POINT EQU 49H ;第一个输入数位置指针
VARIABLE_PLACE2_POINT EQU 4AH ;第一个输入数位置指针
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$变量定义区(30H-)$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
OUTBIT EQU P2 ; 位控制口
LEDMAP: ; 八段管显示码(共阳极)
DB 0C0h, 0F9h, 0A4h, 0B0h, 099h, 092h, 082h, 0F8h,080h, 090h, 088h, 083h,0C6H
KEYTABLE:
DB 00h, 04h, 08h
MOV R3,#0FFH
ACALL GET_ROW1
GE1:
RRC A
INC R3
JC GE2
SJMP GE1
GE2:
RET
;***************************得到列值程序,出口参数R4(列值),所用寄存器R1,R2******************************************** ***************
VARIABLE_STORE1 EQU 32H ;存储第一个输入数
VARIABLE_STORE2 EQU 33H
VARIABLE_STORE3 EQU 34H ;存储第二个输入数
VARIABLE_STORE4 EQU 35H
ORG 0000H
AJMP STABLE
ORG 0100H
; *****************************************************键码定义和键值定义*******************************************************************
KEY3 BIT P3.4
KEY4 BIT P3.5
;****************************************************进入主程序*****************************************************************************
RET
;*******************************得到行值程序,出口参数R3(行值)**********************************************************************************
GET_ROW:
MOV ROW_COLUMN,#07H ;将行线置1.列线置0
;****************************************************延时程序(30H,31H)**********************************************************************
DELAY:
MOV VARIABLE_DELAY1,#10H
VARIABLE_INPUT1C EQU 3AH
VARIABLE_INPUT1D EQU 3BH
VARIABLE_INPUT2A EQU 3CH ;第二个输入数保存地址
VARIABLE_INPUT2B EQU 3DH
VARIABLE_INPUT2C EQU 3EH
VARIABLE_INPUT2D EQU 3FH
GET_ROW1:
MOV A,ROW_COLUMN ; 读入键状态
ORL A, #0f8h ; 高5位不用,变为11111
CPL A ;11111110->00000001,11111101->00000010,11111011->00000100, 1,2,4
MOV ROW_COLUMN, a
ACALL GET_ROW1 ;调用得到行值时需要给出列值的状态
JZ GOON1 ;当A为零时,说明本列有键按下
VARIABLE_SIGN2 EQU 45H ;保存第二个符号位
VARIABLE_INPUT1_POINT EQU 46H ;第一个输入数状态指针,记录输入的位数
VARIABLE_INPUT2_POINT EQU 47H ;第二个输入数状态指针,记录输入的位数
FUNCTION1_SIGN1:
MOV VARIABLE_SIGN1,#1
SJMP SCANNING
FUNCTION2_SIGN1:
MOV VARIABLE_SIGN1,#2
SJMP SCANNING
FUNCTION3_SIGN1:
MOV VARIABLE_SIGN1,#3
ห้องสมุดไป่ตู้GET_COLUMN:
MOV ROW_COLUMN,#07H ;将行线置1.列线置0
MOV R2, #4
KLoop:
CJNE R2,#4,NEXT1
MOV A,#01FH
AJMP NEXT5
NEXT1:
CJNE R2,#3,NEXT2
SCANNING:
JNB KEY1,FUNCTION1_SIGN1
JNB KEY2,FUNCTION2_SIGN1
JNB KEY3,FUNCTION3_SIGN1
JNB KEY4,FUNCTION4_SIGN1
RET
;****************************************************第一个符号位保存程序*****************************************************************
MOV OUTSEG, @R0
MOV OUTBIT, R2 ; 显示一位八段管
ACALL DELAY ;
MOV A, R2 ; 位选选中下一位