历史上的今天

今天是:2024年11月26日(星期二)

正在发生

2020年11月26日 | 单片机5*4矩阵键盘计算器制作

发布者:温馨的家庭 来源: 51hei关键字:单片机  矩阵键盘  计算器 手机看文章 扫描二维码
随时随地手机看文章

本设计是以STC89C52单片机为核心的计算器模拟系统设计,输入采用5×8矩阵键盘,可以进行加、减、乘、除等十几种数字运算,同时支持括号的嵌套使用级浮点数的运算,并在LCD1602上显示操作过程。


本次设计注重设计方法及流程,首先根据原理设计电路,利用keil编程,借助实验开发平台进行仿真实验,进而利用altium designer 制作PCB,最后到焊接元器件,直至调试成功。在设计的同时,特别注重keil软件和altium designer软件的使用方法和技巧以及常用的LCD显示器和矩阵键盘的设计和使用方法。


单片机源程序如下:

#include

#include

#include

#include

#include

sbit RS = P2^5;

sbit RW = P2^6;

sbit E  = P2^7;


#define Data  P0//数据端口

//全局变量

float num1;//第一操作数num1     (初始为零)

float num2;//第二操作数num2     (初始为零)

char yun_flag='+';//运算符号 yun_flag    (默认为+ )

char key_last;//上次按键状态标志 key_last

char sqrt_flag;//开方键按下标志   sqrt_flag

unsigned long pos_flag=1;//小数位权pos_flag      (默认为1)

char neg_flag;//正负标志 neg_flag

char data c_num1[15]=" ";//c_num1 字符型第一操作数 (数组不定义大小与其他变量冲突)

char data c_num2[15]=" ";//c_num2 字符型第二操作数

char error;//运算法则错误;

char len;//小数点后位数

/*                    微秒延时函数                                */

/******************************************************************/

void DelayUs(unsigned char us)//delay us

{

unsigned char uscnt;

uscnt=us>>1;        /*12MHz频率*/

while(--uscnt);

}

/******************************************************************/

/*                    毫秒函数声明                                */

/******************************************************************/

void DelayMs(unsigned char ms)

{

while(--ms)

   {

     DelayUs(250);

     DelayUs(250);

         DelayUs(250);

         DelayUs(250);

   }

}

/******************************************************************/

/*                   写入命令函数                                 */

/******************************************************************/

void WriteCommand(unsigned char c)

{

DelayMs(5);//操作前短暂延时,保证信号稳定

E=0;

RS=0;

RW=0;

_nop_();

E=1;

Data=c;

E=0;

}

/******************************************************************/

/*                   写入数据函数                                 */

/******************************************************************/

void WriteData(unsigned char c)

{

DelayMs(5);  //操作前短暂延时,保证信号稳定

E=0;

RS=1;

RW=0;

_nop_();

E=1;

Data=c;

E=0;

RS=0;

}

/******************************************************************/

/*                   写入字节函数                                 */

/******************************************************************/

void ShowChar(unsigned char pos,unsigned char c)

{

unsigned char p;

if (pos>=0x10)

    p=pos+0xb0; //是第二行则命令代码高4位为0xc

else

    p=pos+0x80; //是第二行则命令代码高4位为0x8

WriteCommand (p);//写命令

WriteData (c);   //写数据

}

/******************************************************************/

/*                   写入字符串函数                               */

/******************************************************************/

void ShowString (unsigned char line,char *ptr)

{

unsigned char l,i;

l=line<<4;

for (i=0;*(ptr+i)!='';i++)

  ShowChar (l++,*(ptr+i));//循环显示16个字符

}

/******************************************************************/

/*                   初始化函数                                   */

/******************************************************************/

void InitLcd()

{

DelayMs(15);

WriteCommand(0x38); //display mode

WriteCommand(0x38); //display mode

WriteCommand(0x38); //display mode

WriteCommand(0x06); //显示光标移动位置

WriteCommand(0x0c); //显示开及光标设置

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


}

/*************按键扫描****************************/

char scan()

{


  char h_data,l_data,i,key_num;

  P2=P2&0XE0;//P2低5位送0

  P1=P1|0X0F;//P1低4位送1

  while((P1|0xf0)==0xff)//判断P1低4位是否全为1

  {

   while((P1|0xf0)==0xff);

   DelayMs(10);//延时10ms

  }

   l_data=~(P1|0xf0);//记入列标志

   P2=P2|0X1F;//P2低五位送1

   P1=P1&0XF0;//P1低四位送0

   h_data=~(P2|0xe0);//记入行标志

   for(i=0;i<=4;i++)//计算行号(0~4)

            {

           if(h_data==1)break;

           h_data=h_data>>1;

         }

h_data=i;//行号

  for(i=1;i<=4;i++)//计算列号(1~4)

         {

          if(l_data==1)break;

          l_data=l_data>>1;

        }

l_data=i;//列号

   key_num=h_data*4+l_data;        


  P2=P2&0XE0;//P2低5位送0

  P1=P1|0X0F;//P1低4位送1

  while((P1|0xf0)!=0xff)//判断P1低4位是否全为1

  {

   while((P1|0xf0)!=0xff);

   DelayMs(10);//延时10ms

  }

  return key_num;

}

