/* 接盤按鍵說明: -------------------------------------------------- | 1 | 2 | 3 | + | - - - - - - - - - - - - - | 4 | 5 | 6 | - | - - - - - - - - - - - - - | 7 | 8 | 9 | * | - - - - - - - - - - - - - | C | 0 | = | / | --------------------------------------------------*/ //操作簡介 // 按第一個數,再按'+-*/',再按'='顯示出結果,然后按C清屏 // 加最大9999+9999=19998 // 減最大9999-0 =9999 // 乘最大9999*9999=99980001 // 除 1/9=0.1111 保留小數點后4位 #include<reg51.h> #define uint unsigned int #define uchar unsigned char //--------LCD1602------------------- //P00-07==== D0-7 sbit rs=P2^5; //指令or數據 sbit wela=P2^6; //讀or寫 sbit lcden=P2^7; //使能信號 //--------LCD1602------------------- //--------KEY----------------------- //P1口 //--------KEY----------------------- uchar code table[]= " "; long int data_a,data_b; //第一個數和第二個數 long int data_c; //計算結果 uchar dispaly[10]; //顯示緩沖 //************************************************************************/ // 描述: 延時t us函數 //************************************************************************/ void LCD_Delay_us(unsigned int t) { while(t--); //t=0,退出 } //************************************************************************/ // 描述: 延時t ms函數 //************************************************************************/ void LCD_Delay_ms(unsigned int t) { unsigned int i,j; for(i=0;i<t;i++) //執行t次循環 for(j=0;j<113;j++) //執行113次循環 ; } //************************************************************************/ // 描述: 1602液晶寫指令 //************************************************************************/ void write_com(uchar com) //1602液晶寫指令 { rs=0; //寫指令 lcden=0; //使能1602 P0=com; //寫入指令com LCD_Delay_ms(1); //延時1ms lcden=1; //使能1602 LCD_Delay_ms(2); //延時2ms lcden=0; //使能1602 } //************************************************************************/ // 描述:1602液晶寫數據 //************************************************************************/ void write_date(uchar date) //1602液晶寫數據 { rs=1; //寫數據 lcden=0; //使能1602 P0=date; //寫入數據date LCD_Delay_ms(1); //延時1ms lcden=1; //使能1602 LCD_Delay_ms(2); //延時2ms lcden=0; //使能1602 } //************************************************************************/ // 描述:指定x,y寫入字符函數 //************************************************************************/ void W_lcd(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0){write_com(0x80 + x);} //第一行 else{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){write_com(0x80 + x);} //第一行 else{write_com(0xC0 + x);} //第二行 while (*s) // {write_date( *s); s++;} //寫入數據 } //************************************************************************/ // 描述:初始化液晶,及畫面初始化 //************************************************************************/ void init_lcd(void) //初始化液晶,及畫面初始化 { wela=0; //寫液晶 lcden=0; //使能1602 write_com(0x38); //8 位總線,雙行顯示,5X7 的點陣字符 LCD_Delay_us(100); //延時100us write_com(0x0c); //開顯示,無光標,光標不閃爍 write_com(0x06); //光標右移動 write_com(0x01); //清屏 write_com(0x80); //DDRAM 地址歸0 } //************************************************************************/ // 描述: 反轉法鍵盤掃描 //************************************************************************/ short keycheckdown() /* 反轉法鍵盤掃描 */ { short temp1,temp2,temp,a=0xff; P1=0xf0; /* 輸入行值(或列值) */ LCD_Delay_ms(20); /* 延時 */ temp1=P1; /* 讀列值(或行值) */ P1=0xff; LCD_Delay_ms(20); /* 延時 */ P1=0x0f; /* 輸入列值(或行值) */ LCD_Delay_ms(20); /* 延時 */ temp2=P1; /* 讀行值(或列值) */ P1=0xff; temp=(temp1&0xf0)|(temp2&0xf); /* 將兩次讀入數據組合 */ switch(temp) /* 通過讀入數據組合判斷按鍵位置 */ { case 0x77 :a=0x0d;break;// 按鍵/ case 0x7b :a=0x0e; break;// 按鍵= case 0x7d :a=0; break;// 按鍵0 case 0x7e :a=0x0f; break;// 按鍵CE case 0xb7 :a=0x0c;break;// 按鍵* case 0xbb :a=0x9;break; // 按鍵9 case 0xbd :a=0x8;break; // 按鍵8 case 0xbe :a=0x7;break; // 按鍵7 case 0xd7 :a=0x0b;break;// 按鍵- case 0xdb :a=0x6;break; // 按鍵6 case 0xdd :a=0x5;break; // 按鍵5 case 0xde :a=0x4;break; // 按鍵4 case 0xe7 :a=0x0a; break;// 按鍵+ case 0xeb :a=3;break; // 按鍵3 case 0xed :a=2;break; // 按鍵2 case 0xee :a=1;break; // 按鍵1 default :a=0xff; } return 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); //顯示數據a if(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]); //顯示個位 } 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+6+0x40); //第一行 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+11+0x40); //第一行 write_date('E'); //顯示 E write_date('r'); //顯示R write_date('r'); //顯示R write_date('o'); //顯示O write_date('r'); //顯示E } } void eql(uchar x)//加減乘除運算 { switch(x) /*功能鍵選擇*/ { case 1:data_c=data_a+data_b;break; //加 /* + S=1 */ /* 數值轉換函數 */ case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///減 else{data_c=data_b-data_a;W_lcd(5,1,'-');} //負數符號 break; case 3:data_c=(data_a*data_b);break; /* * S=3 *///乘 case 4:if(data_b==0){LCD_Write_String(0,1,"Error !");}else{data_c=(data_a*10000)/data_b;}break; /* / S=4 *///除//溢出時顯示錯誤 case 0:break; } } void main() { uchar key=0xff; //鍵值初始化 uchar n=0; //第1個數可以按1-4次 uchar m=5; //第2個數可以按1-4次 uchar x=0; data_a=0; //前一個數 data_b=0; //后一個數 data_c=0; //結果 init_lcd(); //1602液晶初始化 display_a(); while(1) { key=keycheckdown(); /*動態掃描鍵盤,返回按鍵對應值,賦給j key=0到f */ if(0xff!=key) /*若返回值有效,進入內部處理程序*/ { if(key<10) { if(n<4){data_a=data_a*10+key;m=5;display_a();}n++; //首先輸入第一個數 if(m<4){data_b=data_b*10+key;n=5;display_b();}m++; //必須按了+-*/才能輸入第二個數 } else { switch(key) /*功能鍵選擇*/ { case 0xa:n=5;m=0;x=1;W_lcd(5,0,'+');break; //加 /* + S=1 */ /* 數值轉換函數 */ case 0xb:n=5;m=0;x=2;W_lcd(5,0,'-');break; /* - S=2 *///減 case 0xc:n=5;m=0;x=3;W_lcd(5,0,'*');break; /* * S=3 *///乘 case 0xd:n=5;m=0;x=4;W_lcd(5,0,'/');break; /* / S=4 *///除 case 0xe:n=5;m=5;eql(x);W_lcd(12,0,'=');display_c(x);break; /* = */ case 0xf:n=0;x=0;m=5; data_a=0;data_b=0;data_c=0;LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0');break; /* C*/ } } do{P1=0xf0;}while(P1!=0xf0); /*等待按鍵松開*/ }//(0xff!=key) }//while }//main |