单片机计算器资料.docx

上传人:b****8 文档编号:28700627 上传时间:2023-07-19 格式:DOCX 页数:22 大小:17.88KB
下载 相关 举报
单片机计算器资料.docx_第1页
第1页 / 共22页
单片机计算器资料.docx_第2页
第2页 / 共22页
单片机计算器资料.docx_第3页
第3页 / 共22页
单片机计算器资料.docx_第4页
第4页 / 共22页
单片机计算器资料.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

单片机计算器资料.docx

《单片机计算器资料.docx》由会员分享,可在线阅读,更多相关《单片机计算器资料.docx(22页珍藏版)》请在冰豆网上搜索。

单片机计算器资料.docx

单片机计算器资料

#include"reg52.h"

#include"math.h"

//#include"lcd1602_8.h"

#defineuintunsignedint

#defineucharunsignedchar

uinttemp,num;//键盘扫描数值

ucharkeynum1=0,keynum2=0,sign=0,i=0,j=0;//按键计数,符号标示

ucharnum1[8]={0},num2[8]={0};//按键存储数组

floatans1=0,ans2=0,ans=0,point=0;//运算数据

bitconflag=0;//继续运算标志位

bitnewcalc=0;//新运算标志位

bitac=0;//清零标志,1为清零

bitbeepflag=0;//蜂鸣器标志位

bitsqrtflag1=0;//开方1标志位

bitsqrtflag2=0;//开方2标志位

sbitkeybeep=P3^3;//蜂鸣器开关按键

sbitbeep=P2^7;//蜂鸣器控制口

sbitkeysqrt=P3^4;//开方按键

sbitkeypow=P3^5;//任意次方按键

sbitLCDRS=P2^0;

sbitLCDRW=P2^1;

sbitLCDEN=P2^2;

ucharkeyscan();

voidmaininit(void);

//附4:

LCD1602显示程序

//#include

//#include"lcd1602_8.h"

//#include

//延时1ms程序

voiddelayms(uintx)//12M延时1ms

{

unsignedintTempMS=x*110;

while(TempMS--);

}

//写命令

voidlcdwrite_com(uchari)

{

P0=i;

LCDRS=0;

LCDRW=0;

LCDEN=0;

delayms

(1);

LCDEN=1;

}

//写数据

voidlcdwrite_data(uchari)

{

P0=i;

LCDRS=1;

LCDRW=0;

LCDEN=0;

delayms

(1);

LCDEN=1;

}

//写字符串

voidlcdwrite_string(uchar*s)

{

while(*s)

{

lcdwrite_data(*s);

s++;

}

}

//设置lcd光标值

voidlcd_setxy(ucharx,uchary)

{

ucharaddress;

y&=0x0f;

if(!

x)

address=0x80+y;//0在第一行

else

address=0xc0+y;//1在第二行

lcdwrite_com(address);

}

//显示1位数字

voidlcdwrite_num1(uintn)

{

lcdwrite_data(n+48);

}

//显示任意位数字

voidlcdwrite_num(longn)

{

ucharlength=0,j,a[8]={0,0,0,0,0,0,0,0};

longnx;

if(n==0)

{

lcdwrite_data('0');

return;

}

if(n<0)

{

lcdwrite_data('-');

n=0-n;

}

nx=n;

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

{

if(nx>=1)

length++;

nx/=10;

}

nx=n;

for(;length>0;length--)

{

a[length-1]=nx%10+0x30;

nx/=10;

}

lcdwrite_string(a);

}

//显示7位小数

voidlcdwrite_float(floatn)

{

uchari=0;

uintj=0;

longnxtemp;

if(n==0)

{

lcdwrite_data('0');

return;

}

if(n<0)

{

lcdwrite_data('-');

n=0-n;

}

nxtemp=n;

n=n;//+0.000002;

lcdwrite_num(nxtemp);

if((n-nxtemp)>0.000009)

{

lcdwrite_data('.');

n=(n-nxtemp)*10000000;

//n=n-1;

nxtemp=n;

//if(nxtemp%10!

=0)

lcdwrite_data(nxtemp/10000000+0x30);//显示第7位小数

if((nxtemp%1000000%100000%10000%1000%100/10!

=0)||(nxtemp%1000000%100000%10000%1000/100!

=0)||(nxtemp%1000000%100000%10000/1000!

=0)||(nxtemp%1000000%100000/10000!

=0)||(nxtemp%1000000/100000!

=0))

lcdwrite_data(nxtemp%1000000/100000+0x30);//显示第6位小数

if((nxtemp%1000000%100000%10000%1000%100/10!

=0)||(nxtemp%1000000%100000%10000%1000/100!

=0)||(nxtemp%1000000%100000%10000/1000!

=0)||(nxtemp%1000000%100000/10000!

=0))

lcdwrite_data(nxtemp%1000000%100000/10000+0x30);//显示第5位小数

if((nxtemp%1000000%100000%10000%1000%100/10!

=0)||(nxtemp%1000000%100000%10000%1000/100!

=0)||(nxtemp%1000000%100000%10000/1000!

=0))

lcdwrite_data(nxtemp%1000000%100000%10000/1000+0x30);//显示第4位小数

if((nxtemp%1000000%100000%10000%1000%100/10!

=0)||(nxtemp%1000000%100000%10000%1000/100!

=0))

lcdwrite_data(nxtemp%1000000%100000%10000%1000/100+0x30);//显示第3位小数

if(nxtemp%1000000%100000%10000%1000%100/10!

=0)

lcdwrite_data(nxtemp%1000000%100000%10000%1000%100/10+0x30);//显示第2位小数

//lcdwrite_data(nxtemp%10+0x30);//显示第1位小数

}

