導航:首頁 > 操作系統 > 個位數計算器設計單片機

個位數計算器設計單片機

發布時間:2024-01-04 01:39:45

A. 基於51單片機的簡易計算器設計,急

//功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零 表3-1 3.2 計算器的軟體設計

#include<reg51.h> //頭文件

#define uint unsigned int //

#define uchar unsigned char

sbit lcden=P2^3; //定義引腳

sbit rs=P2^4;

sbit rw=P2^0;

sbit busy=P0^7;

char i,j,temp,num,num_1;

long a,b,c; //a,第一個數 b,第二個數 c,得數

float a_c,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 code table1[]={

7,8,9,0x2f-0x30,

4,5,6,0x2a-0x30,

1,2,3,0x2d-0x30,

0x01-0x30,0,0x3d-0x30,0x2b-0x30};

void delay(uchar z) // 延遲函數

{

uchar y;

for(z;z>0;z--)

for(y=0;y<110;y++);

} void check() // 判斷忙或空閑

{

do{

P0=0xFF;

rs=0; //指令

rw=1; //讀

lcden=0; //禁止讀寫

delay(1); //等待,液晶顯示器處理數據

lcden=1; //允許讀寫

}while(busy==1); //判斷是否為空閑,1為忙,0為空閑

}

void write_com(uchar com) // 寫指令函數

{

P0=com; //com指令付給P0口

rs=0;

rw=0;

lcden=0;

check();

lcden=1;

}

void write_date(uchar date) // 寫數據函數

{

P0=date;

rs=1;

rw=0;

lcden=0;

check();

lcden=1;

}

void init() //初始化

{

num=-1;

lcden=1; //使能信號為高電平

write_com(0x38); //8位,2行

write_com(0x0c); //顯示開,游標關,不閃爍*/

write_com(0x06); //增量方式不移位 顯竟獗暌貧 柚?

write_com(0x80); //檢測忙信號

write_com(0x01); //顯示開,游標關,不閃爍

num_1=0;

i=0;

j=0;

a=0; //第一個參與運算的數

b=0; //第二個參與運算的數

c=0;

flag=0; //flag表示是否有符號鍵按下,

fuhao=0; // fuhao表徵按下的是哪個符號

}

void keyscan() // 鍵盤掃描程序

{

P3=0xfe;

if(P3!=0xfe)

{

delay(20); //延遲20ms

if(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!=0)

{

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(5);

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&&num!=7)//如果按下的是'4','5'或'6'

{

if(j!=0)

{

write_com(0x01);

j=0;

}

if(flag==0)//沒有按過符號鍵

{

a=a*10+table[num];

}

else//如果按過符號鍵

{

b=b*10+table[num];

}

}

else//如果按下的是'/'

{

flag=1;

fuhao=3;//3表示乘號已按

}

i=table1[num];

write_date(0x30+i);

}

P3=0xfb; if(P3!=0xfb)

{

delay(5);

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!=0)

{

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(5);

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

P1=0;

}

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

else

c=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)

write_date(0x2e);

}

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();

}

}

B. 用單片機怎麼做計算器

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/1114.0等價於(123+321) / 111
2.3+5.4=/0.1+77等號後直接按 / ,則將前面的運算結果作為第一個
操作數
1/0=E錯誤顯示

9. 不足 使用3位元組的浮點數表示,不可避免的帶來了數表示的不精確,加上有效數字比較少,因此計算結果很容易產生誤差,尤其是進行連續多次運算後,結果和精度較高的科學計算器的誤差會很快達到0.01以上,當然這個差距和所測試的用例也有關系,4位有效數字導致了數字123456隻能表示為123400,最後兩位有效數字被摒棄了。 同時,雖然純整數可以進行較為高精度的運算,實現也較為容易,但是考慮到要和浮點數混合在一起處理,如果在演算法上分別考慮整數和浮點數,整個程序框架代碼將會膨脹不少,因此將其簡化為統一作為浮點數對待。

