历史上的今天
返回首页

历史上的今天

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

正在发生

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

2020-11-26 来源: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);

推荐阅读

史海拾趣

AUREL公司的发展小趣事

AUREL公司早期在电子行业中并不显眼,直到它成功研发出一款具有革命性的半导体芯片。这款芯片在功耗、性能和稳定性上都达到了前所未有的水平,立刻引起了市场的广泛关注。公司通过积极的市场推广和技术合作,逐渐打开了国内外市场,奠定了在电子行业中的技术领先地位。

EDAC公司的发展小趣事

面对数字化浪潮的冲击,ECS-D公司积极拥抱数字化转型,通过引入先进的信息技术和智能化设备,提升企业的运营效率和创新能力。公司建立了数字化管理平台,实现了生产、销售、财务等各个环节的信息化管理。同时,ECS-D公司还加强了对员工的数字化培训和教育,提升员工的数字化素养和创新能力。这些数字化转型的举措使ECS-D公司在激烈的市场竞争中保持了领先地位,也为公司的未来发展奠定了坚实的基础。

以上五个故事均以ECS公司的发展为主题,分别从不同角度描述了这些公司在电子行业中的成长历程和成功经验。这些故事旨在展示ECS公司如何通过技术创新、全球化战略、品质管理、绿色环保理念和数字化转型等方式实现持续发展和壮大。

Fairchild (ON Semiconductor)公司的发展小趣事

1957年,被誉为“八叛逆”的八位年轻科学家在罗伯特·诺伊斯的带领下,离开了肖克利半导体实验室,创立了Fairchild Semiconductor公司。这八位科学家,包括诺伊斯、戈登·摩尔等人,后来都成为了硅谷科技产业的领军人物。Fairchild的成立不仅为硅谷的发展奠定了坚实的基础,更为电子行业培养了大量的人才,被誉为“人才摇篮”。

Custom LeatherCraft Manufacturing Co Inc公司的发展小趣事

为了扩大市场份额,CLC开始实施全球化战略。他们在世界各地寻找优质的原材料供应商,并与当地的合作伙伴建立长期合作关系。同时,他们还积极参加国际展览和贸易活动,展示自己的产品和技术实力。这些努力使CLC的品牌影响力逐渐扩大,产品也走进了更多的国家和地区。

芯邦(Chipsbank)公司的发展小趣事

随着公司业务的不断发展,芯邦开始积极布局UWB(超宽带通信)产品线。UWB技术以其高速率、高精度和低功耗的特点,在智能家居、物联网等领域展现出巨大的应用潜力。芯邦通过研发UWB等信息传输技术及产品,致力于从移动存储及智能家电市场出发,以手机及移动智能设备、车规及汽车周边产品应用、智能家居及物联网领域为目标市场,打造多系列产品线格局,提升公司的市场竞争力。

AD Semiconductor公司的发展小趣事

为了进一步扩大业务规模,提升研发实力,芯邦科技于2023年成功在上交所科创板上市,并计划募资6亿元用于投建移动存储控制芯片等项目。这一举措不仅为芯邦提供了更多的资金支持,也为其未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

给大学生就业支招3--部分面试试题

看了我们历年来的部分招聘试题,大家一定会觉得太容易了,但大多数学生还是做不出来,包括研究生在内,比例达到98%以上,所以我不得不投入到创新教育实践活动之中去。我们每次出题之前都要翻看各种版本的教材与实验指导书,如果只有一本书上有类似 ...…

查看全部问答>

安防必知闭路监控系统的七大组成

安防监控系统是一门被人们日益重视的新兴专业,就目前发展看,应用普及越来越广,科技含量越来越高。几乎所有高新科技都可促进其发展,尤其是信息时代的来临,更为该专业发展提供契机。但就监控业界而言,系统组成一直没得到明确的划分,这使工程商 ...…

查看全部问答>

各种开关电源电路图

各种开关电源电路图…

查看全部问答>

pxa270烧了bootloader起不来

1,最近调试pxa270开发板,发现很奇怪的现象,采用的是pxa270主芯片,2片16bits norflash,组成32bits的总线与pxa270相连,共32MB,,intel strata flash,TE28F128J3A-150,内存是两片美光的16M16,组成64MB SDRAM. 现在我采用简易的Jtag下载线,只能 ...…

查看全部问答>

求触摸屏校准算法

小弟刚接受触摸屏,想要个校正的例子学习一下,各位有的给我发一个万分感谢啊,万分感谢!!! EMAIL:daihou1136@sina.com QQ:35937862 感谢感谢感谢感谢感谢!!!…

查看全部问答>

stm8a系列好买吗

                                 stm8a系列 的种类全 好买吗…

查看全部问答>

为什么TIM_ARRPreloadConfig在我的程序中没有作用 他到底有什么作用?

我用TIM2定时一秒,可是 不管我将TIM_ARRPreloadConfig设置为DISABLE 还是ENABLE,结果都不变。我都不明白TIM_ARRPreloadConfig有什么作用了;  另外,TIM_TimeBaseStructure.TIM_Prescaler=0还是9我都试过,定时还是一秒;不知道为什 ...…

查看全部问答>

玩FPGA的该何去何从

事情是这样子的:昨天有个工程师(一直都是在做山寨产品)来我们电子系开讲座,大概介绍了电子行业的一些规则,当我问到你们公司会不会用FPGA来开发产品,他这样跟我说:现在FPGA用得很少,只有IC方面的才用到,我做了十年的工程师都没用到, ...…

查看全部问答>

单片机之防止PC指针的弹飞

下面就由福州卓跃教育为您具体介绍单片机编程经验之用“软件陷阱+程序口令”对付PC指针的弹飞。       当CPU受到外界干扰,有时PC指针会飞到另一段程序中,或跳到空白段去。其实,如果PC指针飞到空白段去,倒也好处理。 ...…

查看全部问答>

TMS320LF240x DSP硬件开发教程

PDG格式的,需要超星阅读器观看   …

查看全部问答>