单片机设计计算器

单片机设计计算器,第1张

下面是我以前写的一个简单的计算器的程序,你可以参考参考

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit E=P2^7; //1602使能引脚

sbit RW=P2^6; //1602读写引脚

sbit RS=P2^5; //1602数据/命令选择引脚

uchar temp,num,k,m,flag,flag1,tt,a;

uint table[10];

uint val[8];

uint shu,shu1,shu2;

void init();

void delay(uint z);

void write_com(uchar com);

void write_date(uchar date);

uchar keyscan();

void input();

void output();

void main()

{

init();

while(1)

{

input();

output();

}

}

void delay(uint z)

{

int i,j;

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

for(j=110;j>0;j--);

}

void init()

{

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x80);

write_com(0x01);

}

void write_com(uchar com)

{

P0=com;

RS=0;

RW=0;

E=0;

delay(5);

E=1;

delay(5);

}

void write_date(uchar date)

{

P0=date;

RS=1;

RW=0;

E=0;

delay(5);

E=1;

delay(5);

}

uchar keyscan()

{

P1=0xfe;//对矩阵键盘的第一行全赋0,扫描第一行

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)//消抖

{

delay(10);

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;//将P1的值读入temp中,否则temp的值始终为0xf0

//因为当程序运行到松手检测循环时,要退出松手

//检测循环就必须是temp值为0xf0

switch(temp)

{

case 0xee:num=7;break;//break是跳出switch语句,

case 0xde:num=8;break;//而不是跳出while语句

case 0xbe:num=9;break;

case 0x7e:num=13;break;//num=13表示除号

}

while(temp!=0xf0) //松手检测

{ //即当手松开时,也即无按键被按下

temp=P1; //则temp值就等于0xf0,

temp=temp&0xf0; //退出此循环

}

}

}

P1=0xfd;//对矩阵键盘的第二行全赋0,扫描第二行

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xed:num=4;break;

case 0xdd:num=5;break;

case 0xbd:num=6;break;

case 0x7d:num=12;break;//num=12表示乘号

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

}

}

P1=0xfb;//对矩阵键盘的第三行全赋0,扫描第三行

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xeb:num=1;break;

case 0xdb:num=2;break;

case 0xbb:num=3;break;

case 0x7b:num=11;break;//num=11表示减号

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

}

}

P1=0xf7;//对矩阵键盘的第四行全赋0,扫描第四行

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

delay(5);

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xe7:num=15;break;//num=15表示清零

case 0xd7:num=16;break;//num=16表示0

case 0xb7:num=14;break;//num=14表示等号

case 0x77:num=10;break;//num=10表示加号

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

}

}

return num;

}

void digit(uchar number)

{

write_com(0x80+a);

write_date(number+'0');

table[a]=tt;

delay(5);

tt=0;

num=0;

a++;

}

void input()

{

uint i,j;

tt=keyscan();

if(tt==15) //清零

{

write_com(0x01);

tt=0;

num=0;

a=0;

m=0;

flag1=0;

flag=0;

}

if(tt==1) digit(1);

if(tt==2) digit(2);

if(tt==3) digit(3);

if(tt==4) digit(4);

if(tt==5) digit(5);

if(tt==6) digit(6);

if(tt==7) digit(7);

if(tt==8) digit(8);

if(tt==9) digit(9);

if(tt==16)

{

write_com(0x80+a);

write_date(0+'0');

table[a]=0;

delay(5);

tt=0;

num=0;

a++;

}

if(tt==10)//检测到加号

{

m=1;//表示加法

shu1=0;

j=1;

write_com(0x80+a);

write_date('+');

delay(5);

flag=a;

for(i=flag;i>0;i--)

{

shu1+=(table[i-1]j);

j=10;

}

tt=0;

num=0;

a++;

}

if(tt==11)//检测到减号

{

m=2;//表示减法

shu1=0;

j=1;

write_com(0x80+a);

write_date('-');

delay(5);

flag=a;

for(i=flag;i>0;i--)

{

shu1+=(table[i-1]j);

j=10;

}

tt=0;

num=0;

a++;

}

if(tt==12)//检测到乘号

{

m=3;//表示乘法

shu1=0;

j=1;

write_com(0x80+a);

write_date('');

delay(5);

flag=a;

for(i=flag;i>0;i--)

{

shu1+=(table[i-1]j);

j=10;

}

tt=0;

num=0;

a++;

}

if(tt==13)//检测到除号

{

m=4;//表示除法

shu1=0;

j=1;

write_com(0x80+a);

write_date('/');

delay(5);

flag=a;

for(i=flag;i>0;i--)

{

shu1+=(table[i-1]j);

j=10;

}

tt=0;

num=0;

a++;

}

if(tt==14) //检测到等号

{

flag1=1;

write_com(0x80+a);

write_date('=');

shu2=0;

j=1;

for(i=a-1;i>flag;i--)

{

shu2+=(table[i]j);

j=10;

}

num=0;

tt=0;

}

}