我這里有一個類似的程序;簡單的計算器演示程序 硬體連接:矩陣鍵盤接p1口1602液晶控制p2.0-2.2 液晶數據p0 *;0-99之間的加、減、乘、除運算 *; 0a鍵+ 0b鍵- 0c鍵* 0#鍵/ 0#鍵清除 00鍵 等於 *;矩陣鍵盤定義: *;P1.0-P1.3為列線,P1.4-P1.7為行線 *;出口:A、R3存鍵值 * RELAY EQU P1.3 BEEP EQU P3.7;------------------------------- RS EQU P2.0 RW EQU P2.1 EN EQU P2.2 X EQU 3fH ;LCD 地址變數;------------------------------- TEMP1 EQU 30H ;臨時暫存器 TEMP2 EQU 31H TEMP3 EQU 32H TEMP4 EQU 33H RES_H EQU 24H ;輸入被加(減、乘、除)數 RES_L EQU 25H ;輸入加(減、乘、除)數 OUT_H EQU 26H ;運算結果高位 OUT_L EQU 27H ;運算結果低位;------------------------------- ORG 0000H JMP MAIN;-------------------------------MAIN: MOV SP,#60H CLR EN CALL SET_LCD MOV 20H,#00H CALL BEEP_BL ;起延時作用 MOV R1,#00H MOV TEMP1,#00H MOV TEMP2,#00H MOV TEMP3,#00H MOV RES_L,#00H MOV RES_H,#00H MOV OUT_H,#00H MOV OUT_L,#00HLOOP: CALL KEY_IN ;送被(加、減、乘、除)數 JNB 20H.0,LOOP ;鍵標記 CALL BEEP_BL INC R1 CJNE R1,#01H,LOOP_1 MOV TEMP2,A ;高位 MOV X,#2 CALL CONV0LOOP_1: CJNE R1,#02H,LOOP SUBB A,#0AH ;判是否是功能鍵? JNC LOOP_2 ;是,轉LOOP_2 MOV TEMP1,TEMP2 MOV A,TEMP1 MOV X,#1 CALL CONV0 MOV A,R3 ;恢復有效鍵值 MOV TEMP2,A ;低位 MOV X,#2 CALL CONV0 MOV A,TEMP1 ANL A,#0FH SWAP A ORL A,TEMP2 MOV RES_H,A JMP LOOP0LOOP_2: MOV RES_H,TEMP2 AJMP LOOP0ALOOP0: CALL KEY_IN JNB 20H.0,LOOP0 CALL BEEP_BLLOOP0A: MOV A,R3 ;重裝鍵值 CJNE A,#0AH,LOOP1 ;加運算 CALL CONV1 SETB 20H.1 ;加運算標記 AJMP LOOP5LOOP1: CJNE A,#0BH,LOOP2 ;減運算 CALL CONV2 SETB 20H.2 ;減運算標記 AJMP LOOP5LOOP2: CJNE A,#0CH,LOOP3 ;乘運算 CALL CONV3 SETB 20H.3 ;乘運算標記 AJMP LOOP5LOOP3: CJNE A,#0DH,LOOP4 ;除運算 CALL CONV4 SETB 20H.4 ;除運算標記 AJMP LOOP5LOOP4: CJNE A,#0FH,LOOP4A AJMP MAIN LOOP4A: AJMP LOOP0LOOP5: MOV R1,#00H MOV TEMP1,#00H MOV TEMP2,#00H CLR 20H.0 ;送(加、減、乘、除)數LOOP5A: CALL KEY_IN JNB 20H.0,LOOP5A CALL BEEP_BL CJNE A,#0FH,LOOP5B AJMP MAINLOOP5B: INC R1 CJNE R1,#01H,LOOP5C MOV TEMP2,A MOV X,#6 CALL CONV0LOOP5C: CJNE R1,#02H,LOOP5A SUBB A,#0AH ;判是否是功能鍵? JNC LOOP5D ;是,轉LOOP5C MOV TEMP1,TEMP2 MOV A,TEMP1 MOV X,#6 CALL CONV0 MOV A,R3 MOV TEMP2,A MOV X,#7 CALL CONV0 MOV A,TEMP1 ANL A,#0FH SWAP A ORL A,TEMP2 MOV RES_L,A JMP LOOP6LOOP5D: MOV RES_L,TEMP2 JMP LOOP6ALOOP6: CALL KEY_INLOOP6A: MOV A,R3 ;重裝鍵值 CJNE A,#0FH,LOOP6B AJMP MAINLOOP6B: CJNE A,#0EH,LOOP6 ;顯示(=) CALL CONV5 CALL BEEP_BL ;顯示運算結果 JNB 20H.1,LOOP6C CALL SUADDLOOP6C: JNB 20H.2,LOOP6D CALL SUSUBLOOP6D: JNB 20H.3,LOOP6E CALL SUMULLOOP6E: JNB 20H.4,LOOP7 CALL SUDIVLOOP7: CALL KEY_IN CJNE A,#0FH,LOOP7 ;復位(清零) AJMP MAIN;------------------------;加法運運算元程序;入口:R0-被加數,R1-加數;出口:R4(高)、R2(低)為和值;------------------------SUADD: MOV R1,RES_L MOV R0,RES_H MOV A,R0 ADD A,R1 DA A MOV R2,A CLR A ADDC A,#00H MOV R4,A MOV OUT_H,R4 MOV OUT_L,R2 CALL T_CONV RET;------------------------;減法運運算元程序;入口:R0-被減數,R1-減數;出口:R2-差值;------------------------SUSUB: MOV R1,RES_L MOV R0,RES_H CLR C MOV A,#9AH SUBB A,R1 ;減數十進制求補 ADD A,R0 DA A MOV R2,A ;差值送R2 JC POSI ;C=1,表示差值為正 NEGA: MOV A,#9AH ;差值為負,求補後得差值的絕對值 SUBB A,R2 MOV R2,A SETB 20H.5 ;顯示負號標記 POSI: MOV OUT_H,#00H MOV OUT_L,R2 CALL T_CONV RET;-------------------------;乘法運運算元程序; 單位元組BCD碼乘法子程序;入口: R0(被乘數)、R1(乘數);出口: R3(高)、R2(低),積為雙位元組,BCD碼形式的積;從乘數高位開始進行BCD碼移位乘法;-------------------------SUMUL: MOV R1,RES_L MOV R0,RES_HBCDMUL: CLR A ;積單元清零 MOV R2,A MOV R3,A MOV A,R1 JZ RETURN ANL A,#0F0H ;取乘數高位 JZ LBCD ;乘數高位是否為0? SWAP A MOV R4,A ACALL DDBCDM SWAP A ;BCD碼左移一位 MOV R3,A MOV A,R2 SWAP A MOV R2,A ANL A,#0FH ORL A,R3 MOV R3,A MOV A,R2 ANL A,#0F0H MOV R2,A LBCD: MOV A,R1 ;取乘數低位 ANL A,#0FH JZ RETURN ;乘數低位是否為0? MOV R4,A ACALL DDBCDMRETURN: MOV OUT_H,R3 MOV OUT_L,R2 CALL T_CONV RETDDBCDM: ;一位BCD碼乘法 MOV A,R2 ADD A,R0 DA A MOV R2,A MOV A,R3 ADDC A,#00H DA A MOV R3,A DJNZ R4,DDBCDM RET;------------------------------------------------;除法運運算元程序;單位元組BCD碼除法;入口:R0(被除數)、R1(非零除數);出口:R2(商)、R3(余數);《MCS-51系列單片機實用子程序集錦》Page 73;-----------------------------------------------SUDIV: MOV R1,RES_L MOV R0,RES_HBCDDIV: MOV R2,#00H ;商單元清零 MOV A,R1 ;除數求補 CPL A ADD A,#9BH MOV R1,A MOV A,R0 ;被除數高位移入 ANL A,#0F0H ;部分余單元 SWAP A LP0: MOV R3,A ;做除法 ADD A,R1 DA A JNC LP1 ;部分余數>=除數? INC R2 ;商加1 SJMP LP0 LP1: MOV A,R3 ; SWAP A MOV R3,A MOV A,R2 ;商左移一位 SWAP A MOV R2,A MOV A,R0 ;移位 ANL A,#0FH ORL A,R3 LP2: MOV R3,A ;做除法 ADD A,R1 DA A JNC LP3 INC R2 ;商加1 SJMP LP2 LP3: MOV A,R3 ;四舍五人 ADD A,R3 DA A JC LP4 ADD A,R1 DA A JNC RETURN1 LP4: MOV A,R2 ADDC A,#00H DA A MOV R2,A RETURN1: MOV OUT_H,#00H MOV OUT_L,R2 CALL T_CONV RET;-----------------------------------------------------; LCD 初始化設置;-----------------------------------------------------SET_LCD: CLR EN CALL INIT_LCD ;初始化 LCD CALL DELAY1 MOV DPTR,#INFO1 ;指針指到顯示信息1 MOV A,#1 ;顯示在第一行 CALL LCD_SHOW MOV DPTR,#INFO2 ;指針指到顯示信息2 MOV A,#2 ;顯示在第二行 CALL LCD_SHOW RET;-----------------------------------------------------INFO1: DB " CALCULATOR ",0 ;LCD 第一行顯示信息INFO2: DB " ",0 ;LCD 第二行顯示信息;----------------------------------------------------INIT_LCD: ;8位I/O控制 LCD 介面初始化 MOV A,#38H ;雙列顯示,字形5*7點陣 CALL WCOM CALL DELAY1 MOV A,#38H ;雙列顯示,字形5*7點陣 CALL WCOM CALL DELAY1 MOV A,#38H ;雙列顯示,字形5*7點陣 CALL WCOM CALL DELAY1 MOV A,#0CH ;開顯示,關游標, CALL WCOM CALL DELAY1 MOV A,#01H ;清除 LCD 顯示屏 CALL WCOM CALL DELAY1 RET;----------------------------------------------------LCD_SHOW: ;在LCD的第一行或第二行顯示信息字元
CJNE A,#1,LINE2 ;判斷是否為第一行 LINE1: MOV A,#80H ;設置 LCD 的第一行地址 CALL WCOM ;寫入命令 CALL CLR_LINE ;清除該行字元數據 MOV A,#80H ;設置 LCD 的第一行地址 CALL WCOM ;寫入命令 JMP FILL LINE2: MOV A,#0C0H ;設置 LCD 的第二行地址 CALL WCOM ;寫入命令 CALL CLR_LINE ;清除該行字元數據 MOV A,#0C0H ;設置 LCD 的第二行地址 CALL WCOM FILL: CLR A ;填入字元 MOVC A,@A+DPTR ;由信息區取出字元 CJNE A,#0,LC1 ;判斷是否為結束碼 RET LC1: CALL WDATA ;寫入數據 INC DPTR ;指針加1 JMP FILL ;繼續填入字元 RET ;---------------------------------------------------CLR_LINE: ;清除該行 LCD 的字元 MOV R0,#24 CL1: MOV A,#' ' CALL WDATA DJNZ R0,CL1 RET;-----------------------------------------------------; 寫指令、數據使能子程序;-----------------------------------------------------WCOM: ;寫指令使能 MOV P0,A CLR RS ;RS=L,RW=L,D0-D7=指令碼,E=高脈沖 CLR RW SETB EN CALL DELAY0 CLR EN RETWDATA: ;寫數據使能 MOV P0,A SETB RS ;RS=H,RW=L,D0-D7=數據,E=高脈沖 CLR RW SETB EN CALL DELAY0 CLR EN RET
DELAY0: MOV R7,#250 ;延時500微秒 DJNZ R7,$ RET;---------------------------------------------------;在 LCD 第二行顯示字元;A=ASC DATA, B=LINE X POS;---------------------------------------------------LCDP2: ;在LCD的第二行顯示字元 PUSH ACC ; MOV A,B ;設置顯示地址 ADD A,#0C0H ;設置LCD的第二行地址 CALL WCOM ;寫入命令 POP ACC ;由堆棧取出A CALL WDATA ;寫入數據 RET;-----------------------------------------------------;矩陣鍵盤鍵值讀取子程序;-----------------------------------------------------KEY_IN: MOV P1,#0F0H ;置列線為0,行線為1 MOV A,P1 ANL A,#0F0H MOV B,A MOV P1,#0FH ;置列線為1,行線為0 MOV A,P1 ANL A,#0FH ORL A,B ;高四位與低四位重新組合 CJNE A,#0FFH,KEY_IN1 ;0FFH為末按鍵 CLR 20H.0 RETKEY_IN1: MOV B,A MOV DPTR,#KEYTABLE MOV R3,#0FFHKEY_IN2: INC R3 MOV A,R3 MOVC A,@A+DPTR CJNE A,B,KEY_IN3 MOV A,R3 ;找到,取順序碼 MOV R5,#08H ;延時 CALL DELAY SETB 20H.0 RETKEY_IN3: CJNE A,#0FFH,KEY_IN2 ;末完,繼續查 RET ;0FFH為結束碼;------------------------;在指定位置顯示符合子程序;------------------------CONV0: add A,#30h MOV B,X CALL LCDP2 retCONV1: MOV X,#4 MOV A,#2BH ;+ MOV B,X CALL LCDP2 RET
CONV2: MOV X,#4 MOV A,#2DH ;- MOV B,X CALL LCDP2 RETCONV3: MOV X,#4 MOV A,#2AH ;* MOV B,X CALL LCDP2 RETCONV4: MOV X,#4 MOV A,#2FH ;/ MOV B,X CALL LCDP2 RETCONV5: MOV X,#09H MOV A,#3DH ;= MOV B,X CALL LCDP2 RET;--------------------------;;--------------------------CONV: MOV A,R3 ANL A,#0FH ;取出低四位二進制數 PUSH ACC ;壓入堆棧 CLR C ;C=0 SUBB A,#0AH ;減10 POP ACC ;彈出堆棧 JC ASCII0 ;該數小於10,轉ASCII0 JMP ASCII1 ASCII0: ADD A,#30H ;小於10的數加上30H MOV B,X CALL LCDP2ASCII1: RET
;-------------------------------------------------------T_CONV:
MOV A,OUT_H ;取高位數 mov x,#11 cjne a,#00h,t_conv1 ;判高位數是否為0? setb 20h.6 ;為0,20h.6置1 jmp t_conv3 ;轉取低位數 ;高位數不為0,則t_conv1: anl a,#0f0h ;判高位數的高四位是否為0? cjne a,#00h,t_conv2 ;不為0,2位數都顯示 setb 20h.6 ;為0,20h.6置1,只顯示低四位t_conv2: mov a,out_h CALL SHOW_DIG2 inc x clr 20h.6 ;清顯示標記位
t_conv3: mov a,out_l ;取低位數 jnb 20h.6,t_conv5 ;高位數有顯示,則不判低位數。 anl a,#0f0h ;高位數無顯示,則判低位數。 cjne a,#00h,t_conv4 ;判低位數的高四位是否為0? setb 20h.6 ;為0,20h.6置1,只顯示低四位 MOV A,OUT_L JMP T_CONV5T_conv4: CLR 20H.6 ;低位數不為0,2位數都顯示 mov a,out_l
t_conv5: call show_dig2 clr 20h.6 ;清顯示標記位 RET;----------------------------;在 LCD 的第二行顯示數字與符號;----------------------------SHOW_DIG2: JNB 20H.5,DIG2 ;符號標記 MOV TEMP3,A MOV A,#2DH ;顯示負號 MOV B,X CALL LCDP2 MOV A,TEMP3 INC X DIG2: MOV B,#16 ;設置被除數 DIV AB ;結果A存商數,B存余數 jnb 20h.6,dig3 ;顯示位標記 mov a,#20h jmp dig4dig3: ADD A,#30H ;A為十位數,轉換為字元dig4: PUSH B ;B放入堆棧暫存 MOV B,X ;設置 LCD 顯示的位置 CALL LCDP2 ;由 LCD 顯示出來 POP B ; MOV A,B ;B為個位數 ADD A,#30H ;轉換為字元 INC X ;LCD 顯示位置加1 MOV B,X ;設置 LCD 顯示的位置 CALL LCDP2 ;由 LCD 顯示出來 RET;--------------------------------------------------------;蜂鳴器響一聲子程序;--------------------------------------------------------BEEP_BL: MOV R6,#100 BL1: CALL DEX1 CPL BEEP DJNZ R6,BL1 MOV R5,#50 CALL DELAY RET DEX1: MOV R7,#180 DEX2: NOP DJNZ R7,DEX2 RETDELAY: ;延時R5×10MS MOV R6,#50 D1: MOV R7,#100 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,DELAY RET;-----------------------------------------------------DELAY1: ;延時5MS MOV R6,#25 D2: MOV R7,#100 DJNZ R7,$ DJNZ R6,D2 RET;-----------------------------------------------------KEYTABLE: DB 0eeH ,077H,0B7H,0D7H,07bh,0bbh,0dbh ,07dh,0bdh,0ddh,0e7h,0ebh,0edh, 07eh,0beh,0deh,0ffH;----------------------------------------------------- END

