单片机简易计算机有程序,C51单片机简易计算器程序设计

#include

#include

#include

#define u8  unsigned char

#define u16  unsigned char

sbit LCDEN=P3^4;

sbit RS=P3^5;

sbit RW=P3^6;

sbit BF=P0^7;

u8 code keyval[]="789/456*123-c0=+"; //按键对应的符号

u8 data1[10];

u8 k=0;

char  m[10]={0};

double sum=0;

void delay(u16 x)          //延时x毫秒

{

u16 i,j;

for(i=0;i

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

;

}

u8 keypad4_4()//按键扫描函数:要去抖,若有按键按下,返回对应的按键值(0-15),没有按键按下返回16

{

u8 i,row,temp;

u8 key=16;//按键号,初值设置为16,目的是:没有按键按下时返回16;

//若不设初值(默认值为0),没有按键按下时,将返回0,会误认为0被按下

row=0xef; //从第一列开始

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

{

P1=0xff;

P1=row;        //第i列信号,对应列为低,其他全为高

row=_crol_(row,1);           //生成下一列信号

temp=P1; //读入扫描信号

temp=temp&0x0f; //屏蔽高4位列信号,只保留低4位行信号

if(temp!=0x0f)//有按键被按下,因为第i列某行有按键按下,则低4位中有一位为低

{

delay(20);  //延时去抖

temp=P1;

temp=temp&0x0f;

if(temp!=0x0f)   //再次确认有按键被按下

{

switch(temp)  //根据低4位行信号,判断哪个按键被按下

{

case 0x0e:key=0+i;break; //第i列第1行按键被按下

case 0x0d:key=4+i;break; //第i列第2行按键被按下

case 0x0b:key=8+i;break; //第i列第3行按键被按下

case 0x07:key=12+i;      //第i列第4行按键被按下

}

do

{

temp=P1;              //再次扫描按键

temp=temp&0x0f;

}while(temp!=0x0f); //等待按键释放

}

}

}

return(key);//扫面结束,返回按键值

}

unsigned char DectectBusyBit(void)//状态判断函数(忙/闲?)

{

bit result;

P0 = 0xff;        //读状态前先置高电平,防止误判

RS = 0;

delay(5);

RW = 1;

LCDEN = 1;

delay(5);

result=BF; //若LCM忙,则反复测试,在此处原地踏步;当LCM闲时,才往下继续

LCDEN = 0;

return result;

}

void WrComLCD(unsigned char ComVal)//写命令函数

{

while(DectectBusyBit()==1);         //先检测LCM是否空闲

RS = 0;

delay(1);

RW = 0;

LCDEN = 1;

P0 = ComVal;

delay(1);

LCDEN = 0;

}

void WrDatLCD(unsigned char DatVal)//写数据函数

{

while(DectectBusyBit()==1);

RS = 1;

delay(1);

RW = 0;

LCDEN = 1;

P0 = DatVal;

delay(1);

LCDEN = 0;

}

void LCD_Init(void)//1602初始化函数

{

WrComLCD(0x38);     // 功能设定:16*2行、5*7点阵、8位数据接口

WrComLCD(0x38);

WrComLCD(0x38);

//多次重复设定功能指令,因为LCD启动后并不知道使用的是4位数据接口还是8位的,所以开始时总是默认为4位

WrComLCD(0x01);    // 清屏

WrComLCD(0x06);    // 光标自增、屏幕不动

delay(1);              // 延时,等待上面的指令生效,下面再显示,防止出现乱码

WrComLCD(0x0c);    // 开显示

}

void compute(){

u8 i,j=0,k,n=0;

char data3[10]={0};

int sum1,data2[10]={0};

sum=0;

for(i=0;data1[i]!='\0';i++){

if(data1[i]!='+' && data1[i]!='-' && data1[i]!='*' && data1[i]!='/'){

data2[j] =data2[j]*10+(data1[i]-'0');

}

else{

data3[n++] = data1[i];

j++;

}

}

for(i=0;i

if(i==0){

if(data3[0]=='+')  sum = data2[0] + data2[1];

if(data3[0]=='-')  sum = data2[0] - data2[1];

if(data3[0]=='*')  sum = data2[0] * data2[1];

if(data3[0]=='/')  sum = data2[0] / (double)data2[1];

}

if(i==1){

if(data3[1]=='+')  sum = sum+data2[2];

if(data3[1]=='-')  sum = sum-data2[2];

if(data3[1]=='*')  sum = sum*data2[2];

if(data3[1]=='/')  sum = sum/((float)data2[2]);

}

if(i==2){

if(data3[2]=='+')  sum = sum+data2[3];

if(data3[2]=='-')  sum = sum-data2[3];

if(data3[2]=='*')  sum = sum*data2[3];

if(data3[2]=='/')  sum = sum/((float)data2[3]);

}

}

//判断是小数输出还是整数输出

sum1 = sum;

if(sum1==sum){

sprintf(m,"%d",sum1);

}

else{

sprintf(m,"%f",sum);

}

//把结果输出出来

for(k=0;m[k]!='\0';k++){

WrDatLCD(m[k]);

}

}

void main()

{

u8 y;

LCD_Init();

delay(5);   //延时,等待初始化完成

WrDatLCD('0');

WrComLCD(0x80);           //设置显示地址第一行第一位:0X00(0x80+0x00)

while(1){

y= keypad4_4();

if(y==12)  { k=0;WrComLCD(0x01);WrDatLCD('0'); WrComLCD(0x80);}   //清屏

if(y==14)  {

WrComLCD(0xC0); WrDatLCD(keyval[y]); WrDatLCD(' '); data1[k]='\0';compute();//调用出结果函数

}

if(y<16 && y!=12 && y!=14)

{

WrDatLCD(keyval[y]);

data1[k++]= keyval[y];

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值