void output()

{

uint value;

uchar n;

if((m==1)&&(flag1==1))//加的时候

{

value=shu1+shu2;

if(value>=0&&value<10)

{

val[0]=value;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10&&value<100)

{

val[0]=value/10;

val[1]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=100&&value<1000)

{

val[0]=value/100;

val[1]=value%100/10;

val[2]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=1000&&value<10000)

{

val[0]=value/1000;

val[1]=value%1000/100;

val[2]=value%1000%100/10;

val[3]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10000&&value<100000)

{

val[0]=value/10000;

val[1]=value%10000/1000;

val[2]=value%10000%1000/100;

val[3]=value%10000%1000%100/10;

val[4]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

}

if((m==2)&&(flag1==1))//减的时候

{

value=shu1-shu2;

if(value>=0&&value<10)

{

val[0]=value;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10&&value<100)

{

val[0]=value/10;

val[1]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=100&&value<1000)

{

val[0]=value/100;

val[1]=value%100/10;

val[2]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=1000&&value<10000)

{

val[0]=value/1000;

val[1]=value%1000/100;

val[2]=value%1000%100/10;

val[3]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10000&&value<100000)

{

val[0]=value/10000;

val[1]=value%10000/1000;

val[2]=value%10000%1000/100;

val[3]=value%10000%1000%100/10;

val[4]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

}

if((m==3)&&(flag1==1))//乘的时候

{

value=shu1shu2;

if(value>=0&&value<10)

{

val[0]=value;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10&&value<100)

{

val[0]=value/10;

val[1]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=100&&value<1000)

{

val[0]=value/100;

val[1]=value%100/10;

val[2]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=1000&&value<10000)

{

val[0]=value/1000;

val[1]=value%1000/100;

val[2]=value%1000%100/10;

val[3]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10000&&value<100000)

{

val[0]=value/10000;

val[1]=value%10000/1000;

val[2]=value%10000%1000/100;

val[3]=value%10000%1000%100/10;

val[4]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

}

if((m==4)&&(flag1==1))//除的时候

{

value=shu1/shu2;

if(value>=0&&value<10)

{

val[0]=value;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10&&value<100)

{

val[0]=value/10;

val[1]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=100&&value<1000)

{

val[0]=value/100;

val[1]=value%100/10;

val[2]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=1000&&value<10000)

{

val[0]=value/1000;

val[1]=value%1000/100;

val[2]=value%1000%100/10;

val[3]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

if(value>=10000&&value<100000)

{

val[0]=value/10000;

val[1]=value%10000/1000;

val[2]=value%10000%1000/100;

val[3]=value%10000%1000%100/10;

val[4]=value%10;

write_com(0xc0);

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

{

write_date(val[n]+'0');

delay(2);

}

}

}

}

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里

;===============================================

;五位无符号显示子程序

DIS1: MOV R0,#30H ;把显示数据第一位放在R0里

MOV R2,#04H ;把显示的位码放在R2里

MOV R3,#05H ;把显示的长度放在R3里

DIS2: MOV A,@R0

ANL A,#0FH ;屏蔽显示数据的高四位

MOV B,A

MOV A,R2

ANL A,#0FH ;屏蔽位码的高四位

SWAP A

ORL A,B

MOV P0,A ;送总显示数据到P0显示

LCALL DELY4ms ;调用延时4ms

INC R0 ;取下一个显示数据

DEC R2

DJNZ R3,DIS2 ;四位显示晚后重新开始显示

;===================================================

;键盘扫描子程序

WAIT: MOV P1,#0FFH ;P1口送高电平

CLR P10 ;第一行清零

MOV A,P1 ;读P1口

ANL A,#0F0H ;低位屏蔽

XRL A,#0F0H ;判断低位是否有低电平 ,即判断是否有按键按下

JZ NOKEY1 ;地位有低电平继续扫描,否者跳到第而行去扫描

LCALL DELY10ms ;延时10ms去抖在进行判断是否有按键按下

MOV A,P1 ;继续读P1口

ANL A,#0F0H ;判断低位是否有低电平

CJNE A,#0E0H,NK1 ;如果扫描数据不为0E0H就转到NK1

MOV KEYBUF,#0 ;否者判断为0号键

AJMP DK ;转DK1查表程序

NK1: CJNE A,#0D0H,NK2 ;如果扫描数据不为0D0H就转到NK2

MOV KEYBUF,#1 ;否者判断为1号键

AJMP DK ;转DK2查表程序

NK2: CJNE A,#0B0H,NK3 ;如果扫描数据不为0B0H就转到NK3

MOV KEYBUF,#2 ;否者判断为2号键

AJMP DK ;转DK3查表程序

NK3: CJNE A,#70H,NK4 ;如果扫描数据不为70H就转到NK4

LJMP SAN_CHU

NK4: NOP

NOKEY1: MOV P1,#0FFH ;和上面相同

CLR P11

MOV A,P1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY2

LCALL DELY10MS

MOV A,p1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY2

MOV A,P1

ANL A,#0F0H

CJNE A,#0E0H,NK5

MOV KEYBUF,#3

AJMP DK

NK5: CJNE A,#0D0H,NK6

MOV KEYBUF,#4

AJMP DK

NK6: CJNE A,#0B0H,NK7

MOV KEYBUF,#5

AJMP DK

NK7: CJNE A,#70H,NK8

MOV KEYBUF,#10 ;否者判断为3号键

AJMP DK ;转DK4查表程序

NK8: NOP

NOKEY2: MOV P1,#0FFH

CLR P12

MOV A,P1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY3

LCALL DELY10MS

MOV A,P1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY3

MOV A,P1

ANL A,#0F0H

CJNE A,#0E0H,NK9

MOV KEYBUF,#6

AJMP DK

NK9: CJNE A,#0D0H,NK10

MOV KEYBUF,#7

AJMP DK

NK10: CJNE A,#0B0H,NK11

MOV KEYBUF,#8

AJMP DK

NK11: CJNE A,#70H,NK12

LJMP DENG_HAO

NK12: NOP

NOKEY3: MOV P1,#0FFH

CLR P13

MOV A,P1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY4

LCALL DELY10MS

MOV A,P1

ANL A,#0F0H

XRL A,#0F0H

JZ NOKEY4

MOV A,P1

ANL A,#0F0H

CJNE A,#0E0H,NK13

LJMP CHU

NK13: CJNE A,#0D0H,NK14

LJMP CHENG

NK14: CJNE A,#0B0H,NK15

LJMP JIAN

NK15: CJNE A,#70H,NK16

LJMP JIA

NK16: NOP

;=======================================================

;查表求键值程序

DK: MOV B,#00H

MOV A,KEYBUF ;查表程序 查对应的键号数据

MOV DPTR,#TABLE ;把表头地址放入DPTR

MOVC A,@A+DPTR ;A里面存放的为键号,利用A和表头地址找到对应的键号数据

MOV B,A ;把查到的数据送往显示单元

INC R1 ;取下一个显示单元

MOV A,R1

CJNE A,#36H,DKA1 ;判断显示单元是否已满

MOV R1,#35H ;35H,36H单元用于更好的控制五位显示

AJMP DKA

DKA1: MOV 34H,33H ;按键代码按左移显示,先按先显示

MOV 33H,32H

MOV 32H,31H

MOV 31H,30H

MOV 30H,B

DKA: MOV A,P1 ;读P1口

ANL A,#0F0H ;屏蔽高四位

XRL A,#0F0H ;地位是有低电平

JNZ DKA ;如果有低电平继续读P1口,否者向下执行,查找第二行

NOKEY4: LJMP DIS1

;===================================

;功能按键功能设定

DENG_HAO:MOV DPTR,#JI_SUAN ;等号键功能通过加、减、乘、除设定的偏移量来调用子程序

MOV A,3CH ;3CH存放的为功能程序入口地址偏移量

JMP @A+DPTR ;转移到按键功能程序

JI_SUAN: AJMP JIA1 ;加计算子程序

AJMP JIAN1 ;减计算子程序

AJMP CHENG1 ;乘计算子程序

AJMP CHU ;除计算子程序

;=======删除键功能

SAN_CHU: ACALL QING_DIS

AJMP DKA

;=======加键功能

JIA: MOV 3CH,#00H

ACALL CUN_SHU

ACALL QING_DIS

AJMP DKA

;=======减键功能

JIAN: MOV 3CH,#02H

ACALL CUN_SHU

ACALL QING_DIS

AJMP DKA

;=======乘键功能

CHENG: MOV 3CH,#04H

ACALL CUN_SHU

ACALL QING_DIS

AJMP DKA

;=======除键功能

CHU: MOV 3DH,#06H

ACALL CUN_SHU

ACALL QING_DIS

AJMP DKA

;=================================

;存被加(减、乘、除)数,存放在37H~3BH里

CUN_SHU: MOV 37H,30H ;36H存放的为最低位

MOV 38H,31H

MOV 39H,32H

MOV 3AH,33H

MOV 3BH,34H ;3AH存放的为最高位

RET

;================================

;清除显示单元

QING_DIS: MOV R1,#30H

QING1: MOV @R1,#00H

INC R1

MOV A,R1

CJNE A,#36H,QING1

MOV R1,#30H

LOP1: RET

;================================

;十进制加法子程序

JIA1:

MOV A,37H ;个位被加数

ADD A,30H ;个位被加数+加数

MOV B,#10 ;十六进制除10转换成BCD码

DIV AB

MOV 30H,B ;余数即个位存放在30H

MOV 37H,A ;商存放在37H

MOV A,38H ;十位被加数

ADD A,31H ;十位被加数+加数

ADD A,37H ;加上个位之和的进位

MOV 37H,#00H ;清除37H

MOV B,#10 ;十六进制除10转换成BCD码

DIV AB

MOV 31H,B ;余数即十位存放在31H

MOV 38H,A ;商存放在38H

MOV A,39H ;百位计算同十位

ADD A,32H

ADD A,38H

MOV 38H,#00H

MOV B,#10

DIV AB

MOV 32H,B

MOV 39H,A

MOV A,3AH ;千位计算同十位

ADD A,33H

ADD A,39H

MOV 39H,#00H

MOV B,#10

DIV AB

MOV 33H,B

MOV 3AH,A

MOV A,3BH ;万位计算同十位

ADD A,34H

ADD A,3AH

MOV 3AH,#00H

MOV B,#10

DIV AB

MOV 34H,B

MOV 3BH,#00H

AJMP DKA

;=====================

JIAN1: AJMP DKA

CHENG1: AJMP DKA

CHU1: AJMP DKA

;=============================================

;延时程序和查表表格

DELY4ms: MOV R6,#8 ;延时4毫秒

D1: MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

RET

DELY10ms:MOV R6,#20 ;延时10毫秒

D2: MOV R7,#248

DJNZ R7,$

DJNZ R6,D2

RET

TABLE: DB 07H, 04H, 01H ; / 本表格是以键盘为参考 7 8 9 /

DB 08H, 05H, 02H ; 4 5 6

DB 09H, 06H, 03H ; - 1 2 3 -

DB 00H, 00H ;= + 清除 0 = +

END

要求还不低,i简单的我有,不能实现混合运算比较

主程序如下:

void main()

{ while(1)

{

c=1;

while(c<7)//输入第1个6 位数

{

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;

case 6:b6=keyval; break;

}

c++;

}

display(b1,b2,b3,b4,b5,b6);

}

while(c==7) //输入计算符号

{

keyval=keyscan();

if(keyval>=10)

{

d=keyval;

}

c=1;

}

while(c<7) //输入第2个6 位数

{

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;

case 6:d6=keyval; break;

}

c++;

}

display(d1,d2,d3,d4,d5,d6);

}

P1=0;

bb= b1100000+b210000+b31000+b4100+b510+b6;

dd=d1100000+d210000+d31000+d4100+d510+d6;

while(keyval!=15) //等待按下"="号

{

keyval=keyscan();

}

delay(100);

switch(d1)//根据输入的运算符,作不同的运算

{

case 10:ee=bb+dd; break;//加

case 11:

flag1=0;

if(bb>=dd)//减

{

ee=bb-dd;

flag1=1;;//flag 是正负号标志

}

else ee=bb-dd;

break;

case 12:ee=bbdd; break;//乘

case 13:ee=bb/dd; break; //除

}

f1=ee/100000%10;;// 分离 个十百千万

f2=ee/10000%10;

f3=ee/1000%10;

f4=ee/100%10;

f5=ee/10%10;

f6=ee%10;

display(f1,f2,f3,f4,f5,f6);//显示运算结果

}

}

我以前做过4x4键盘控制电动机转速,用数码管显示电机转速的程序,程序如下:

AD EQU 30H

RTR EQU 31H

LTR EQU 32H

STR EQU 33H

BW EQU 34H

BWS EQU 35H

SHW EQU 36H

SHWS EQU 37H

GW EQU 38H

GWS EQU 39H

WSHR EQU 3AH;WSHR=BWS100+SHWS10+GWS

sz EQU 3BH;数字与代码对应程序的数字变量

xsm EQU 3CH;数字与代码对应程序的代码变量

TODH EQU 3DH;计算的10进位数的高位电机的要求转速高位

TODL EQU 3EH;计算的10进位数的低位电机的要求转速低位

TODHT EQU 3FH;测试后电机的实际转速高位

TODLT EQU 40H;测试后电机的实际转速低位

PCK EQU 41H;pc口当前的状态植

TOH EQU 42H;定时器高位数

T0L EQU 43H;定时器低位数

pink1 EQU 44H;电机转动1/4圈定时器1的奇数次数

pink2 EQU 45H

VTIMES EQU 46H;速度显示次数

T1H EQU 47H

T1L EQU 48H

TESTK DATA 49H ;高电平脉冲的个数

TTH0 EQU 1AH

TTL0 EQU 4BH

SUBNOW EQU 4CH

ORG 0000H

LJMP MAIN

ORG 03H

AJMP INTR0;中段0,用来计算电机转速

ORG 0BH

MOV A,PCK

ANL A,#00000111B

MOV PCK,A

MOV A,#00000110B

CJNE A,PCK,INTT0LF

LJMP INTT0L;

ORG 1BH;pwm停转子程序

AJMP INTT0H

ORG 0040H

;定时器中断子程序

;电机停止程序

INTT0H:

mov th0,TOH

mov tl0,T0L

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

INC pink1

MOV DPTR,#7F02H; b地址

MOV A, #00000000B;电机停止运动

MOVX @DPTR,A

reti

;电动机正转子程序

INTT0L:

mov th1,T1H

mov tl1,T1L

SETB TR1;定时器1开始计数

CLR TR0;定时器0禁止计数

MOV DPTR,#7F02H; b地址

MOV A, #11001100B;C口输出片选号灯

MOVX @DPTR,A

reti

;电动机反转

INTT0LF:

mov th1,T1H

mov tl1,T1L

SETB TR1;定时器1开始计数

CLR TR0;定时器0禁止计数

MOV DPTR,#7F02H; b地址

MOV A, #10101100B;C口输出片选号灯

MOVX @DPTR,A

reti

;计算电机转速

;R2R3R4R5/ R6R7=R4R5余R2R3////(R2R3R4/R7)=(R2)R3R4 余数R7

INTR0:

MOV R2,#00H

MOV R3,#0EH

MOV R4,#0A6H

MOV R7,pink1

MOV pink1,#0

MOV A,#10

CLR CY

SUBB A,R7

JNB CY,OUTINT0

LCALL NDIV31

MOV TODHT, R3

MOV TODLT,R4

MOV R6,TODH

MOV R7,TODL

CLR CY

MOV A,R4

SUBB A,R7

MOV SUBNOW,A

JB CY,ADV

LCALL SUBV

JMP OUTINT0

ADV:

LCALL ADDV

OUTINT0:

LCALL JSW;计算各位的数值毫时大大约600个始周期 ;MOV TODLT,TOH

;LCALL JSW;计算各位的数值毫时大大约600个始周期

RETI;

;

;

COMP_M:

MOV A,#0FDH

SUBB A,TOH

JNB CY,OUT_PMM

MOV TOH,#0FDH

MOV T1H,#85

OUT_PMM:

RET

;加速子程序

ADDV:

CLR EA

CLR TR1

CLR TR0

MOV R1,SUBNOW

MOV R0,#10000000B

FRT:

MOV A,R0

RL A

MOV R0,A

MOV A,R1

ANL A,R0

JZ FRT

MOV A,TOH

ADD A,R0

JC VMAX

MOV TOH,A

MOV A,T1H

SUBB A,R0

MOV T1H,A

JMP TXT

VMAX:

MOV TOH,#0FDH

MOV T1H,#85

TXT:

SETB TR0

SETB TR1

SETB EA

RET

;减加速子程序

SUBV:

CLR EA

CLR TR1

CLR TR0

MOV R1,SUBNOW

MOV R0,#10000000B

FRT1:

MOV A,R0

RL A

MOV R0,A

MOV A,R1

ANL A,R0

JZ FRT1

MOV A,TOH

SUBB A,R0

JC VMAX1

MOV TOH,A

MOV A,T1H

ADD A,R0

MOV T1H,A

JMP TXT1

VMAX1:

MOV TOH,#85

MOV T1H,#0FDH

TXT1:

SETB TR0

SETB TR1

SETB EA

RET

;主程序

MAIN:

MOV BW,#7DH

MOV SHW,#7DH

MOV GW,#7DH

MOV BWS,#0

MOV SHWS,#0

MOV GWS,#0

MOV SP,#0A0H

MOV TOH,#0A1h;

MOV T0L,#0h;

MOV T1H,#0E1h;

MOV T1L,#37h;

MOV TMOD,#00H;定时器0在模式1下工作

MOV RTR,#00110110B

MOV LTR,#00101101B

MOV PCK,#00H

MOV TODHT,#2

MOV TODLT,#25H

MOV TODH,#0

MOV TODL,#0

;LCALL JSTIM;计算总值TODH;TODL

MOV pink2,#0

MOV pink1,#0

SETB EX0

SETB IT0

START:

MOV DPTR,#7F00H; 状态字地址

MOV A, #00111111B;设A,B,C口均为输出

MOVX @DPTR,A

LCALL DISPLAY;显示

LCALL KEYSC;扫描键盘

;MOV TESTK,#44H;TEST

ACALL DISPKEYV ;确定键盘

;LCALL JSTIM;计算总值TODH;TODL

;LCALL JSW;计算各位的数值毫时大大约600个始周期

LCALL JSEHW;计算各个代码

JMP START

;键盘扫描程序

KEYSC:

MOV TESTK,#0

mov p1,#0FH ;p10-3输出1,作为输入位

mov a ,p1

ANL A,#0FH

CJNE A,#0FH,DELAY

RET

DELAY: ACALL DELAY1 ; 延时去键抖

mov a ,p1

ANL A,#0FH

CJNE A,#0FH,HAVE

RET

HAVE:

MOV A,#0EFH ;行扫描码

NEXT:

MOV B,A

MOV P1,A

MOV A,p1

ANL A,#0FH ;检测列

CJNE A,#0FH,YES

MOV A,B

RL A

CJNE A,#0FEH,NEXT

YES: orl a,#0f0h ;高四位置1

CPL A

mov r2,#00h

MOV R2,A ;存列码

MOV A,B ;取行码,

CPL A

ORL A,R2 ;列码+行码=键植

MOV AD,#00H

MOV TESTK,A

RET

;确定键盘程序

DISPKEYV:MOV A,TESTK

KEY0:CJNE A,#11H,KEY1

acall WORD0

KEY1:CJNE A,#12H,KEY2

acall WORD1

KEY2:CJNE A,#14H,KEY3

acall WORD2

KEY3:CJNE A,#18H,KEY4

acall WORD3

KEY4:CJNE A,#21H,KEY5

acall WORD4

KEY5:CJNE A,#22H,KEY6

acall WORD5

KEY6:CJNE A,#24H,KEY7

acall WORD6

KEY7:CJNE A,#28H,KEY8

acall WORD7

KEY8:CJNE A,#41H,KEY9

acall WORD8

KEY9:CJNE A,#42H,KEY10

acall WORD9

KEY10:CJNE A,#44H,KEY11

acall WORD10

KEY11:CJNE A,#48H,KEY12

acall WORD11

KEY12:CJNE A,#81H,KEY13

acall WORD12

KEY13:CJNE A,#82H,KEY14

acall WORD13

KEY14:CJNE A,#84H,KEY15

acall WORD14

KEY15:

CJNE A,#88H,PASS

AJMP WORD15

PASS:RET

WORD0:

lCALL MOVE

MOV A,#0

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK0:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT0

JMP TSTK0

OUT0:

MOV R0,#0

RET

WORD1:

lCALL MOVE

MOV A,#1

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK1:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT1

JMP TSTK1

OUT1:

MOV R0,#0

RET

WORD2:

lCALL MOVE

MOV A,#2

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK2:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT2

JMP TSTK2

OUT2:

MOV R0,#0

ACALL JSEHW;计算各个位的显示代码

RET

WORD3:

lCALL MOVE

MOV A,#3

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK3:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT3

JMP TSTK3

OUT3:

MOV R0,#0

ACALL JSEHW;计算各个位的显示代码

RET

WORD4:

lCALL MOVE

MOV A,#4

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK4:

LCALL KEYSC

CJNE A,TESTK,OUT4

JMP TSTK4

OUT4:

ACALL JSEHW;计算各个位的显示代码

RET

WORD5:

lCALL MOVE

MOV A,#5

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK5:

LCALL KEYSC

CJNE A,TESTK,OUT5

JMP TSTK5

OUT5:

ACALL JSEHW;计算各个位的显示代码

RET

WORD6:

lCALL MOVE

MOV A,#6

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK6:

LCALL KEYSC

CJNE A,TESTK,OUT6

JMP TSTK6

OUT6:

ACALL JSEHW;计算各个位的显示代码

RET

WORD7:

lCALL MOVE

MOV A,#7

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK7:

LCALL KEYSC

CJNE A,TESTK,OUT7

JMP TSTK7

OUT7:

ACALL JSEHW;计算各个位的显示代码

RET

WORD8:

lCALL MOVE

MOV A,#8

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK8:

LCALL KEYSC

CJNE A,TESTK,OUT8

JMP TSTK8

OUT8:

ACALL JSEHW;计算各个位的显示代码

RET

WORD9:

lCALL MOVE

MOV A,#9

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK9:

LCALL KEYSC

CJNE A,TESTK,OUT9

JMP TSTK9

OUT9:

ACALL JSEHW;计算各个位的显示代码

RET

WORD10:

CLR EA

CLR ET0

CLR TR0

mov th0,TOH

mov tl0,T0L

MOV PCK,#00000110B

SETB EA;打开所有中断

SETB ET0;定时器允许中断

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

SETB ET1;定时器1允许中断

RET

WORD11:

CLR EA

CLR ET0

CLR TR0

mov th0,TOH

mov tl0,T0L

MOV PCK,#00000101B

SETB EA;打开所有中断

SETB ET0;定时器允许中断

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

SETB ET1;定时器1允许中断

RET

WORD12:

LCALL ADDV

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

MOV A,TESTK

TSTK12:

LCALL KEYSC

CJNE A,TESTK,OUT12

JMP TSTK12

OUT12:

RET

WORD13:

LCALL SUBV

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

MOV A,TESTK

TSTK11:

LCALL KEYSC

CJNE A,TESTK,OUT11

JMP TSTK11

OUT11:

RET

WORD14:

CLR ET0;使能定时器0中断

CLR ET1;使能定时器1中断

CLR EA;使能总中断

CLR TR1;关闭T1计时

CLR TR0;关闭T0计时

MOV PCK,#00H

MOV BW,#7DH

MOV SHW,#7DH

MOV GW,#77H

RET

WORD15:JB EA,MID15

MOV BWS,#0

MOV SHWS,#0

MOV GWS,#0

JMP OUT15

MID15:

CLR EA

MOV A,TESTK

TSTK15:

LCALL KEYSC

CJNE A,TESTK,OUT15

JMP TSTK15

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

OUT15:

SETB EA

RET

;计算各个代码

JSEHW:

MOV SZ,BWS

ACALL js

MOV BW,xsm

MOV SZ,SHWS

ACALL js

MOV SHW,xsm

MOV SZ,GWS