C. 51單片機鍵盤矩陣實現個位加法計算器,用c編程

KEYBUF
EQU
40H
;鍵號存放單元
ORG
0000H
LJMP
MAIN
ORG
0030H
MAIN:
MOV
KEYBUF,#0
;初始鍵號設位0,也可以為任意值
MOV
R0,#30H
;顯示首地址
MOV
R2,#0CH
;計算數據存放單元個數
CLR
A
QING:
MOV
@R0,A
;將數據存放單元清零
INC
R0
DJNZ
R2,QING
MOV
P0,#8FH
;關閉顯示
MOV
R1,#30H
;將顯示首地址存放R1里

D. 單片機簡單C語言問題,實現一個個位加法計算器

你的問題應該出現在鍵盤處理不完善造成的,稍微修改了一下你試試。
#include <reg52.h>
#define uchar unsigned char
#define unit unsigned int
#define OPdata P0 //十位數據口
#define OPdata1 P1//個位數據口
sbit se0=P3^6;//十位選擇
sbit se1=P3^7;//個位選擇
sbit Q=P2^6;
sbit W=P2^5;
sbit E=P2^4;
uchar cis; //按下鍵盤次數
uchar jia1; //加數1
uchar jia2; //加數2
uchar z; //中轉數
uchar shi; //十位數
uchar ge; //個位數
uchar s; //解碼結果
uchar j; //解碼結果
uchar sum; //加法結果
uchar keytemp;
void judge(uchar m) //數碼顯像管解碼
{
switch (m)
{
case 0: s=0x3F; break;
case 1: s=0x06; break;
case 2: s=0x5B; break;
case 3: s=0x4F; break;
case 4: s=0x66; break;
case 5: s=0x6D; break;
case 6: s=0x7D; break;
case 7: s=0x07; break;
case 8: s=0x7F; break;
case 9: s=0x6F; break;
}
}
void judge1(uchar h) //十位數碼顯像管解碼
{
switch (h)
{
case 0: j=0x3F; break;
case 1: j=0x06; break;
}
}
void judgecis()
{
if (cis==1)
{
jia1=z;
ge=z;
shi=0;
}
else if (cis==2)
{
jia2=z;
ge=z;
shi=0;
cis=0;
}
}
void jiafa(uchar m,uchar n) //加法
{
sum=m+n;
if (sum>=10)
{
ge=sum-10;
shi=1;
}
else
{
ge=sum;
shi=0;
}
}

