找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2220|回复: 4
打印 上一主题 下一主题
收起左侧

51单片机LCD1602计算器,如何改这个程序,把P3. 0口设置为可以十进制转二进制的按钮。

[复制链接]
跳转到指定楼层
楼主
ID:861681 发表于 2020-12-22 00:32 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
10黑币
#include "reg51.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"   

typedef unsigned char uint8;
typedef  int uint16;
#define over_result_h 10000
#define over_result_l -10000
#define key P1
#define key2 P3//...............新按钮加p3口
sbit beep=P2^3;
sbit rw=P2^1;
sbit rs=P2^0;
sbit e=P2^2;
sbit k1=P3^0;//...............新加P3.0按钮键
uint8 flag;
uint8 flag_denghao=0;
uint8 flag_result=0;
char zifu[30];
int k=0;
long        p=0;
uint8 anjian,num,i;
long jieguo=0;
//........................................//
unsigned char addflag=0,subflag=0,mulflag=0,divflag=0,changeflag=0;
long sum1=0;
//........................................//
void delay(uint16 z)  
{
   while(z--);
}
void delayms(uint16 x)
{
        int i=0,j=0;
for(i=0;i<x;i++)
        for(j=0;j<110;j++);

}
//.................写命令函数.....................
void lcdwrc(uint8 c)
{
delay(1000);
rs=0;
rw=0;
e=0;
P0=c;
e=1;
delay(1000);
e=0;
}
//...............写数据函数........................
void lcdwrd(uint8 dat)
{
delay(1000);
rs=1;
rw=0;
e=0;
P0=dat;
e=1;
delay(1000);
e=0;
rs=0;
}
//..............LCD1602初始化函数...................
void lcdinit()
{
delay(1500);
lcdwrc(0x38);//设置功能模式
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
lcdwrc(0x08);//初始地址
lcdwrc(0x01);//清屏
lcdwrc(0x06);//写一位指针加一
lcdwrc(0x0c);// 开显示
}


void keyscan()
{
   key=0xfe;//令第一行为0,然后判断是哪一列按下
   if(key!=0xfe)
   {
   delay(1000);
    if(key!=0xfe)
   {  flag=0;
      anjian=P1&0xf0;
      switch(anjian)
      {
        case 0xe0: num=0;zifu[i]='1';while(key!=0xfe);lcdwrd(zifu[i]);i++;break;
        case 0xd0: num=1;zifu[i]='2';while(key!=0xfe);lcdwrd(zifu[i]);i++;break;
        case 0xb0: num=2;zifu[i]='3';while(key!=0xfe);lcdwrd(zifu[i]);i++;break;
        case 0x70: num=3;zifu[i]='+';while(key!=0xfe);lcdwrd(zifu[i]);i++;break;
      }
   }

   }
   key=0xfd;//令第二行为0,判断是哪一列按下
   if(key!=0xfd)
   {
    delay(1000);
     if(key!=0xfd)
     {  flag=0;
        anjian=P1&0xf0;
        switch(anjian)
        {
         case 0xe0: num=4;zifu[i]='4';while(key!=0xfd);lcdwrd(zifu[i]);i++;break;
         case 0xd0: num=5;zifu[i]='5';while(key!=0xfd);lcdwrd(zifu[i]);i++;break;
         case 0xb0: num=6;zifu[i]='6';while(key!=0xfd);lcdwrd(zifu[i]);i++;break;
         case 0x70: num=7;zifu[i]='-';while(key!=0xfd);lcdwrd(zifu[i]);i++;break;
        }                           
     }
   }
   key=0xfb;//令第三行为0,判断哪一列按下
   if(key!=0xfb);
   {delay(1000);
   if(key!=0xfb)
   { flag=0;
     anjian=P1&0xf0;
     switch(anjian)
     {
       case 0xe0: num=8;zifu[i]='7';while(key!=0xfb);lcdwrd(zifu[i]);i++;break;
       case 0xd0: num=9;zifu[i]='8';while(key!=0xfb);lcdwrd(zifu[i]);i++;break;
       case 0xb0: num=10;zifu[i]='9';while(key!=0xfb);lcdwrd(zifu[i]);i++;break;
       case 0x70: num=11;zifu[i]='*';while(key!=0xfb);lcdwrd(zifu[i]);i++;break;
     }
   }
   }
   key=0xf7;//令第四行为0,判断哪一列按下
   if(key!=0xf7)
   {
     delay(1000);
     if(key!=0x07)
     {  flag=1;
        anjian=P1&0xf0;
        switch(anjian)
        {
            case 0xe0:num=12;zifu[i]='0';while(key!=0xf7);lcdwrd(zifu[i]);i++;break;
            case 0xd0:num=13;while(key!=0xf7);memset(zifu,0,sizeof(zifu));i=0;lcdwrc(0x01);flag_denghao=0;break;
            case 0xb0:num=14;zifu[i]='=';while(key!=0xf7);
//                                        lcdwrd(zifu[i]);
                                        i++;
                                        zifu[i]='\0';break;
                                       
                                       
            case 0x70:num=15;zifu[i]='/';while(key!=0xf7);lcdwrd(zifu[i]);i++;break;
        }
     }
   }
//..............十进制转二进制..............
         P3=0x01;
         key2=P3; //原始P3.0=0x01
        if(key2=0x00)//是否已按下
   {
   delay(500);// 消抖延时
    if(key2=0x00)//是否抖动
   {  flag=0;
      anjian=key2&0x00;
      switch(anjian)
      {
        case 0x00:num=16;while(key2=0x01);break;//case按键值=P3口的电位信息,在此处P3.0口被按下后(没按前P3.0=1,P3=0x01),P3.0=0,P3=0x00
                        }
                }
        }
}



