/********************************************************/
/* 计算器程序 2009-5-25
/* 该计算器能进行15位以下的加减乘除运算,支持浮点数运算
/* 运算结果保留小数点后7位小数,可根据实际情况自动选择是
/* 否用科学计数法表示
/*可以实现计数器和计算之间的切换
/********************************************************/
#include <reg51.h>
#include <intrins.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
/********************************************************/
/*atof():字符串转浮点数函数,有效位有7位 */
/********************************************************/
sbit bp=P3^5;
extern uchar keyscan(void);
extern void LCD_ChangData(unsigned char x,unsigned char y,unsigned long z);
extern void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s);
extern void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat);
extern void inttilcs(void); //液晶初始化子程序
extern void clear(void);
extern void lcd_wcmd(uchar cmd);
extern void delay(int ms);
void caculate(void);
void beep(void);
uchar idata expression[16]; //存储键入的表达式,最长16个字符
uchar idata incount;
bit keypressflag;
uchar convert=0;
uchar shumu=0;
bit keypresslongflag; //长按键标志
bit onflag; //开机标志位,按N/C键后置1
uchar m;
unsigned long n=0;
void main()
{
uchar key; //存键值
inttilcs(); //液晶初始化
incount=0; //键入字符数计数器
keypressflag=0; //有按键标志位,有键按下时置1
keypresslongflag=0; //长按键标志位,一直按一个键时置1,实现一个键只读取一次
onflag=1; //程序开始时为关机状态,即液晶不显示
/*********设置定时器0,用于产生蜂鸣器的频率**************/
TMOD=0X12; //定时器0方式2,自动重装载
TH0=0X70;
TL0=0X70;
TH1=0XD8;
TL1=0XF0;
m=0;
ET0=1;
ET1=1;
TR1=1;
TR0=0;
EA=1;
/********************************************************/
while(1)
{
if(convert==0)
{
TR1=1;
if(n>100)lcd_wcmd(0x08);
LCD_dsp_string(0,1,"09-05-31");
LCD_ChangData(8,1,n);
LCD_dsp_string(0,0,"Welcome To Use");
}
key=keyscan(); //键盘扫描,将键值赋给KEY
if(key=='C') //按下'c'键,可实现切换和清零
{
TR1=0; //关定时器1
clear(); //显示器清屏
convert=1; //不满足计时条件,进入计算
shumu++;
if(shumu==3) {convert=0;shumu=0;} //shumu加到3可实现切换到计时
}
if(keypressflag&&keypresslongflag&&convert) //有键按下且一个按键只处理一次
{
beep(); //按一个键,蜂鸣器响一下
keypresslongflag=0; //长按键标志位清0
if(key=='C') //按清屏键清屏
{
clear();
}
if(key=='=') //按'='键计算表达式的结果
{
shumu=0;
caculate();
}
else if
(key!='='&&key!='C'&&convert) //遇到控制字符不显示
{
shumu=0;
expression[incount]=key; //将输入的非控制字符存于字符数组中
incount++; //指向数组的下一个元素
expression[incount]='\0'; //为数组添加结束符,否则显示会乱码
if(incount==17) //若输入的字符数超过一行则提示"FULL!"
{
incount--; //超过的字符显示在一行最后一个位置处
LCD_dsp_string(0,0,"full!");
}
}
LCD_dsp_string(0,0,expression); //显示键入的表达式
LCD_dsp_string(0,1,"design by yyh");
}
}
}
void timer0(void) interrupt 1 using 1
{
bp=~bp;
}
void timer1(void) interrupt 3 using 3
{
TH1=0XD8;
TL1=0XF0;
m++;
if(m==100) {n++;
m=0;
}
}
/**********************************************************/
void beep(void)
{
TR0=1;
delay(10); //延时一下,否则声音太短
TR0=0;
}
/***********************************************************/
/*void caculate(void) 计算结果
/***********************************************************/
void caculate(void)
{
uchar i,j,k,l;
bit signflag=1; //负号标志位
float sult=0; //存计算结果
float idata expresstemp[8]; //存储字符串转数字的中间变量
float idata exptemp[8]; //加减操作的数据
uchar idata opersion[8]; //存储操作符
uchar idata opertemp[8]; //存储加减运算时的操作符
uchar idata temp[15]; //存储数字转字符串的中间变量
uchar idata jieguo[15]; //存储去处结果转换后的字符串用于显示
lcd_wcmd(0x01); //液晶清屏
delay(5);
LCD_dsp_string(0,0,expression); //显示键入的表达式
for(i=0,j=0,k=0,l=0;expression[i]!='\0';i++) //遍历整个表达式,以提取出数字串和运算符
{
temp[j]=expression[i]; //将数字字符转存于TEMP数组中
//当遇到+-×/运算符时
if(expression[i]=='+'||expression[i]=='-'||expression[i]=='*'||expression[i]=='/')
{
opersion[k++]=temp[j]; //将运算符存于OPERSION数组中
temp[j]='\0'; //每当遇到一个运算符表明该运算符之前的数就是待运算的数据,为此数据数组添加结束标志
expresstemp[l++]=atof(temp); //操作符之前的字符数据转换为浮点数
j=0; //J=0,以便记录下一组待运算的数据
continue; //直接继续下一轮循环
}
j++; //TEMP数组指向下一个元素
}
temp[j]='\0'; //为最后一组数据添加结束标志
if(j!=0) //转换最后一段数据
{
expresstemp[l++]=atof(temp);
}
if(k>=l) //表达式最后一位如果是操作符且该操作符不是第一个字符则提示错误
{
LCD_dsp_string(0,0,"Error!");
}
else //对输入的数据进行运算
{
for(i=0,j=0,k=0,sult=0;i<8;i++) //遍历整个运算符数组
{
if(opersion[i]=='*'||opersion[i]=='/') //判断×/运算符以先算乘除
{
if(opersion[i]=='*') //乘运算
{
sult=expresstemp[i+1]=expresstemp[i]*expresstemp[i+1];
}
else //除运算
{
sult=expresstemp[i+1]=expresstemp[i]/expresstemp[i+1];
}
continue; //遇到连乘或连除情况时直接进入下一轮循环
}
exptemp[j++]=expresstemp[i]; //乘除运算完成后重组待运算数据以供下面的加减运算
opertemp[k++]=opersion[i]; //重组运算符数组
}
for(i=0;i<8;i++) //再次遍历整个运算符数组,进行加减运算
{
if(opertemp[i]=='+') //加运算
{
sult=exptemp[i+1]=exptemp[i]+exptemp[i+1];
}
else if(opertemp[i]=='-') //减运算
{
sult=exptemp[i+1]=exptemp[i]-exptemp[i+1];
}
}
sprintf(jieguo,"%g",sult);
clear();//将结果数据转换为字符串存于JIEGUO中
LCD_dsp_string(0,0,jieguo);//显示结果
}
}
jisuanqi.rar_jisuanqi_强大的计算器_计算器 C程序
版权申诉
114 浏览量
2022-09-24
15:45:57
上传
评论
收藏 272KB RAR 举报
JonSco
- 粉丝: 75
- 资源: 1万+