void main()
{
cis=0;
jia1=0;
jia2=0;
shi=0;
ge=0;
s=0;
j=0;
P2=0XFF;
se0=0;//開啟十位
se1=0;//開啟個位
OPdata=0x3f;//十位
OPdata1=0x3f;//個位
while (1)
{
Q=0;
keytemp=P2;
switch (keytemp)
{
case 0xbb: z=3; cis++;while(P2==0xbb); break;
case 0xbd: z=6; cis++;while(P2==0xbd); break;
case 0xbe: z=9; cis++;while(P2==0xbe); break;
case 0xb7: //等於號
jiafa (jia1,jia2); cis=0; break;
}
Q=1;
W=0;
keytemp=P2;
switch (keytemp)
{
case 0xde: z=8; cis++;while(P2==0xde); break;
case 0xdd: z=5; cis++;while(P2==0xdd); break;
case 0xdb: z=2; cis++;while(P2==0xdb); break;
case 0xd7: z=0; cis++;while(P2==0xd7); break;
}
W=1;
E=0;
keytemp=P2;
switch (keytemp)
{
case 0xee: z=7; cis++;while(P2==0xee); break;
case 0xed: z=4; cis++;while(P2==0xed); break;
case 0xeb: z=1; cis++;while(P2==0xeb); break;
}
judgecis();
judge(ge);
OPdata1=s;
judge1(shi);
OPdata=j;
E=1;
}
}

