『壹』 求助:關於80C51單片機簡易計算器設計的程序,要求是匯編語言。謝謝哈
ORG 0000H
START:MOV 78H,#0 ;初始化:78H放0的段碼,其餘放熄滅碼
MOV 79H,#10
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV R5, #0 ;R5是按鍵次數,初始置0
MOV 30H,#0 ;30H是功能鍵存放單元,置為0
MOV 40H,#0 ;40H單元初始置為0
MOV 41H,#0 ;41H單元初始置為0
LOOP:LCALL DIR
LCALL KEY
INC R5
;散轉程序,判斷按下的是哪個鍵
S1:CJNE A,#10,S2 ;不是"+"鍵,跳到S2
LJMP FUN ;是"+"鍵,跳到FUN
S2:CJNE A,#11,S3 ;不是"-"鍵,跳到S3
LJMP FUN ;是"-"鍵,跳到FUN
S3:CJNE A,#12,S4 ; 不是"*"鍵,跳到S4
LJMP FUN ; 是"*"鍵,跳到FUN
S4:CJNE A,#13,S5 ; 不是"/"鍵,跳到S5
LJMP FUN ; 是"/"鍵,跳到FUN
S5:CJNE A,#14,S6 ; 不是"="鍵,跳到S6
LJMP FUN ;是"="鍵,跳到FUN
S6:CJNE A,#15,N1 ; 不是"CL"鍵,跳到N1
LJMP START ; 是"CL"鍵,跳到START
N1:CJNE R5,#1,N2 ;判斷第幾次按鍵
LJMP D11
N2:CJNE R5,#2,N3
LJMP T2
N3:CJNE R5,#3,N4
LJMP T3
N4:CJNE R5,#4,N5
LJMP T4
N5:CJNE R5,#5,N6
LJMP T5
N6:CJNE R5,#6,START
LJMP T6
D11:MOV R4,A
MOV 78H,A ;輸入值送顯示個位緩存
MOV 79H,#10
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
LJMP LOOP
T2:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7AH,#10
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV 79H, 78H ;個位到十位
MOV 78H,R7 ;新數為個位
LJMP LOOP
T3:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7BH,#10
MOV 7CH,#10
MOV 7DH,#10
MOV 7AH,79H ;十位到百位
MOV 79H,78H ;個位到十位
MOV 78H,R7 ; 新數為個位
LJMP LOOP
T4:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7CH,#10
MOV 7DH,#10
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP
T5:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7DH,#10
MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP
T6:MOV R7,A
MOV B,#10
MOV A,R4
MUL AB
ADD A,R7
MOV R4,A
MOV 7DH,7CH
MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP
MOV 7CH,7BH
MOV 7BH,7AH
MOV 7AH,79H
MOV 79H,78H
MOV 78H,R7
LJMP LOOP
FUN:MOV 78H,#10
MOV 79H,#10
MOV 7AH,#10
MOV R0,30H ;與上次功能鍵交換
MOV 30H,A
MOV A,R0
CJNE A,#10,FUN1 ;判斷功能鍵
LJMP ADDY ;"+"
FUN1:CJNE A,#11,FUN2
LJMP SUBT ;"-"
FUN2:CJNE A,#12,FUN3
LJMP MULT ;"*"
FUN3:CJNE A,#13,FUN4
LJMP DIVI ;"/"
FUN4:CJNE A,#14,FUN5 ;首次按功能鍵,即A=#0
LJMP EQUA ;"="
FUN5:MOV 40H,R4 ;保存第一個數
MOV R5,#0 ;按鍵次數清零
LJMP BCD ;將其拆為bcd碼,以便後來將其顯示
OF:LJMP START ;溢出處理
ADDY:MOV A,40H ;第一個數送累加器
ADD A,R4 ;第一個數加第二個數
JB CY,OF ;溢出
MOV 40H,A ;存本次結果
MOV R5,#0 ;按鍵次數清零
LJMP BCD
SUBT:MOV A,40H
SUBB A,R4
JB CY,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
MULT:MOV A,40H
MOV B,A
MOV A,R4
MUL AB
JB OV,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
DIVI:MOV A,R4
MOV B,A
MOV A,40H
DIV AB
JB OV,OF
MOV 40H,A
MOV R5,#0
LJMP BCD
EQUA:MOV R5,#0
LJMP BCD
BCD:MOV B,#10
MOV A,40H ;結果送累加器
DIV AB ;結果除10
MOV 41H,A ;暫存"商"
MOV A,B ;取個位數
MOV 78H,A ;個位數送顯示緩存
MOV A,41H
JZ RETURN ;結果是一位數,返回LOOP
MOV B,#10
MOV A,41H
DIV AB
MOV 41H,A
MOV A,B
MOV 79H,A ;十位送顯示緩存
MOV A,41H
JZ RETURN ;結果是二位數,返回LOOP
MOV 7AH,A ;百位數送顯示緩存
RETURN:LJMP LOOP
;動態顯示子程序
DIR:MOV DPTR,#TAB ; 數碼管解碼表首址
MOV R0,#78H ;待顯緩沖區個位地址
MOV A,#0FEH ; 個位位選信號
MOV R1,A
LD1:MOV A,@R0
MOVC A,@A+DPTR ;查表
MOV P2,R1 ;共陽極管字位選擇送到P2口
MOV P0,A ;欄位碼送P0口
LCALL DELAY1ms ;調延時1ms 子程序
INC R0 ;R0指向下一模塊
MOV A,R1 ;
JNB ACC.5,LD2 ;判斷是否發完6個數
RL A ;指向下一個位
MOV R1,A ;位選信號存回R3
SJMP LD1 ;跳去再顯示下一個數
LD2:RET ;發完6個數就返回
TAB:DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,80H,90H,0FFH ;共陽極解碼表
DELAY1ms:MOV R6,#2
LOOP1:MOV R7,#248
NOP
LOOP2:DJNZ R7,LOOP2
DJNZ R6,LOOP1
RET
KEY:LCALL KS ;調用檢測按鍵子程序
JNZ K1 ;有鍵按下繼續
LCALL DELAY2 ;無鍵按調用延時去抖
ACALL DIR ;調用動態顯示
AJMP KEY ;返回繼續檢測按鍵
K1:LCALL DELAY2 ;有鍵按下延時去抖動
LCALL KS ;再調用檢測按腱子程序
JNZ K2 ;確認有按鍵進行下一步
ACALL DIR ;調用動態顯示
AJMP KEY ;無鍵按下返回繼續檢測
K2:MOV R2,#0EFH ;將掃描值送入R2暫存
MOV R3,#00H ;將第一列值送入R3暫存
K3:MOV P1,R2 ;將R2值送入P1口
L0:JB P1.0,L1 ;P1.0等於1跳轉到L1
MOV A,#00H ;將第一行值送入ACC
AJMP LK ;跳轉到鍵值處理程序
L1:JB P1.1,L2 ;P1.1等於1跳轉到L2
MOV A,#04H ;將第二行的行值送入ACC
AJMP LK ;跳轉到鍵值處理程序
L2:JB P1.2,L3 ;P1.2等於1跳轉到L3
MOV A,#08H ;將第三行行值送入ACC
AJMP LK ;跳轉到鍵值處理程序
L3:JB P1.3,NEXT ;P1.3等於1跳轉到NEXT處
MOV A,#0CH ;將第四行行值送入ACC
LK:ADD A,R3 ;行值與列值相加後的鍵值送入A
PUSH ACC ;將A中的值送入堆棧暫存
K4:LCALL DELAY2 ;調用延時去抖程序
LCALL KS ;調用按鍵檢測程序
JNZ K4 ;按鍵沒有松開繼續返回檢測
POP ACC ;將堆棧值送入ACC
MOV DPTR,#KEYTAB
MOVC A,@A+DPTR
RET
NEXT:INC R3 ;列值加一
MOV A,R2 ;R2值送入A
JNB ACC.7,KEY ;掃描完至KEY處進行下一掃描
RL A ;掃描未完將值左移一位進行下一列掃描
MOV R2,A ;將ACC值送入R2暫存
AJMP K3 ;跳轉到K3繼續
KS:MOV P1,#0FH ;將P1口高四位置0低四位置1
MOV A,P1 ;讀P1口
XRL A,#0FH ;將A中的值與A中的值相異或
RET ;子程序返回
KEYTAB:DB 1,2,3,10,4,5,6,11,7,8,9,12,15,0,14,13 ;鍵值表
DELAY2:MOV R6,#2H ;延時去抖動子程序
LP1:MOV R7,#0FAH
LP2:DJNZ R7,LP2
DJNZ R6,LP1
RET
END
『貳』 利用51單片機,4個數碼管設計一個計時器,要求在數碼管上顯示的數據從0開始每1秒鍾加1。
共陽數碼管中斷程序:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
uint num,a;
uchar ,shi,ge;
void init();
void delay(uint);
void display(uchar,ucharshi,ucharge);
uint fb();
uint fs();
uint fg();
void main()
{
init();
while(1)
{
display(fb(),fs(),fg());
}
}
void init()
{
num=0;
a=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void display(uchar,ucharshi,ucharge)
{
P1=0xfd;
P0=table[];
delay(1);
P1=0xfb;
P0=table[shi];
delay(1);
P1=0xf7;
P0=table[ge];
delay(1);
}
void timeoff() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65526-50000)%256;
a++;
if(a%20==0)
{
num++;
if(num==999)
{
num=0;
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uint fb()
{
=num/100;
return ;
}
uint fs()
{
shi=num%100/10;
return shi;
}
uint fg()
{
ge =num%100%10;
return ge;
}
(2)51單片機數碼管計算器擴展閱讀
2個可編程定時/計數器·5個中斷源,2個優先順序(52有6個)
一個全雙工串列通信口
外部數據存儲器定址空間為64kB
外部程序存儲器定址空間為64kB
邏輯操作位定址功能·雙列直插40PinDIP封裝
單一+5V電源供電
CPU:由運算和控制邏輯組成,同時還包括中斷系統和部分外部特殊功能寄存器;
RAM:用以存放可以讀寫的數據,如運算的中間結果、最終結果以及欲顯示的數據;
ROM:用以存放程序、一些原始數據和表格;
I/O口:四個8位並行I/O口,既可用作輸入,也可用作輸出
T/C:兩個定時/記數器,既可以工作在定時模式,也可以工作在記數模式;
五個中斷源的中斷控制系統;
一個全雙工UART(通用非同步接收發送器)的串列I/O口,用於實現單片機之間或單片機與微機之間的串列通信;
片內振盪器和時鍾產生電路,石英晶體和微調電容需要外接。最佳振盪頻率為6M—12M。
參考資料來源:網路-51單片機
『叄』 51單片機計數器怎麼使用
設置T0模式 為計數模式就行了 就是TMOD的C/T位置1;
脈沖從T0輸入 T0就計數了
你讀取TH0和TL0就曉得脈沖個數了
有了這個脈沖個數 輸出到數碼管即ok
『肆』 51單片機實現對外部脈沖進行十進制計數,從0開始最大計數999999。6位數碼管顯示,有啟動暫停清零功能。
只是計數吧,對脈沖的頻率又不需要進行測算,可以只用外部埠中斷(中斷函數內只實現一個全局變數的自加運算),在主循環函數實現對這個全局變數的復位和送顯示,暫停只要關外部中斷即可
『伍』 怎樣用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] = '