void float_to_char(float a,char* p)

{

  char i,flag,length;

  flag=0;

  sprintf(p,"%f",a);

  length=strlen (p);

  for(i=0;i  {

    if(*(p+i)=='.')flag=1;

  }

  if(flag==1)

  for(i=length-1;i>=0;i--)

  {

    if(*(p+i)=='.'){*(p+i)='';break;}

    if(*(p+i)!='0'){*(p+i+1)='';break;}

  }

}

/**********************更新液晶*************************/

void refresh()//更新液晶

{

  char length,i,j;

  char dot;

  dot=0;

         

  float_to_char(num2,c_num2);//num2转为字符型

  length=strlen(c_num2);

  for(i=0,j=0;i  {

    if(c_num2[i]=='.')

        dot=1;

        if(dot==1)

    j++;

  }

  if(j  {

          if(dot==1)

          {        

            for(i=length;i<(length+len-j);i++)

                 {

                   c_num2[i]='0';

        

                 }

                 c_num2[i]='';

          }

          else

                {

                  

                  c_num2[length]='.';

                  if(len-j>1)

                  {

                    for(i=length+1;i<(length+len-j);i++)

                         c_num2[i]='0';

                  }

                  c_num2[length+len-j]='';

                }  

  }


  if(neg_flag==1)//'+/-'按下首位加‘-’

   {

      length=strlen(c_num2);//计算c_num2长度         

                    for(i=length-1;i>=0;i--)

                  {

                          c_num2[i+1]=c_num2[i];

                  }

                  c_num2[length+1]='';

                  c_num2[0]='-';

   }

   

   if(sqrt_flag==1)

           {

      length=strlen(c_num2);//计算c_num2长度

             for(i=length-1;i>=0;i--)

          {

                  c_num2[i+1]=c_num2[i];

          }

          c_num2[length+1]='';

          c_num2[0]=0xe8;//字符根号

   }

   

   

   if(error==0)

   {

           float_to_char(num1,c_num1);//num1转为字符型

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

           ShowString(0,c_num1);

           ShowString(1,c_num2);  

           ShowChar(15,yun_flag);

   }else

   {

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

           ShowString(0,"error!!!");

   }

}

//键值处理

void operation1(char keynum)//按下 ’+、-、*、/处理

{

  if(key_last==1)//上次按键为 数字、小数点、+/-、sqrt

   {

     if(neg_flag==1)num2=-num2;//'+/-'按下

         if(sqrt_flag==1)//sqrt按下

         {

         if(num2>=0)

         num2=sqrt(num2);

[1] [2]
关键字:单片机  矩阵键盘  计算器 引用地址:单片机5*4矩阵键盘计算器制作

上一篇:STC89单片机+TM1638超级秒表程序
下一篇:51单片机设计的电子密码锁

推荐阅读

1. 学界|水下机器人: 康奈尔大学科学家研发水下跳跃机器人康奈尔大学科学家研发了水下跳跃机器人,该机器人旨在了解鲸鱼和海豚等动物如何跳出水面。自然界中像鲸鱼或海豚跳出水面是壮观的景象,这些优美的动作在技术上具有挑战性。因此,一组研究人员着手了解如何通过建造一个机器人来实现跳出水面。来自康奈尔大学的研究人员研究了更简单和更常见的动...
据MoneyDJ报道,爱立信(Ericsson)周一发表报告指出,预计5G用户数量将从2019年的1300万增长至2025年的26亿,2025年年底前5G网络将覆盖全球65%的人口。并且按照他们之前的预测,6年内5G流量在全球移动网络数据流量占比重将达到45%。爱立信在报告中指出,从当前动能来看,5G的覆盖速度将比4G快上许多,2025年时5G用户数量将会占所有移动通讯用户的29%。不...
日前,全球知名工业级存储领导大厂宜鼎国际(Innodisk)宣布,旗下 DRAM 内存模组 DDR4 产品系列通过海光 CPU7000、5000、3000 系列产品兼容性认证。 海光认证书 同时,Innodisk DRAM 内存模组 DDR4-2666 内存与上海兆芯集成电路有限公司(以下简称兆芯)及龙芯中科技术有限公司联合进行兼容性测试,兆芯开胜 KX-6000 系列 CPU 可以做到软件、...
相关数字万用表上HFE的含意,意思是三极管的电流量变大倍率,hFE就是指在固定不动的直流电参考点下的电流量增益值,而hfe则是沟通交流小数据信号电流量增益值。数字万用表HFE的含意H:Hybrid; F:forward;E:common emitter(共射接线方法),实际上便是三极管的电流量变大倍率。hFE就是指在固定不动的直流电参考点下的电流量增益值,而hfe则是沟通交...

史海拾趣

小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved