求助,关于AT89C51单片机简易计算器设计的程序,最好是关于C语言的。谢谢哈。

求助,关于AT89C51单片机简易计算器设计的程序,最好是关于C语言的。谢谢哈。,第1张

下面是我用STC89C52单片机编的程序,采用44矩阵键盘,键盘接P3口,采用六位数码管(共阴极)显示,数码管位选和片选信号分别通过两个锁存器接P0口,位选所存端接P^7口,段选所存端接P2^6口。矩阵键盘的具体接法和各位表示的含义楼主可以从程序里看的出来,楼主可以根据自己的硬件对我的程序加以修改应该就会好使,下面的程序是我自己设计的,并且用硬件检验过好使,可以实现两个整数的加减乘除,和平方,祝你成功!

#include<reg52h>

#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=10num1+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=num2num3;break;

case 4:num4=num2/num3;break;

case 5:num4=num2num2;break;

}

}

}

void main()

{

while(1)

{

jisuan();

jieguo();

display(num4);

}

}

我用的是51单片机,你也可以把它改成你需要的即可。程序如下:

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

uchar code DSY_CODE[]=

{

0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff

};

uchar Num_Buffer[] = {0,0,0};

uchar Key_Code,Key_Counts=0;

void DelayMS(uint x)

{

uchar t;

while(x--)

{

for(t=0;t<120;t++);

}

}

void Show_Counts_ON_DSY()

{

uchar i,j=0x01;

Num_Buffer[2]=Key_Counts/100;

Num_Buffer[1]=Key_Counts/10%10;

Num_Buffer[0]=Key_Counts%10;

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

{

j = _cror_(j,1);

P2 = j;

P0 = DSY_CODE[Num_Buffer[i]];

DelayMS(1);

}

}

void main()

{

uchar i;

P0 = 0xff;

P1 = 0xff;

P2 = 0x00;

Key_Code = 0xff;

while(1)

{

Show_Counts_ON_DSY();

P1 = 0xff;

Key_Code = P1;

if(Key_Code != 0xff)

{

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

{

Show_Counts_ON_DSY();

}

}

switch(Key_Code)

{

case 0xfe:if(Key_Counts<255)

Key_Counts++;break;

case 0xfd:if(Key_Counts>0)

Key_Counts--;break;

case 0xfb:Key_Counts=0;

}

Key_Code = 0xff;

要求还不低,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);//显示运算结果

}

}

这是一个简易的计算器,有加减乘除运算。

#include<reg51h>

#define uchar unsigned char;

uchar LED1,LED2,LED3,LED4;

uchar keyval,calflag,s_dat,d_dat;

uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};

unsigned int number,r_dat;

void delay(unsigned int a)

{

unsigned int i,j;

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

for(j=0;j<1000;j++);

}

void dealdat()

{

switch(calflag)

{

case 0:

r_dat=s_dat+d_dat;

break;

case 1:

r_dat=s_dat-d_dat;

break;

case 2:

r_dat=s_datd_dat;

break;

case 3:

r_dat=s_dat/d_dat;

break;

default:break;

}

LED1=(r_dat/1000)%10;

LED2=(r_dat/100)%10;

LED3=(r_dat/10)%10;

LED4=r_dat%10;

}

uchar kbscan(void)

{

unsigned char sccode,recode;

P3=0x0f; //发0扫描,列线输入

if ((P3 & 0x0f) != 0x0f) //有键按下

{

delay(20); //延时去抖动

if ((P3&0x0f)!= 0x0f)

{

sccode = 0xef; //逐行扫描初值

while((sccode&0x01)!=0)

{

P3=sccode;

if((P3&0x0f)!=0x0f)

{

recode=(P3&0x0f)|0xf0;

return((~sccode)+(~recode));

}

else

sccode=(sccode<<1)|0x01;

}

}

}

return 0; //无键按下,返回0

}

void getkey(void)

{

unsigned char key;

key=kbscan();

if(key==0){keyval=0xff;return;}

switch(key)

{

case 0x11:keyval=7;break;

case 0x12:keyval=4;break;

case 0x14:keyval=1;break;

case 0x18:keyval=10;break;

case 0x21:keyval=8;break;

case 0x22:keyval=5;break;

case 0x24:keyval=2;break;

case 0x28:keyval=0;break;

case 0x41:keyval=9;break;

case 0x42:keyval=6;break;

case 0x44:keyval=3;break;

case 0x48:keyval=11;break;

case 0x81:keyval=12;break;

case 0x82:keyval=13;break;

case 0x84:keyval=14;break;

case 0x88:keyval=15;break;

default:keyval=0xff;break;

}

}

void t0isr() interrupt 1

{

TH0=0xf4;

TL0=0x48;

switch(number)

{

case 0:P2=0x04;P0=distab[LED1];break;

case 1:P2=0x08;P0=distab[LED2];break;

case 2:P2=0x01;P0=distab[LED3];break;

case 3:P2=0x02;P0=distab[LED4];break;

default:break;

}

number++;

if(number>3)number=0;

}

main()

{

TMOD = 0x01;

number = 0;

TH0=0xf4;

TL0=0x48;

TR0=1;

ET0=1;

EA=1;

LED1=0;

LED2=0;

LED3=0;

LED4=0;

while(1)

{

getkey();

switch(keyval)

{

case 0:

case 1:

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

LED3=LED4;

LED4=keyval;

LED1=0;

LED2=0;

break;

case 10:break; //"ON"

case 11: //"="

d_dat=LED310+LED4;

dealdat();

break;

case 12: //"/"

calflag=3;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 13: //""

calflag=2;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 14: //"-"

calflag=1;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 15: //"+"

calflag=0;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

default:break;

}

}

}

以上就是关于求助,关于AT89C51单片机简易计算器设计的程序,最好是关于C语言的。谢谢哈。全部的内容,包括:求助,关于AT89C51单片机简易计算器设计的程序,最好是关于C语言的。谢谢哈。、用单片机设计1位十进制加法计算器,、51单片机计算器,运算部分和结果显示怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/9388502.html

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

发表评论

登录后才能评论

评论列表(0条)

保存