//..............十进制转二进制..............
void zhuanhuan()
{
   
   changeflag++;
         subflag=mulflag=divflag=addflag=0;

}
//........................................//
long caculate(uint8* zifu)
{
uint8 lable[10]={0};
long int num[10];
uint16 len=strlen(zifu);
uint8 cnt=0;
uint8 index=0;
long int tmp;
long int result;
int t,y,m;
for(y=len-1;y>=0;y--)//错误使用
{
        if(                                        (  zifu[len-2]>0x39||zifu[len-2]<0x30  )//最后一位为符号位
                                ||                 (  zifu[0]>0x39||zifu[0]<0x30  )//第一位为符号位
                                ||    ( (  zifu[y]>0x39||zifu[y]<0x30)&&(  zifu[y-1]>0x39||zifu[y-1]<0x30) )//连续两个符号
                               
                                ||                (                zifu[y]=='0'&&        zifu[y-1]=='/')
                )
        {
                if  (  (zifu[0]=='+')   ||  (zifu[0]=='-')  )
                flag_result=0;
                else               
                flag_result=1;
                break;
        }
        else
        {
                flag_result=0;
        }
}               
       
       
for(k=0;k<len;k++)
{
  if(zifu[k]>0x39||zifu[k]<0x30)
  {
     lable[cnt]=zifu[k];
     zifu[k]='\0';
     num[cnt]=atol(zifu+index);
     cnt++;
     index=k+1;
  }
}
num[cnt++]=atol(zifu+index);

   for(k=0;k<=len-1;k++)
   {

      if(lable[k]=='*'||lable[k]=='/')//判断加减乘除优先级
      {
      if(lable[k]=='*')
      tmp=num[k]*num[k+1];
      else if(lable[k]=='/')
      tmp=num[k]/num[k+1];

      lable[k]='%';
      num[k+1]=tmp;
      num[k]=0;
      }
   }
         
         for(k=0;k<=len-1;k++)
   {

      if(lable[k]=='%')//判断加减乘除优先级
      {
                                m=k;//记录下第一个%位置
                                while(lable[k]=='%')
                                {
                                       
                                        lable[k]='+';
                                        k++;
                                        num[m]=num[m]+num[k];
                                }
                               
                                num[k]=0;
      }
   }
   result=num[0];

//         lcdwrc(0x45+0x80);
//        lcdwrc(0x04);
//         m=0;
//         while(lable[m]!=0)
//        {lcdwrd(lable[m]);
//                m++;
//        }

   for(t=0;t<len-1;t++)
   {
     if(lable[t]=='+')
     {
        result+=num[t+1];
     }
                 
     if( lable[t]=='-')
     {
        result-=num[t+1];
     }
       
               

   }
return result;
}

void display(long jieguo)
{
p=jieguo;
if(p==0)
lcdwrd('0');
if(p<0)
jieguo=-jieguo;
while(jieguo!=0)
{lcdwrd(0x30+jieguo%10);
jieguo=jieguo/10;
}
if(p<0)
lcdwrd('-');//如果为负数,显示负号
//memset(zifu,0,sizeof(zifu));
//i=0;
flag_denghao=1;

//........................................//
if(changeflag)  //十进制转换二进制
        {
                lcdwrc(0X4f+0x80);//从第二行最末向前显示
                lcdwrc(0x04);//指针光标自动减1 整屏不移动
                while(sum1!=0)
                {
                   lcdwrd(0x30+sum1%2);
                         sum1/=2;
                }
                  lcdwrd('=');
                  changeflag=0;
        }
//........................................//

}

void main()
{
        beep=0;
        lcdinit();
        while(1)
        {
                while(flag_denghao)
                {keyscan();}
                {
                                keyscan();
                }

                if(anjian==0xb0&&flag==1)
                {
                        jieguo=caculate(zifu);
                        lcdwrc(0x4f+0x80);
                        lcdwrc(0x04);
                       
                        if(flag_result==0)//
                        {
                                if(( jieguo>100000000 )||(jieguo<-100000000))//高溢出  100000000  9个位      
                                {
                                        lcdwrc(0x45+0x80);
                                        lcdwrd('r');
                                        lcdwrd('e');
                                        lcdwrd('v');
                                        lcdwrd('o');
                                        beep=1;
                                        delayms(1000);
                                        beep=0;
                                       
                                }
                                else
                                {
                                        display(jieguo);
                                }
                               
                        }
                        else
                        {
                                        lcdwrc(0x45+0x80);
                                        lcdwrd('r');
                                        lcdwrd('o');
                                        lcdwrd('r');
                                        lcdwrd('r');
                                        lcdwrd('e');
                                        beep=1;
                                        delayms(1000);
                                        beep=0;
                       
                        }
                        flag=0;
                }
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:584814 发表于 2020-12-23 09:25 | 只看该作者
#define key2 P3//...............新按钮加p3口
连这行是啥意思看不懂,所以呵呵呵好像帮不了
回复

使用道具 举报

板凳
ID:750420 发表于 2020-12-23 10:08 | 只看该作者
增加一个或运算将输入连接到P3.0 输出连接到外部中断,使能外部中断,触发后在外部中断函数中比较你需要的几个按键并进行判断把相应的标志位置位进行相应操作
回复

使用道具 举报

地板
ID:861681 发表于 2020-12-23 19:41 来自手机 | 只看该作者
wyqf 发表于 2020-12-23 10:08
增加一个或运算将输入连接到P3.0 输出连接到外部中断,使能外部中断,触发后在外部中断函数中比较你需要的 ...

谢谢你给的思路,但是还是不会写外部中断服务函数里面的内容
回复

使用道具 举报

5#
ID:161164 发表于 2024-5-8 10:16 | 只看该作者
什么乱七八糟的代码


??



num有啥用?



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表