之前看到網上利用51和12864做計算器的資源比較少,找了很久才找到了一個帖子是用12864做的計算器,于是下載下來后做了一定程度的改進,于是想分享出來讓更多吧友看到,也歡迎各位留言評論,咱們一起學習,個人的思想還是很狹隘的,一個人想問題時思緒容易走進死胡同出不來,希望各位吧友指出不足和改進意見。附件是仿真和程序,用keil5寫的,keil4可能打不開哦(反正我用keil4打不開的),仿真也是protues8.6做的,低版本也可能打不開。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
1.png (64.85 KB, 下載次數(shù): 77)
下載附件
2021-3-23 21:45 上傳
單片機源程序如下:
- #include<reg52.h>
- #include<array.h>
- #include<stdio.h>
- #include<string.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit E=P2^0;
- sbit RW=P2^1;
- sbit RS=P2^2;
- sbit CS2=P2^3;
- sbit CS1=P2^4;
- sbit RST=P2^5;
- sbit BEEP=P2^6;
- uchar hang,lie; //行,列
- float dat1,dat2,count; //運算值
- uchar keynum; //按鍵返回值(0~17)
- uchar x; //按鍵所對應的字符在字符表中的行號
- uchar keyfun; //運算方式選擇(1:*, 2:+, 3:-, 4:/)
- void delay(uchar i) //延遲10*n微秒
- {
- while(i--);
- }
- void delay_ms(uchar n) //延遲n毫秒
- {
- uchar i,j;
- for(i=n;n>0;n--)
- for(j=120;j>0;j--);
- }
- /********************************************************/
- /*********************檢測工作狀態(tài)***********************/
- //void checkbusy(void)
- //{
- // unsigned int timeout = 0;
- // E = 0;
- // RS = 0;
- // RW = 1;
- // E = 1;
- // while((P0 & 0x80)&& ++timeout != 0);//忙狀態(tài)檢測,等待超時時間為60ms
- // E = 0;
- //}
- /********************************************************/
- /************************寫命令**************************/
- void write_cmd(uchar cmd)
- {
- // checkbusy();
- RS=0;
- RW=0;
- E=1;
- P0=cmd;
- delay(20);
- E=0;
- }
- /****************************************************/
- /***********************寫數(shù)據(jù)***********************/
- void write_dat(uchar dat)
- {
- // checkbusy();
- RS=1;
- RW=0;
- E=1;
- P0=dat;
- delay(20);
- E=0;
- }
- /****************************************************/
- /*********************設置頁與列*********************/
- void set(uchar page,uchar col)
- {
- page=page|0xb8; //頁的首地址為0xb8
- col=col|0x40; //列的首地址為0x40
- write_cmd(col);
- write_cmd(page);
- }
- /****************************************************/
- /*******************選擇左、右屏*********************/
- void Select_Screen(uchar swich)
- {
- switch(swich)
- {
- case 0:CS1=CS2=0;break; //全屏
- case 1:CS1=0;CS2=1;break; //左屏
- case 2:CS1=1;CS2=0;break; //右屏
- default:break;
- }
- }
- /***************************************************/
- /********************LCD初始化**********************/
- void Lcd_Init()
- {
- uchar i,j,k=0;
- RST=0;
- delay(10);
- RST=1;
- write_cmd(0xc0);//設置顯示起始行11xxxxxx
- write_cmd(0x3f);//0x3f顯示開,0x3e顯示關
- Select_Screen(0);
- set(0,0);
- for(i=0;i<8;i++)
- {
- for(j=0;j<64;j++)
- write_dat(0x00);
- k++;
- set(k,0);
- }
- lie=2;hang=3;keyfun=0;
- dat1=0.0,dat2=0.0,count=0.0;
- }
- /*****************************************************/
- /********************計算窗口清空*********************/
- void Clear_jisuan()
- {
- uchar i,j;
- Select_Screen(0);
- for(i=3;i<6;i++) //從第三頁開始寫入數(shù)據(jù)0x00,清空計算窗口
- {
- for(j=0;j<64;j++)
- {
- set(i,j);
- write_dat(0x00);
- }
- }
- lie=2;hang=3;keyfun=0;
- dat1=0.0,dat2=0.0,count=0.0;
- }
- /**************************************************/
- /********************顯示字符**********************/
- void Display_zifu(uchar n)
- {
- uchar i; //列數(shù)小于64時
- if(lie<64)
- {
- Select_Screen(1); //開左屏
- set(hang,lie); //設置行,列
- for(i=0;i<6;i++)
- write_dat(zifu[n++]); //寫入數(shù)據(jù)
- lie=lie+7; //每輸出一個字符列數(shù)加6
- if(hang>7) //行數(shù)大于7時回到初始值
- hang=3;
- }
- else //列數(shù)大于64時
- {
- Select_Screen(2);
- set(hang,lie-64);
- for(i=0;i<6;i++)
- write_dat(zifu[n++]);
- lie=lie+7;
- if(lie>123)
- {
- lie=0;hang++;
- Select_Screen(1);
- }
- if(hang>7)
- hang=3;
- }
- }
- /******************************************************/
- /***********將運算結果轉化為字符串而后顯示*************/
- void Display_string(uchar page,uchar col,float num)
- {
- uchar str[20];
- uchar tmp[16],i,j,k,c;
- int len;
- if((int)num==(int)(num+0.99999))//如果為整數(shù)
- {
- sprintf(str,"%d",(int)num); //將結果轉化為字符串
- len=sprintf(str,"%d",(int)num); //sprintf函數(shù)的返回值為字符串的長度,不含'/0'
- }
- else //如果為小數(shù)
- {
- sprintf(str,"%.3f",num); //將結果轉化為字符串
- len=sprintf(str,"%.3f",num);
- }
-
- if(col>63) //列數(shù)大于63開右屏
- {
- Select_Screen(2);
- col=col-64;
- }
-
- for(i=0;i<len;i++) //將字符串逐個顯示
- {
- if(col<63) //列數(shù)小于63開左屏
- {Select_Screen(1);}
- c=(str[i]-42)*6; //數(shù)組第一行*號的ASCII值為42,每個數(shù)組中的相應元素減去42得到其在數(shù)組中的行數(shù)
- for(j=0;j<10;j++)
- {tmp[j]=zifu[c];} //將數(shù)組zifu相應字符的ASCII碼輸送給數(shù)組tmp
- set(page,col);
- for(k=0;k<6;k++)
- write_dat(zifu[c++]); //寫入數(shù)據(jù)
-
- col=col+6; //每寫一個字符列數(shù)加6,繼續(xù)寫入下一個字符
- delay(100);
- }
- }
- /*****************************************************/
- /***********************顯示漢字**********************/
- void Display_Project(uchar screen,uchar page,uchar col,uchar n,uchar table[][32])
- {
- uchar i,temp[32];
- for(i=0;i<16;i++) //將table數(shù)組中的相應漢字的ascii碼輸送給數(shù)組temp
- temp[i]=table[n][i];
- for(i=16;i<32;i++)
- temp[i]=table[n][i];
-
- Select_Screen(screen);
- set(page,col);
- for(i=0;i<16;i++) //寫漢字的上半部分
- write_dat(temp[i]);
-
- set(page+1,col);
- for(i=0;i<16;i++) //寫漢字的下半部分
- write_dat(temp[i+16]);
- }
- /***********************************************************/
- /******************** 響鈴 *********************************/
- //void play()
- //{
- //
- // BEEP=0;
- // delay_ms(1000);
- // BEEP=1;
- //
- //}
- /***********************************************************/
- /********************選擇計算類型***************************/
- float calulate()
- {
- switch(keyfun)
- {
- case 1: count=dat2*dat1;dat1=count;break;
- case 2: count=dat2+dat1;dat1=count;break;
- case 3: count=dat2-dat1;dat1=count;break;
- case 4: count=dat2/dat1;dat1=count;break;
- default: break;
- }
- return(count);
- }
- /********************************************************/
- /***********************計算過程*************************/
- void cal_process()
- {
- uchar str_mul[10],len_mul;
- if(x!=19)
- {Display_zifu(x*6);}
- while((P3&0xf0)!=0xf0); //按鍵按下有效,顯示刷新
-
- switch(keynum)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9: dat1=dat1*10+keynum;break; //例如:輸入12,初始dat1=0;則dat1=0*10+1=1;dat1=1*10+2=12
- /* * */ case 10:calulate();dat2=dat1;dat1=0;keyfun=1;break;
-
- /* + */ case 11:calulate();dat2=dat1;dat1=0;keyfun=2;break;
-
- /* - */ case 12:calulate();dat2=dat1;dat1=0;keyfun=3;break;
-
- /* / */ case 13:calulate();dat2=dat1;dat1=0;keyfun=4;break;
-
- /* = */ case 14:hang=5;lie=0;Display_zifu(19*6);
- switch(keyfun)
- {
- case 1: count=dat2*dat1;break;
- case 2: count=dat2+dat1;break;
- case 3: count=dat2-dat1;break;
- case 4: count=dat2/dat1;break;
- default:break;
- }
- if(count<999999999)
- {
- if(keyfun==1)
- {
- if((len_mul=sprintf(str_mul,"%d",count))<8) //多位整數(shù)乘法若結果大于6則顯示?
- Display_string(5,6,count);
- }
- else if(keyfun==4)
- {
- if(dat1!=0) //除數(shù)為0則輸出?
- Display_string(5,6,count);
- }
- else
- Display_string(5,6,count);
- }
-
- else Display_zifu(20*6);break;
- default: break;
- }
- }
- /********************************************************/
- /*****************矩陣按鍵掃描(逐行掃描)*****************/
- void keyscan()
- {
- uchar key;
- P3=0xfe; //令第一行為0,判斷列
- if(P3!=0Xfe)
- {
- delay(100); //消抖
- if(P3!=0xfe)
- {
- key=P3&0xf0;
- switch(key)
- {
- case 0xe0:keynum=7; x=13;cal_process();break; // 7
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
計算器12864帶字.rar
(139.63 KB, 下載次數(shù): 195)
2021-3-23 21:08 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|