求助,关于AT89C51单片机简易计算器设计的程序,最好是关于C语言的。谢谢哈。
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
#include
delay10ms()
{
unsigned char a,b;
for(a=100;a>0;a--)
for(b=50;b>0;b--);
}
delay1ms()
{
unsigned char a,b;
for(a=10;a>0;a--)
for(b=50;b>0;b--);
}
unsigned char code tab[]=
{
0x3f,6,0x5b,0x4f,0x66,0x6d,0x7d,7,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};
main()
{
unsigned char m,i,j,k,l,p,cc2,cc3,cc4,cc5,o;
unsigned long c1,c2,cc;
unsigned int cc1;
unsigned char aa0,aa1,aa2,aa3,bb0,bb1,bb2,bb3;
unsigned char a0,a1,a2,a3,b0,b1,b2,b3;
bit q,n;
while(1)
{static dian=0x80,fuhao=0;
for (j=0;j<=3;j++)
{
k=0xfe<<j;
l=0xfe>>(8-j);
P0=k|l;
if(P0_4==0)
{
delay10ms();
if(P0_4==0)
{
while(P0_4==0)
{
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
P2=dian;
P1=0xef;
delay1ms();
P2=0;
P2=fuhao;
P1=0xef;
delay1ms();
P2=0;
}
if(tab[4*j]==0x39)
{
n=1;
i=3;
}
else
{m++;
if(m<=4&n==0)
{
a3=a2;
a2=a1;
a1=a0;
a0=tab[4*j];
aa3=aa2;
aa2=aa1;
aa1=aa0;
aa0=4*j;
}
else
{
if(p<=3&n==1)
{
b3=b2;
b2=b1;
b1=b0;
b0=tab[4*j];
bb3=bb2;
bb2=bb1;
bb1=bb0;
bb0=4*j;
p++;
}
}
}
}
}
if(P0_5==0)
{
delay10ms();
if(P0_5==0)
{
while(P0_5==0)
{
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
P2=dian;
P1=0xef;
delay1ms();
P2=0;
P2=fuhao;
P1=0xef;
delay1ms();
P2=0;
}
if(tab[4*j+1]==0x5e)
{
i=4;
n=1;
}
else
{m++;
if(m<=4&n==0)
{
a3=a2;
a2=a1;
a1=a0;
a0=tab[4*j+1];
aa3=aa2;
aa2=aa1;
aa1=aa0;
aa0=4*j+1;
}
else
{
if(p<=3&n==1)
{
b3=b2;
b2=b1;
b1=b0;
b0=tab[4*j+1];
bb3=bb2;
bb2=bb1;
bb1=bb0;
bb0=4*j+1;
p++;
}
}
}
}
}
if(P0_6==0)
{
delay10ms();
if(P0_6==0)
{
while(P0_6==0)
{
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
P2=dian;
P1=0xef;
delay1ms();
P2=0;
P2=fuhao;
P1=0xef;
delay1ms();
P2=0;
}
if(tab[4*j+2]==0x77)
{
i=1;
n=1;
}
else
{
if(tab[4*j+2]==0x79)
{
q=1;
n=1;
}
else
{
m++;
if(m<=4&n==0)
{
a3=a2;
a2=a1;
a1=a0;
a0=tab[4*j+2];
aa3=aa2;
aa2=aa1;
aa1=aa0;
aa0=4*j+2;
}
else
{
if(p<=3&n==1)
{
b3=b2;
b2=b1;
b1=b0;
b0=tab[4*j+2];
bb3=bb2;
bb2=bb1;
bb1=bb0;
bb0=4*j+2;
p++;
}
}
}
}
}
}
if(P0_7==0)
{
delay10ms();
if(P0_7==0)
{
while(P0_7==0)
{
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
P2=dian;
P1=0xef;
delay1ms();
P2=0;
P2=fuhao;
P1=0xef;
delay1ms();
P2=0;
}
if(tab[4*j+3]==0x71)
{
i=6;
n=1;
}
else
{
if(tab[4*j+3]==0x7c)
{
i=2;
n=1;
}
else
{m++;
if(m<=4&n==0)
{
a3=a2;
a2=a1;
a1=a0;
a0=tab[4*j+3];
aa3=aa2;
aa2=aa1;
aa1=aa0;
aa0=4*j+3;
}
else
{
if(p<=3&n==1)
{
b3=b2;
b2=b1;
b1=b0;
b0=tab[4*j+3];
bb3=bb2;
bb2=bb1;
bb1=bb0;
bb0=4*j+3;
p++;
}
}
}
}
}
}
if(i==6)//复位
{
a0=a1=a2=a3=b0=b1=b2=b3=0;
dian=0x80;
fuhao=0;
m=i=j=k=l=n=p=q=0;
aa0=aa1=aa2=aa3=bb0=bb1=bb2=bb3=0;
c1=c2=cc=cc1=cc2=cc3=cc4=cc5=0;
}
if(q==0)
{
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
P2=dian;
P1=0xef;
delay1ms();
P2=0;
P2=fuhao;
P1=0xef;
delay1ms();
P2=0;
}
else
{
q=0;
c1=aa0+aa1*10+aa2*100+aa3*1000;
c2=bb0+bb1*10+bb2*100+bb3*1000;
if(i==1)//加法运算
{
cc=c1+c2;
}
if(i==2)//减法运算
{
if(c1>=c2)
{
cc=c1-c2;
}
else
{
cc=c2-c1;
fuhao=0x40;
}
}
if(i==3)//乘法运算
{
cc=c1*c2;
}
a3=tab[cc/10000000];
aa3=cc/10000000;
a2=tab[(cc%10000000)/1000000];
aa2=(cc%10000000)/1000000;
a1=tab[(cc%1000000)/100000];
aa1=(cc%1000000)/100000;
a0=tab[(cc%100000)/10000];
aa0=(cc%100000)/10000;
b3=tab[(cc%10000)/1000];
bb3=(cc%10000)/1000;
b2=tab[(cc%1000)/100];
bb2=(cc%1000)/100;
b1=tab[(cc%100)/10];
bb1=(cc%100)/10;
b0=tab[cc%10];
bb0=cc%10;
dian=0;//消除点
if(aa3==0)//消除多余的零
{
a3=0;
if(aa2==0)
{
a2=0;
if(aa1==0)
{
a1=0;
if(aa0==0)
{
a0=0;
if(bb3==0)
{
b3=0;
if(bb2==0)
{
b2=0;
if(bb1==0)
{
b1=0;
}
}
}
}
}
}
}
if(i==4)//除法运算
{
if(c2==0)
{
for(o=100;o>0;o--)
{
b2=b1=b0=0;
a3=0x79;
a2=a1=b3=0x77;
a0=0x3f;
P2=b0;
P1=0xfe;
delay1ms();
P2=0;
P2=b1;
P1=0xfd;
delay1ms();
P2=0;
P2=b2;
P1=0xfb;
delay1ms();
P2=0;
P2=b3;
P1=0xf7;
delay1ms();
P2=0;
P2=a0;
P1=0xef;
delay1ms();
P2=0;
P2=a1;
P1=0xdf;
delay1ms();
P2=0;
P2=a2;
P1=0xbf;
delay1ms();
P2=0;
P2=a3;
P1=0x7f;
delay1ms();
P2=0;
delay10ms();
}
i=6;
}
else
{
cc1=c1/c2;
a3=tab[cc1/1000];
aa3=cc1/1000;
a2=tab[(cc1%1000)/100];
aa2=(cc1%1000)/100;
a1=tab[(cc1%100)/10];
aa1=(cc1%100)/10;
a0=tab[cc1%10];
aa0=cc1%10;
dian=0x80;
cc2=(c1%c2)*10/c2;
b3=tab[cc2];
cc3=((c1%c2)*10%c2)*10/c2;
b2=tab[cc3];
cc4=(((c1%c2)*10%c2)*10%c2)*10/c2;
b1=tab[cc4];
cc5=((((c1%c2)*10%c2)*10%c2)*10%c2)*10/c2;
b0=tab[cc5];
if((((((c1%c2*10)%c2)*10%c2)*10%c2)*10%c2)*10/c2>=5)
{
b0=tab[cc5+1];
}
if(aa3==0)//消除多余的零
{
a3=0;
if(aa2==0)
{
a2=0;
if(aa1==0)
{
a1=0;
}
}
}
}
}
}
}
}
}
这个是数码管的
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
void display(long z);
long k, temp,num,num1,num2,num3,num4,f,f1,f2,f3,swan,wan,qian,bai,shi,ge,equ,biao;
/*f1=1 :有键按下.f=1 f2=1:有符号键按下.f3=0/1:输入第一个数/输入第二个数,biao=1/2/3/4:加减乘除
equ=1:按下等于号,num:keyscan中键值num1:得到连续输入的值num2:第一次输入的值,num3:第二次输入
的值,num4:被显示的值*/
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};//数码管段选代码
uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//数码管位选代码
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
long keyscan()//键盘扫描函数
{
P3=0xfe;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)//键盘去抖
{
temp=P3;
switch(temp)
{
case 0xee:num=7;f1=1;f2=0;break;
case 0xde:num=8;f1=1;f2=0;break;
case 0xbe:num=9;f1=1;f2=0;break;
case 0x7e:num='/';f1=1;f=1;f2=1;f3=1;biao=4;break;
}
while(temp!=0xf0)//松手检测
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xfd;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=4;f1=1;f2=0;break;
case 0xdd:num=5;f1=1;f2=0;break;
case 0xbd:num=6;f1=1;f2=0;break;
case 0x7d:num='*';f1=1;f=1;f2=1;f3=1;biao=3;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xfb;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=1;f1=1;f2=0;break;
case 0xdb:num=2;f1=1;f2=0;break;
case 0xbb:num=3;f1=1;f2=0;break;
case 0x7b:num='-';f1=1;f=1;f2=1;f3=1;biao=2;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xf7;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(100);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num='c';f1=1;f2=1;biao=5;equ=1;break;
case 0xd7:num=0;f1=1;f2=0;break;
case 0xb7:num='=';f1=1; f=1;f2=1;equ=1;break;
case 0x77:num='+';f1=1; f=1;f2=1;f3=1;biao=1;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
return num;
}
void display(long z)//显示函数
{
swan=z/100000;
wan=z%100000/10000;
qian=z%10000/1000;
bai=z%1000/100;
shi=z%100/10;
ge=z%10;
if(swan==0)//数码管最高位为0则不现实
{
P0=table1[0];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[0];
wela=1;
wela=0;
P0=table[swan];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan))//前两位都为0则不现实(后面类似)
{
P0=table1[1];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[1];
wela=1;
wela=0;
P0=table[wan];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian))
{
P0=table1[2];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[2];
wela=1;
wela=0;
P0=table[qian];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian||bai))
{
P0=table1[3];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[3];
wela=1;
wela=0;
P0=table[bai];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian||bai||shi))
{
P0=table1[4];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[4];
wela=1;
wela=0;
P0=table[shi];
dula=1;
dula=0;
delay(2);
}
P0=table1[5];
wela=1;
wela=0;
P0=table[ge];
dula=1;
dula=0;
delay(2);
}
void jisuan()//连续按键时计算出按的值(如按1计算出为1再按2计算出12再按3计算出123)
{
k=keyscan();
if(f1==1)//有键按下
{
f1=0;
if(f==1)//有符号键按下
{
f=0;
num1=0;
}
else
num1=10*num1+k;
if(f2==0)//有数字键按下
{
if(f3==0)
{
num2=num1;
num4=num2;
}
else
{
num3=num1;
num4=num3;
}
}
}
}
void jieguo()//按等号时进行相应的计算并将结果计算出来
{
if(equ==1)
{
switch(biao)
{
case 1:num4=num2+num3;break;
case 2:num4=num2-num3;break;
case 3:num4=num2*num3;break;
case 4:num4=num2/num3;break;
case 5:num4=num2*num2;break;
}
}
}
void main()
{
while(1)
{
jisuan();
jieguo();
display(num4);
}
}
OUTBIT EQU 8002H ;端口地址初始化
OUTSEG EQU 8004H
HIN EQU 8001H
LEDBUF EQU 30H
ORG 0000H
LJMP START
ORG 0100H
LEDMAP: ;短码表
DB 3FH,06H,5BH,4FH
DB 66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH
DB 39H,5EH,79H,71H
DELAY: MOV 19H,#10
DEY1: MOV 18H,#50 ;延蔇EY2: DJNZ 18H,DEY2
DJNZ 19H,DEY1
RET
DISPLAY: ;显示子程序
MOV DPTR,#OUTBIT
MOV A,#0
MOVX @DPTR,A
MOV A,R5 ;R4--段码
MOV DPTR,#OUTSEG
MOVX @DPTR,A
MOV DPTR,#OUTBIT
MOV A,R2 ;R2--位码
MOVX @DPTR,A
ACALL DELAY
MOV DPTR,#OUTBIT
MOV A,#0
MOVX @DPTR,A
RET
TESTKEY: MOV DPTR,#OUTBIT ;检测键盘
MOV A,#00H
MOVX @DPTR,A ;输出列置0
MOV DPTR,#HIN
MOVX A,@DPTR ;读入键盘状态
CPL A
ANL A,#0FH
RET
KEYTABLE: DB 16H,15H,14H,0FFH ;键码定义
DB 13H,12H,11H,10H
DB 0DH,0CH,0BH,0AH
DB 0EH,03H,06H,09H
DB 0FH,02H,05H,08H
DB 00H,01H,04H,07H
GETKEY: MOV DPTR,#OUTBIT ;计算键编号
MOV P2,DPH
MOV R1,#HIN ;R1行地址
MOV R3,#20H ; R2列码
MOV R7,#6
KLOOP: MOV A,R3
CPL A
MOVX @DPTR,A ;第一列置0
CPL A
RR A
MOV R3,A ;下一列
MOVX A,@R1 ; 读该列状态
CPL A
ANL A,#0FH ;屏蔽高四位
JNZ GOON1
DJNZ R7,KLOOP
MOV R7,#0FFH ;无键按下返回0FFH
SJMP EXIT
GOON1: MOV R3,A ;编号=列*4+行
MOV A,R7
DEC A
RL A
RL A
MOV R7,A ;R0=(R7-1)*4
MOV A,R3 ;R2为读入列值
MOV R2,#4
LOOPC: RRC A ;右移计算行值
JC EXIT ;R0=R0+行值
INC R7
DJNZ R3,LOOPC
EXIT: MOV A,R7 ;取键编号
MOV DPTR,#KEYTABLE
MOVC A,@A+DPTR
MOV @R0,A ;存键值R0中
WAITRELEASE: ;等待键释放
MOV DPTR,#OUTBIT
CLR A
MOVX @DPTR,A
ACALL DELAY
ACALL TESTKEY
JNZ WAITRELEASE
MOV A,@R0 ;键值存入A
RET
ADDY: MOV 12H,R0
CLR C ;加法
MOV R7,#4
ADDY1: MOV A,@R0
ADDC A,@R1
MOV @R0,A ;结果存入R0
INC R0
INC R1
DJNZ R7,ADDY1
MOV R7,#5
ACALL CHANG
RET
SUBBY: MOV 12H,R0
CLR C ;减法
MOV R7,#2
SUB1: MOV A,@R1
SUBB A,@R0
JNC N1
ADD A,#10
SETB C
N1: MOV @R0,A
INC R0
INC R1
DJNZ R7,SUB1
MOV R0,12H
RET
MULY: MOV 12H,R0
MOV R3,#0 ;乘法
MOV 15H,@R0 ;另存乘数
INC R0
MOV 16H,@R0
DEC R0
MOV R2,#2
MUL1: MOV A,@R1
MOV B,@R0
MUL AB
MOV @R0,A
INC R0
DJNZ R2,MUL1
DEC R0
INC R1
MOV B,15H
MOV R2,#2
MUL2: MOV A,@R1
MUL AB
ADD A,@R0
MOV @R0,A
INC R0
MOV A,#0
ADDC A,#0
MOV @R0,A
MOV B,16H
DJNZ R2,MUL2
MOV R7,#4
ACALL CHANG
RET
CHANG: MOV R0,12H ;转化为十进制
MOV R3,#0
C1: MOV A,@R0
ADD A,R3
MOV B,#10
DIV AB
XCH A,B
MOV @R0,A
INC R0
MOV R3,B
DJNZ R7,C1
MOV R0,12H
RET
LEDBUFY: JC NEXT1 ;数据缓冲子程序
SJMP NEXT2
NEXT1: MOV R5,#40H ;负数
MOV R2,#20H
ACALL DISPLAY
MOV R2,17H
NEXT2: MOV A,@R0
MOV DPTR,#LEDMAP
MOVC A,@A+DPTR
MOV R5,A
ACALL DISPLAY
MOV A,R2
RR A
MOV R2,A
DEC R0
DJNZ R6,NEXT2
RET
START: CLR C ;开始
MOV R0,#LEDBUF ;R0--数据缓冲地址
MOV R6,#0
MOV R3,#30 ;初始化参数
K1: MOV @R0,#00H
INC R0
DJNZ R3,K1
MOV R0,#LEDBUF+20 ;缓冲区清零
DISPL: MOV 10H,R0 ;保护R0,R6
MOV 11H,R6
MOV R2,#1
CJNE R6,#0,Y1
SJMP Y3 ;无任何键按下
Y1: MOV A,R0
ADD A,R6
MOV R0,A ;数据高位地址送R0
MOV A,R2
RRC A
Y2: RLC A
DJNZ R6,Y2
MOV R2,A ;位码移到高位
MOV R6,11H
SJMP Y4
Y3: MOV R6,#01H
Y4: MOV 17H,R2
ACALL LEDBUFY ;数据送缓冲区显示
MOV R6,11H
MOV R0,10H
TESTY: ACALL TESTKEY
ACALL DELAY ;测试键盘
JZ DISPL ;无键按下,动态显示缓冲区内容
ACALL GETKEY ;有键输入
DEC R0
K2: CJNE A,#0AH,K3 ;确认键值
SJMP NEXT ;功能键“+”
K3: JNC K4
INC R6
SJMP DISPL
K4: CJNE A,#0FH,K5
SJMP START ;清零键
K5: CJNE A,#0BH,K6 ;功能键“-”
SJMP NEXT
K6: CJNE A,#0CH,K7 ;功能键“*”
NEXT: MOV R4,A ;功能键“+,-,*”,并保存入R4
MOV A,R0
INC A
INC A
MOV 1FH,A
MOV R0,#LEDBUF+10 ;赋下一个操作数缓冲地址
MOV R6,#0 ; 计数清零
SJMP TESTY ;等待数据输入
K7: CJNE A,#0EH,K8 ;功能键“=”
EQUY: INC R0
INC R0
MOV R1,1FH
CJNE R4,#0AH,LOOP1 ;测试上一次功能键
ACALL ADDY
DEC R0 ;加法
MOV R6,#5 ;五个缓冲单元
SJMP DISPL
LOOP1: CJNE R4,#0BH,LOOP2
ACALL SUBBY
DEC R0 ;减法
MOV R6,#2 ;两个缓冲单元
SJMP DISPL
LOOP2: ACALL MULY ;乘法
DEC R0
MOV R6,#4 ;四个缓冲单元
SJMP DISPL ;送数入显示缓冲区
K8: INC R0
MOV @R0,#0
SJMP TESTY ;继续测试键盘
END
这个是我原来点的1602驱动。你对照看看,判忙,发数据,发命令函数是不是一样的。 你的程序我没具体看。你尝试在某些命令后加上延时试看。 还有第二行的地址是40H开头的。
/********************************************************************************
*Design: qinhao
*********************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
volatile char bf;
sbit rs=P3^0;
sbit rw=P3^1;
sbit e=P3^2;
#define bf P1^7
uchar code qin[]={
0x1F,0x11,0x11,0x11,0x11,0x11,0x11,0x1F, //方框
0x0E,0x0A,0x04,0x1F,0x04,0x0E,0x0A,0x1B, //小人
0x0A,0x15,0x0A,0x15,0x0A,0x15,0x0A,0x15, //黑白格子
0x1F,0x15,0x1F,0x1B,0x1B,0x1F,0x11,0x1F, //脸
0x0E,0x11,0x11,0x15,0x15,0x0E,0x04,0x04, //树
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11, // 月
0x1F,0x00,0x1F,0x00,0x1F,0x00,0x1F,0x00, //黑白横条
0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, //黑白竖条
};
void delay(unsigned int n)
{
unsigned int i,j;
for(j=n;j>0;j--)
for(i=112;i>0;i--);
} /////// 精确MS,
void check() // 判忙
{
rs=0;
rw=1;
e=0;
P1=0xff;
e=1;
_nop_();
_nop_();
while(P1&0x80){};
delay(10);
}
void sendc(uchar com) // 发命令字
{
check();
rs=0;
rw=0;
e=1;
P1=com;
_nop_();
e=0;
_nop_();
}
void sendd(uchar word) // 发显示字
{
check();
rs=1;
rw=0;
e=1;
P1=word;
_nop_();
e=0;
_nop_();
}
void inti() // 初始化
{
sendc(0x01);
sendc(0x38);
sendc(0x0f);
sendc(0x06);
delay(10);
}
void setcgram() ////// 写cgram
{
uchar x;
sendc(0x40);
for(x=0;x<64;x++)
{
sendd(*(qin+x));
};
}
void main()
{
unsigned char i;
setcgram();
inti();
sendc(0x80); /// 第一行
for(i=0;i<8;i++)
{
sendd(i+0x00);
};
sendc(0xc0); /// 第二行
for(i=0;i<8;i++)
{
sendd(0x07-i);
};
while(1){};
}
求助:如何往AT89C51单片机里烧写程序
买一个USB转UART模块,中关村卖20元一个,然后用杜邦接口的排线把VCC,GND,RXD,TXD接到单片机对应脚上,就组成了简单的ISP下载线,为方便使用可以把排线另一端接上芯片座,随插随用,很方便。
利用AT89C51单片机实现两个共阳数码管倒数计时99秒,求程序!!要求是C...
这是正时,改动一下 include <AT89X51.H> unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};unsigned char second;unsigned char keycnt;unsigned int tcnt;void main(void){ unsigned char i,j;TMOD=0x...
AT89C1051可以用AT89C2051互换吗?
这两个的话,应该是可以互换的
STC89C 51跟AT89C51有啥区别
AT的芯片要专门的编程器,STC的支持串行下载,也就是说不用买编成器喽,可以节约点喽,且AT89C51的数据存储空间为1*4=4KB,而STC89C52的存储空间为2*4=8KB,STC的芯片优于AT的。
急求 单片机 AT8951与STC89C52的区别
当然烧不进去,52单片机是8KROM,256BRAM,而51单片机是4KROM,128BRAM;好比你要把80G硬盘里的东西烤到40G硬盘里面,如果文件超过40G怎么拷?而且单片机不同的厂家烧录方式不尽相同,如果你的开发板不另带编程器的话,你那片52应该是STC89C52。STC的单片机是串口烧录,ATMEL(AT)C系列单片机是并行烧录...
51单片机 型号
ATMEL的51、2051、1051均有多种封装,如AT89C(S)51有PDIP、PLCC和PQFP\/TQFP等封装;2051\/1051有PDIP和SOIC封装等。下图是部分封装实物。由于51系列单片机的内核都一样,所以在51单片机教材方面目前仍然沿用Intel MCS 8051单片机的书籍。开发软件和工具也是一样,我们统称为8051开发系统、环境、等等,如我们网站介绍的汇编...
80系列单片机和89系列单片机有什么区别?
我们统称这些与8051内核相同的单片机为“51系列单片机”。在众多的51系列单片机中,要算 ATMEL 公司的AT89C51更实用,因他不但和8051指令、管脚完全兼容,而且其片内的4K程序存储器是FLASH工艺的,这种工艺的存储器用户可以用电的方式瞬间擦除、改写,一般专为 ATMEL AT89Cx 做的编程器均带有这些功能。
节水灌溉为什么要选AT89C55作为单片机
记得在上个世纪九十年代有一款产品中选这个芯片的理由是程序超过了8kB。
51系列单片机有哪些
51 ;单片机目前已有多种型号, 8031\/8051\/8751是Intel公司早期的产品,而 ATMEL ;公司的AT89C51、AT89S52则更实用。ATMEL公司的51系列还有AT89C2051、AT89C1051等品种,这些芯片是在AT89C51的基础上将一些功能精简掉后形成的精简版。而市场上目前供货比较足的芯片还要算ATMEL ;的51、52...
求教AT单片机烧录……
AT的单片机主要是两种编程方式:并行编程和串行编程(ISP)。并行编程的多见于一些比较古老的单片机型号,比如AT89C系列单片机,它们大部分需要使用12V的电压才能编程(正常工作电压为5V),并且需要使用很多IO口(比如为AT89C51下载程序,除了Vcc和GND之外,还要连接二十多根线),并且需要将芯片拆下安装到专用...
标厚四物: #include unsigned char data dis_digit; unsigned char key_s, key_v; unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off unsigned char dis_buf[8]; // 显示缓冲区 unsigned ...
金东区15531003492: AT89C51单片机设计一个简易秒表? - ?
标厚四物: 定时器10ms中断 检测按键且10ms位加一 若10ms=10,100ms位加一 若10ms=10,1000ms位加一 以此内推 显示最好用LCD的 用数码管的也行 有疑问mail:290765583@163.com
金东区15531003492: 请大神们帮我编个简单的AT89C51单片机的c语言程序 - ?
标厚四物: #include "reg51.h" void main(void) {P1=P1 | 0X40;//P1.6=1P1=P1 & 0X7F;//P1.7=0P0=P0 | 0X07;//P0.0=1,P0.1=1,P0.2=1while(1){if((P1 & 0X40)==0)//P1.6=0{P0=P0 & 0XF8;//P0.0=0,P0.1=0,P0.2=0}if((P1 & 0X80)>0)//P1.7=1{PCON=PCON | 2;//睡眠}} }
金东区15531003492: 电子钟的设计(带按键调整) 任务要求:利用AT89C51单片机设计简易电子钟(六位),通过6位共阴 - ?
标厚四物: #include#define uchar unsigned char...要是PROTEUS的话差不多是这样,要是不想麻烦搞个74595的话P1就直接连(有没有都一样有的话比较整洁,没有的话程序上省点脑筋)主按键就用INT0,我没用P0口是因为懒得加上拉电阻,高低电平暂时先设成低的,思路就是P2口片选,当INT0触发时,你可以用while循环兜住不让出去,第一次是片选前两位“时”,第二次分第三次秒,如果第四次按下P32,也就是进入中断后第三次按下按键,结束中断,调到main.思路应该是这样当然肯定漏洞很多,先吃个饭再看看.
金东区15531003492: 如何自制at89c51/at80c51的最小系统单片机 - ?
标厚四物: 给你一个89C52的最小系统,和89C51、80C51通用.最小系统:能让单片机工作的最少条件,对于这两种51单片机,需要电源、晶振、复位电路、EA就可以组成一个最小系统,图给你发了,按照图片上的连接方法和参数,一定可以做成这个最小系统.还有你说的晶振可以更换,你可以使用晶振的孔座,和单片机的孔座一样,方便更换.
金东区15531003492: 求基于AT89C51单片机简易计算器设计的程序,请帮帮忙,谢谢. - ?
标厚四物: 这个是我原来点的1602驱动.你对照看看,判忙,发数据,发命令函数是不是一样的. 你的程序我没具体看.你尝试在某些命令后加上延时试看. 还有第二行的地址是40H开头的. /************************************************************************...
金东区15531003492: 求一个基于AT89C51单片机制作的简单计算机的汇编语言 - ?
标厚四物: 软件自带汇编语言的计算器.
金东区15531003492: 用AT89C51单片机构成一简单的方波发生器 急求!?
标厚四物:ORG 0000H LJMP start ORG 000BH LJMP aaaa ;3个周期 ORG 0030H start: MOV TMOD,#01H MOV TH0,#0FFH MOV TL0,#3AH SETB TR0 SETB ET0 SETB EA SJMP $ aaaa: MOV TH0,#0FFH ;197个周期 MOV TL0,#3AH CPL P1.7 bbbb: RETI END 共延时200个周期 也就是25us取反P1.7脚,P1.7输出为方波,周期为200us*2=400us 12M晶振为Ius周期
金东区15531003492: AT89C51单片机程序 - ?
标厚四物: 这个很简单的啊.“第三个是RST输入低电平 程序初始化”表述不清楚,如果这是由复位引脚输入,那就和软件没有关系了;是由单片机的IO口输入,就用软件复位.如果该单片机没有软件复位,那就重新初始化各个变量和IO口
金东区15531003492: at89c51资料 - ?
标厚四物: AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机.AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单...