E. 怎樣用51單片機做計算器啊

1、硬體模擬圖

4、程序源代碼

#include <reg51.h>#include <intrins.h>

#include <ctype.h>

#include <stdlib.h>

#define uchar unsigned char

#define uint unsigned int

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

P1 = 0xfe;

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)

;

}

}

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;

default: skey = '#';

}

while((P1 & 0xf0) != 0xf0)

;

}

}

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)

;

}

}

P1 = 0xf7;

while((P1 & 0xf0) != 0xf0)

{

delay(3);

while((P1 & 0xf0) != 0xf0)

{

switch(P1)

{

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;

uchar ckey, cut1 = 0, cut2 = 0;

uchar operator;

uchar i, bool = 0;

init:

buf(0);

disp();

value = 0;

cut1 = cut2 = 0;

bool = 0;

for(i = 0;i < 9;i++)

{

operand1[i] = '';

operand2[i] = '';

}

while(1)

{

ckey = keyscan();

if(ckey != '#')

{

if(isdigit(ckey))

{

switch(bool)

{

case 0:

operand1[cut1] = ckey;

operand1[cut1+1] = '';

value1 = atoi(operand1);

cut1++;

buf(value1);

disp();

break;

case 1:

operand2[cut2] = ckey;

operand2[cut2+1] = '';

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();

}

else if(ckey == '=')

{

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;

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;

}

else

for(i = 7; val > 0; i--)

{

dbuf[i] = val % 10;

val /= 10;

}

for( ; i > 0; i--)

dbuf[i] = 10;

}

void disp(void)

{

uchar bsel, n;

bsel=0x01;

for(n=0;n<8;n++)

{

P2=bsel;

P0=table[dbuf[n]];

bsel=_crol_(bsel,1);

delay(3);

P0=0xff;

}

}

(5)個位數計算器設計單片機擴展閱讀:

PROTEUS 是單片機課堂教學的先進助手

PROTEUS不僅可將許多單片機實例功能形象化,也可將許多單片機實例運行過程形象化。前者可在相當程度上得到實物演示實驗的效果,後者則是實物演示實驗難以達到的效果。

它的元器件、連接線路等卻和傳統的單片機實驗硬體高度對應。這在相當程度上替代了傳統的單片機實驗教學的功能,例:元器件選擇、電路連接、電路檢測、電路修改、軟體調試、運行結果等。

課程設計、畢業設計是學生走向就業的重要實踐環節。由於PROTEUS提供了實驗室無法相比的大量的元器件庫,提供了修改電路設計的靈活性、提供了實驗室在數量、質量上難以相比的虛擬儀器、儀表,因而也提供了培養學生實踐精神、創造精神的平台

隨著科技的發展,「計算機模擬技術」已成為許多設計部門重要的前期設計手段。它具有設計靈活,結果、過程的統一的特點。可使設計時間大為縮短、耗資大為減少,也可降低工程製造的風險。相信在單片機開發應用中PROTEUS也能茯得愈來愈廣泛的應用。

使用Proteus 軟體進行單片機系統模擬設計,是虛擬模擬技術和計算機多媒體技術相結合的綜合運用,有利於培養學生的電路設計能力及模擬軟體的操作能力;

在單片機課程設計和全國大學生電子設計競賽中,我們使用 Proteus開發環境對學生進行培訓,在不需要硬體投入的條件下,學生普遍反映,對單片機的學習比單純學習書本知識更容易接受,更容易提高。

實踐證明,在使用 Proteus 進行系統模擬開發成功之後再進行實際製作,能極大提高單片機系統設計效率。因此,Proteus 有較高的推廣利用價值。

F. 單片機簡易計算器設計的程序

首先會按鍵掃描,再會數碼管或液晶屏顯示,基本上可以了
程序 流程: 掃描按鍵(最多5次,最大65536,簡易計算器嗎)獲得一個數,再掃描按鍵獲得加減乘除符號 掃描按鍵獲得另一個數 掃描按鍵獲得「=」,顯示計算結果
由於程序比較長,且與硬體有關,因此只貼出主程序:
void main()
{ while(1)
{
c=1;
while(c<6)//輸入第1個5 位數
{
keyval=keyscan();
if(keyval<10)
{
switch(c)
{
case 1:b1=keyval; break;
case 2:b2=keyval; break;
case 3:b3=keyval; break;
case 4:b4=keyval; break;
case 5:b5=keyval; break;
}
c++;
}
display1(b1,b2,b3,b4,b5);
}

while(c==6) //輸入計算符號
{
keyval=keyscan();
if((keyval>=10)&&(keyval<14)) //10-13代表加減乘除 4種符號
{
d=keyval;
}
c=1;
display3(d);

}
while(c<6) //輸入第2個5 位數
{
keyval=keyscan();
if(keyval<10)
{
switch(c)
{
case 1:d1=keyval; break;
case 2:d2=keyval; break;
case 3:d3=keyval; break;
case 4:d4=keyval; break;// 除
case 5:d5=keyval; break;
}
c++;
}
display2(d1,d2,d3,d4,d5);
}

bb= b1*10000+b2*1000+b3*100+b4*10+b5;//5個按鍵數值合成一個數
dd=d1*10000+d1*1000+d3*100+d4*10+d5; //另外5個按鍵數值也合成一個數
while(keyval!=14) //等待按下"="
{
keyval=keyscan();
}
Delay1ms(10);
switch(d)
{
case 10:ee=bb+dd; break;//+
case 11:
flag1=1;//結果是負數的標志,先假定是負數
if(bb>=dd)
{
ee=bb-dd; //結果不是負數
flag1=0;
}
else ee=dd-bb; //減數和被減數交換
break;

case 12:ee=bb*dd; break;//*可能會溢出
case 13:ee=bb/dd; //除法小數部分會丟失,保留2位
ff=bb%dd;
fd1=ff*10/dd;
fd2=ff*100/dd%10;
break;
}
f10=ee/1000000000%10;
f9=ee/100000000%10;
f8=ee/10000000%10;
f7=ee/1000000%10;
f6=ee/100000%10;
f5=ee/10000%10;
f4=ee/1000%10;
f3=ee/100%10;
f2=ee/10%10;
f1=ee%10;
display4(f10,f9,f8,f7,f6,f4,f4,f3,f2,f1,fd1,fd2);

while(keyval!=15)
{
keyval=keyscan();
}
b1=0;b2=0;b3=0;b4=0;b5=0;
d1=0;d2=0;d3=0;d4=0;d5=0;
bb=0;dd=0;ee=0;
init2();
}
}

G. 00-99計數器設計。 利用單片機來製作一個手動計數器,還有模擬圖,謝謝

ORG 0000H

JMP BEGIN

ORG 0030H

TABLE: ; 共陰極數碼管顯示代碼表

DB 3FH,06H,5BH,4FH,66H ;01234

DB 6DH,7DH,07H,7FH,6fh ;56789

;---------------------------------------

BEGIN: MOV P0,#0 ;數碼管初始化,不顯示

MOV P1,#0 ;數碼管初始化,不顯示

MOV 30H,#0 ;數據初始化為0

LOOP:

JB P3.2,LOOP1 ;加1鍵如果未按下轉LOOP1

JNB P3.2,$ ;鍵被按下,等待鍵抬起

INC 30H ;數據加1

LCALL DIS ;顯示

SJMP LOOP ;會循環起點

LOOP1:

JB P3.6,LOOP ;清零鍵如果未按轉循環起點

JNB P3.6,$ ;鍵被按下等待按鍵抬起

MOV 30H,#0 ;數據清零

LCALL DIS ;顯示

SJMP LOOP ;會循環起點

DIS:

MOV A,30H ;數據送A

CJNE A,#100,DIS1

CLR A

MOV 30H,A

DIS1:

MOV B,#10 ;除數送B

DIV AB ;除法運算

MOV 32H,A ;十位數送32H

MOV 33H,B ;個位數送33H

MOV DPTR,#TABLE;段碼首地址送數據指針

MOV A,33H ;個位數送A

MOVC A,@A+DPTR ;查表

MOV P1,A ;結果送P1

MOV A,32H ;十位數送A

MOVC A,@A+DPTR ;查表

MOV P0,A ;結果送P0

RET ;子程序返回

END ;程序結束

閱讀全文

與個位數計算器設計單片機相關的資料

熱點內容
電影重建文件夾 瀏覽:981
第五人格香香解壓 瀏覽:626
我的世界手機版推薦什麼伺服器 瀏覽:706
安卓怎麼下載空戰 瀏覽:586
程序員賣房入市 瀏覽:117
android視頻播放窗口 瀏覽:288
17元特效的app名字叫什麼 瀏覽:838
小米手機什麼時候配置安卓 瀏覽:262
三種命令方塊 瀏覽:565
hp伺服器怎麼重新做系統 瀏覽:480
電腦與單片機無線 瀏覽:611
雲伺服器錢怎麼提現 瀏覽:878
華為運動app怎麼退出登錄 瀏覽:796
程序員那麼可愛陸漓金句 瀏覽:879
java如何將自己電腦設置成伺服器 瀏覽:858
域名怎麼制定伺服器8080埠 瀏覽:665
伺服器的主機如何使用 瀏覽:814
廣訊通伺服器地址怎麼填 瀏覽:665
山東交管伺服器繁忙雲空間 瀏覽:52
51單片機熱敏電阻壞了 瀏覽:548