elsereturn;

}

//初始化液晶

voidlcd_init(void)

{

lcdwrite_com(0x01);//显示清屏

lcdwrite_com(0x01);//显示清屏

lcdwrite_com(0x38);//设置成1602显示

delayms(5);

lcdwrite_com(0x38);//设置成1602显示

delayms(5);

lcdwrite_com(0x38);//设置成1602显示

delayms(5);

//lcdwrite_com(0x0f);//开显示0x0e显示开,光标开

lcdwrite_com(0x0c);//显示开

lcdwrite_com(0x06);//设置光标移动方向增量方式,并指定显示不移动。

//lcdwrite_com(0x05);//设置光标移动方向减量方式,并指定显示移动。

(光标不移动而整个屏幕移动)

//lcdwrite_com(0x07);//(当写一个字符,整屏显示左移)

}

//初始化程序

voidmaininit(void)

{

delayms(100);//等待液晶初始化

lcd_init();

lcd_setxy(0,0);

lcdwrite_data('0');

lcd_setxy(0,0);

IT0=1;//下降沿触发

EX0=1;//开外部中断0

IT1=1;//下降沿触发

EX1=1;//开外部中断1

EA=1;//开全局中断

}

//清零中断程序

voidEX0_int()interrupt0

{

if(beepflag==1)//若开声音则每一次按键均鸣叫

{

beep=0;

delayms(100);

beep=1;

}

lcdwrite_com(0x01);//显示清屏

lcd_setxy(0,0);

lcdwrite_data('0');

lcd_setxy(0,0);

num='N';//数字初始化

keynum1=0,keynum2=0,sign=0;

ans1=0,ans2=0,ans=0,point=0;

conflag=0,newcalc=0;

ac=1;

}

//声音中断程序

voidEX1_int()interrupt2

{

beepflag=~beepflag;

if(beepflag==1)//若开声音则每一次按键均鸣叫

{

beep=0;

delayms(100);

beep=1;

}

}

//按键扫描程序

ucharkeyscan()

{

num='N';//若没有按下任何按键,则返回‘N’

P1=0xfe;//扫描第一行

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)//扫描列

{

delayms(10);

temp=P1;

switch(temp)

{

case0xee:

num='+';

break;

case0xde:

num='=';

break;

case0xbe:

num='.';

break;

case0x7e:

num=0;

break;

}

while(temp!

=0xf0)//等待松手

{

temp=P1;

temp=temp&0xf0;

}

}

P1=0xfd;//扫描第二行

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)//扫描列

{

delayms(10);

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=P1;

switch(temp)

{

case0xed:

num='-';

break;

case0xdd:

num=3;

break;

case0xbd:

num=2;

break;

case0x7d:

num=1;

break;

}

while(temp!

=0xf0)

{

temp=P1;

temp=temp&0xf0;//等待松手

}

}

}

P1=0xfb;//扫描第三行

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)//扫描列

{

delayms(10);

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=P1;

switch(temp)

{

case0xeb:

num='*';

break;

case0xdb:

num=6;

break;

case0xbb:

num=5;

break;

case0x7b:

num=4;

break;

}

while(temp!

=0xf0)//等待松手

{

temp=P1;

temp=temp&0xf0;

}

}

}

P1=0xf7;//扫描第四行

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)//扫描列

{

delayms(10);

temp=P1;

temp=temp&0xf0;

while(temp!

=0xf0)

{

temp=P1;

switch(temp)

{

case0xe7:

num='/';

break;

case0xd7:

num=9;

break;

case0xb7:

num=8;

break;

case0x77:

num=7;

break;

}

while(temp!

=0xf0)

{

temp=P1;

temp=temp&0xf0;//等待松手

}

}

}

if(keypow==0)

{

delayms(5);

if(keypow==0)

{

//powflag=1;

num='^';

}

while(keypow==0);//扫描多次方按键

delayms(5);

while(keypow==0);

}

if(beepflag==1&&num!

='N')//若开声音则每一次按键均鸣叫

{

beep=0;

delayms(100);

beep=1;

}

returnnum;

}

//主程序

voidmain(void)