ACALL js

MOV GW,xsm

RET

js:

mov a,sz

js0:cjne a,#0,js1

mov xsm,#7dh

js1:cjne a,#1,js2

mov xsm,#14h

js2:cjne a,#2,js3

mov xsm,#6eh

js3:cjne a,#3,js4

mov xsm,#3eh

js4:cjne a,#4,js5

mov xsm,#17h

js5:cjne a,#5,js6

mov xsm,#3bh

js6:cjne a,#6,js7

mov xsm,#7bh

js7:cjne a,#7,js8

mov xsm,#00011100B

js8:cjne a,#8,js9

mov xsm,#7fh

js9:cjne a,#9,js10

mov xsm,#3fh

js10:ret

;计算各位的数值毫时大大约600个始周期

JSW:;(R2R3R4/R7)=(R2)R3R4 余数R7

MOV R2,#0

MOV R3,TODHT

MOV R4, TODLT

MOV R7,#100

LCALL NDIV31

MOV BWS,R4

MOV A,R7;

MOV R4,A

MOV R3,#0

MOV R2,#0

MOV R7,#10

LCALL NDIV31

MOV SHWS,R4

MOV GWS,R7

RET

;计算十进制结果

JSTIM:

MOV TODL,#0

MOV TODH,#0

MOV A,GWS

MOV B,#1

ACALL JSHL

MOV A,SHWS

MOV B,#10

ACALL JSHL

MOV A,BWS

MOV B,#100

ACALL JSHL

RET

JSHW:

JB OV,JSGW

CLR OV

RET

JSGW:

INC TODH;TEST DATE

RET

JSHL:

MUL AB

MOV R1,B

ADD A,TODL

MOV TODL,A

MOV A,B

ADDC A,TODH

MOV TODH,A

ACALL JSHW

RET

;单字节的除法

;(R2R3R4/R7)=(R2)R3R4 余数R7

NDIV31 :MOV A,R2

MOV B,R7

DIV AB

MOV R2,B

MOV B,#10H

NDV311 :CLR C

MOV A,R4

RLC A

MOV R4,A

MOV A,R3

RLC A

MOV R3,A

MOV A,R2

RLC A

MOV R2,A

MOV F0,C

CLR C

SUBB A,R7

JB F0,NDV312

JC NDV313

NDV312 :MOV R2,A

INC R4

NDV313 :DJNZ B,NDV311

CLR OV

JZ NDV314

SETB OV

NDV314 :XCH A,R2

MOV R7,A

RET

;双字节减法(R3R4-R6R7)=(R3R4)

NSUB :MOV A,R4

CLR C

SUBB A,R7

MOV R4,A

MOV A,R3

SUBB A,R6

MOV R3,A

RET

DELAY1:

MOV R5,#10

D1: MOV R6,#250

DJNZ R6, $

DJNZ R5,D1

RET

DELAY_BS:

MOV R5,#5

D2: MOV R6,#99

D3: MOV R7,#99

DJNZ R7, $

DJNZ R6,D3

DJNZ R5,D2

RET

;显示器显示子程序

DISPLAY:

MOV DPTR,#7F01H;

MOV A, BW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A, #00011000B;C口输出片选号灯

MOV R0,PCK;pck=

ORL A,R0;a=11

MOV R0,#00011111B;a=00011

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

MOV DPTR,#7F01H;

MOV A, SHW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A,#00101000B

ORL A,R0

MOV R0,#00101111B

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

MOV DPTR,#7F01H;

MOV A, GW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A, #00110000B;C口输出片选号灯

ORL A,R0

MOV R0,#00110111B

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

mov a,#0ffh

MOVX @DPTR,A

RET

D_40ms:

MOV R7,#10

DELAYBB:

MOV R6,#10

NOP

DELAYNN:

DJNZ R6,DELAYNN; 2X198+2=398

DJNZ R7,DELAYBB; (398+2)X200+1=80ms

RET

;各个位移位自程序

MOVE:

MOV A,SHWS

MOV BWS,A

MOV A,GWS

MOV SHWS,A

RET

END

以上就是关于单片机设计计算器全部的内容,包括:单片机设计计算器、用89C51单片机设计4*4矩阵式键盘计算器程序 要汇编的、51单片机计算器,运算部分和结果显示怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9411467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存