{

maininit();//初始化

while

(1)//整个系统大循环,让计数器一直处于工作状态

{

while

(1)//第一运算数扫描

{

if(ac==1)break;//若清零则退出输入

if((keyscan()!

='N')&&((num>=0&&num<=9)||num=='.'))//记录按下的数字

{

if(newcalc==1)//新一次运算开始

{

lcdwrite_com(0x01);//清屏

newcalc=0;

lcd_setxy(0,0);

}

if(keynum1<=7)//限制输入位数

{

if(num=='.')

{

lcdwrite_data('.');//显示小数点

}

else

lcdwrite_num1(num);

num1[keynum1]=num;

keynum1++;

}

}

elseif(num=='+'||num=='-'||num=='*'||num=='/'||num=='='||num=='^'||keysqrt==0)

{

if(keynum1==0&&num1[0]==0)//若直接输入运算符而没有输入数字则执行连续运算

{

here:

ans1=ans;

sign=num;

lcdwrite_com(0x01);

delayms(5);

lcd_setxy(0,0);

lcdwrite_float(ans1);

if(sqrtflag2!

=1&&num!

='N')lcdwrite_data(num);

break;

}

for(i=0;keynum1>0;i++)//计算按下的数字的大小

{

if(num1[i]!

='.')ans1=ans1*10+num1[i];

elseif(num1[i]=='.')

break;

keynum1--;

}

for(keynum1--,i++,j=0;keynum1>0;j++,i++,keynum1--)point=point*10+num1[i];

for(;j>0;j--)point*=0.1;

ans1=ans1+point;

sqrtflag1=0;//清除开方标志

sqrtflag2=0;//清除开方标志

if(keysqrt==0)//计算开方

{

delayms(5);

if(keysqrt==0)

{

if(beepflag==1)//若开声音则每一次按键均鸣叫

{

beep=0;

delayms(100);

beep=1;

}

ans=sqrt(ans1);

sqrtflag1=1;

lcdwrite_data(0xe8);

while(keysqrt==0);

delayms(10);

while(keysqrt==0);

break;

}

}

sign=num;//记住运算符号

lcdwrite_data(num);

break;//输入运算符号则退出第一运算数的输入

}

}

while

(1)

{

if(ac==1)break;//若清零,则退出输入

if(sqrtflag1==1)//若第一次按键为开方,则直接显示结果

{

break;

}

if((keyscan()!

='N')&&((num>=0&&num<=9)||num=='.'))//记录按键下的数字

{

if(keynum2<=7)

{

if(num=='.')

{

lcdwrite_data('.');//显示小数点

}

else

lcdwrite_num1(num);

num2[keynum2]=num;

keynum2++;

}

}

elseif(num=='='||keysqrt==0)

{

sqrtflag2=0;//清除开方标志

if(keysqrt==0)//进入开方

{

delayms(5);

if(keysqrt==0)

{

sqrtflag2=1;//开方标志

lcdwrite_data(0xe8);//写开方符号

if(beepflag==1)//若开声音则每一次按键均鸣叫

{

beep=0;

delayms(100);

beep=1;

}

while(keysqrt==0);

delayms(10);

while(keysqrt==0);

}

}

point=0;

for(i=0;keynum2>0;i++)//计算按下是数字的大小

{

if(num2[i]!

='.')ans2=ans2*10+num2[i];

elseif(num2[i]=='.')break;

keynum2--;

}

for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)

point=point*10+num2[i];

for(;j>0;j--)

point*=0.1;

if(sqrtflag2!

=1)

lcdwrite_data(num);

ans2=ans2+point;

break;//输入等于号则退出第二运算数的输入

}

elseif(num=='+'||num=='-'||num=='*'||num=='/'||num=='^')

{

point=0;

for(i=0;keynum2>0;i++)//计算按下数字的大小

{

if(num2[i]!

='.')ans2=ans2*10+num2[i];

elseif(num2[i]=='.')break;

keynum2--;

}

for(keynum2--,i++,j=0;keynum2>0;j++,i++,keynum2--)

point=point*10+num2[i];

for(;j>0;j--)

point*=0.1;

lcdwrite_data(num);

ans2=ans2+point;

conflag=1;

break;//进行连续计算

}

}

if(ac==1)

{

ac=0;

continue;//清零后进行下一次运算

}

if(sign=='+')//计算结果

ans=ans1+ans2;

if(sign=='-')

ans=ans1-ans2;

if(sign=='*')

ans=ans1*ans2;

if(sign=='/')

ans=ans1/ans2;

if(sign=='^')//计算多次方

ans=pow(ans1,ans2);

if(sqrtflag2==1)//计算开方

ans=sqrt(ans);

lcd_setxy(1,0);

if((ans2==0&&sign=='/')||(ans<0&&(sqrtflag1==1||sqrtflag2==1)))

lcdwrite_string("matherror");//ans2=0或被开方数小于0时提示错误

elselcdwrite_float(ans);//显示结果

sqrtflag1=0,newcalc=1;//为新的一次运算准备

ans1=0;

ans2=0;

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

num1[i]=0;

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

num2[i]=0;

if(conflag==1)

{

conflag=0;

gotohere;//跳转到连续运算

}

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1