本文目录一览:

51单片机键盘接口电路的计算器的实现的毕业设计及开题报告

51单片机计算器的设计(开题报告实物论文)

目 录

1.课程设计的目的………………………………………………3

2.课程设计题目描述和要求……………………………………3

3.单片机发展简史………………………………………………4

4.MCS-51单片机系统简介………………………………………6

5.MCS-51单片机内部定时器/计数器简介……………………7

6.理论设计………………………………………………………8

7.主要电路分析…………………………………………………8

8.硬件设计………………………………………………………10

9.软件设计………………………………………………………11

10.程序代码……………………………………………………12

11.设计总结……………………………………………………18

12.参考文献……………………………………………………20

随着社会的发展,科学的进步,人们的生活水平在逐步的提高,尤其是微电子技术的发展,犹如雨后春笋般的变化。电子产品的更新速度快就不足惊奇了。

计算器在人们的日常中是比较的常见的电子产品之一。可是它还在发展之中,以后必将出现功能更加强大的计算器,基于这样的理念,本次设计是用单片机来设计的四位数计算器。该设计系统是以AT89S51为单片机, P3口作为输入端,外接4X4的键盘,通过键盘扫描来对输入数的控制,在P1口,P2口接了驱动电路。用来保证LED的工作正常。计算器将完成的功能有加,减,乘,除等功能。

功能:

完成0~9999整数的一次加/减/乘/除运算,

减法运算结果可以实现计算结果的负数显示,

除法运算结果为0~999并保留两位小数,

按键音,

设有清零键,

首位零不显示,

其它的显示"E"

按键排布为:

清零/确认/除/乘

减/加/9/8

7/6/5/4

3/2/1/0

怎样用51单片机做计算器啊?

1、硬件仿真图

硬件部分比较简单,当键盘按键按下时它的那一行、那一列的端口为低电平。因此,只要扫描行、列端口是否都为低电平就可以确定是哪个键被按下。

2、主程序流程图

程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。将操作数分别转化为字符串存储,操作符存储为字符形式。然后调用compute()函数进行计算并返回结果。具体程序及看注释还有流程图。

3、Altium Designer画的PCB图

4、程序源代码

#include reg51.h#include intrins.h

#include ctype.h          

#include stdlib.h          

#define uchar unsigned char

#define uint unsigned int

uchar operand1[9], operand2[9];

uchar operator;                  

void delay(uint);

uchar keyscan();

void disp(void);

void buf(uint value);

uint compute(uint va1,uint va2,uchar optor);

uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,

              0x92,0x82,0xf8,0x80,0x90,0xff};  

uchar dbuf[8] = {10,10,10,10,10,10,10,10};         

void delay(uint z)

{

uint x,y;

for(x=z;x0;x--)

  for(y=110;y0;y--);

}

uchar keyscan()

{

  uchar skey;                   

  P1 = 0xfe;

  while((P1 0xf0) != 0xf0)      

  {

      delay(3);                 

      while((P1 0xf0) != 0xf0)  

      {

          switch(P1)              

          {

              case 0xee: skey = '7'; break;

              case 0xde: skey = '8'; break;

              case 0xbe: skey = '9'; break;

              case 0x7e: skey = '/'; break;   

              default:   skey = '#';

          }

          while((P1 0xf0) != 0xf0)

              ;

      }

  }

  P1 = 0xfd;  

  while((P1 0xf0) != 0xf0)

  {

      delay(3);

      while((P1 0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xed: skey = '4'; break;

              case 0xdd: skey = '5'; break;

              case 0xbd: skey = '6'; break;

              case 0x7d: skey = '*'; break;

              default:   skey = '#';

          }

          while((P1 0xf0) != 0xf0)

              ;

      }

  }

  P1 = 0xfb;

  while((P1 0xf0) != 0xf0)

  {

      delay(3);

      while((P1 0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xeb: skey = '1'; break;

              case 0xdb: skey = '2'; break;

              case 0xbb: skey = '3'; break;

              case 0x7b: skey = '-'; break;

              default: skey = '#';

          }

          while((P1 0xf0) != 0xf0)

              ;

      }

  }

  P1 = 0xf7;

  while((P1 0xf0) != 0xf0)

  {

      delay(3);

      while((P1 0xf0) != 0xf0)

      {

          switch(P1)

          {

              case 0xe7: skey = '$'; break;

              case 0xd7: skey = '0'; break;

              case 0xb7: skey = '='; break;

              case 0x77: skey = '+'; break;

              default:   skey = '#';

          }

          while((P1 0xf0) != 0xf0)

              ;

      }

  }

  return skey;

}

void main()

{  

  uint value1, value2, value;        

  uchar ckey, cut1 = 0, cut2 = 0;  

  uchar operator;                    

  uchar i, bool = 0;

init:                                 

  buf(0);                          

  disp();

  value = 0;

  cut1 = cut2 = 0;

  bool = 0;

  for(i = 0;i 9;i++)

  {

      operand1[i] = '\0';

      operand2[i] = '\0';

  }                               

  while(1)

  {

      ckey = keyscan();          

      if(ckey != '#')

      {

          if(isdigit(ckey))      

          {

              switch(bool)  

              {

                  case 0:

                          operand1[cut1] = ckey;

                          operand1[cut1+1] = '\0';

                          value1 = atoi(operand1);

                          cut1++;

                          buf(value1);

                          disp();

                          break;

                  case 1:

                          operand2[cut2] = ckey;

                          operand2[cut2+1] = '\0';

                          value2 = atoi(operand2);

                          cut2++;

                          buf(value2);

                          disp();

                          break;                     

                  default: break;

              }

          }

          else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/')

          {

              bool = 1;  

              operator = ckey;

              buf(0);

              dbuf[7] = 10;

              disp();

          }

          else if(ckey == '=')

          {

              value = compute(value1,value2,operator);

              buf(value);

              disp();

              while(1)                  

              {

                  ckey = keyscan();

                  if(ckey == '$')        

                      goto init;

                  else

                      {

                          buf(value);

                          disp();

                      }

              }

          }

          else if(ckey == '$')

          {    goto init;}

      }

      disp();

  }

}

uint compute(uint va1,uint va2,uchar optor)

{

  uint value;

  switch(optor)

  {

      case '+' : value = va1+va2;    break;

      case '-' : value = va1-va2;    break;

      case '*' : value = va1*va2;    break;

      case '/' : value = va1/va2;    break; 

      default :  break;

  }

  return value;

}

void buf(uint val)

{

  uchar i;

  if(val == 0)

  {

      dbuf[7] = 0;

      i = 6;

  }

  else

      for(i = 7; val 0; i--)

      {

          dbuf[i] = val % 10;

          val /= 10;

      }

  for( ; i 0; i--)

      dbuf[i] = 10;

}

void disp(void)

{

  uchar bsel, n;

  bsel=0x01;

  for(n=0;n8;n++)

  {

      P2=bsel;

      P0=table[dbuf[n]];

      bsel=_crol_(bsel,1);

      delay(3);

      P0=0xff;

  }

}

扩展资料:

PROTEUS 是单片机课堂教学的先进助手

PROTEUS不仅可将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。前者可在相当程度上得到实物演示实验的效果,后者则是实物演示实验难以达到的效果。

它的元器件、连接线路等却和传统的单片机实验硬件高度对应。这在相当程度上替代了传统的单片机实验教学的功能,例:元器件选择、电路连接、电路检测、电路修改、软件调试、运行结果等。

课程设计、毕业设计是学生走向就业的重要实践环节。由于PROTEUS提供了实验室无法相比的大量的元器件库,提供了修改电路设计的灵活性、提供了实验室在数量、质量上难以相比的虚拟仪器、仪表,因而也提供了培养学生实践精神、创造精神的平台

随着科技的发展,“计算机仿真技术”已成为许多设计部门重要的前期设计手段。它具有设计灵活,结果、过程的统一的特点。可使设计时间大为缩短、耗资大为减少,也可降低工程制造的风险。相信在单片机开发应用中PROTEUS也能茯得愈来愈广泛的应用。

使用Proteus 软件进行单片机系统仿真设计,是虚拟仿真技术和计算机多媒体技术相结合的综合运用,有利于培养学生的电路设计能力及仿真软件的操作能力;

在单片机课程设计和全国大学生电子设计竞赛中,我们使用 Proteus 开发环境对学生进行培训,在不需要硬件投入的条件下,学生普遍反映,对单片机的学习比单纯学习书本知识更容易接受,更容易提高。

实践证明,在使用 Proteus 进行系统仿真开发成功之后再进行实际制作,能极大提高单片机系统设计效率。因此,Proteus 有较高的推广利用价值。

参考资料来源:百度百科-protues

基于51单片机的简易计算器制作

您好,这样的:

纵观单片机的发展过程,可以预示单片机的发展趋势,;1)低功耗CMOS化;MCS-51系列的8051推出时的功耗达630m;2)微型单片化;现在常规的单片机普遍都是将中央处理器(CPU)、;此外,现在的产品普遍要求体积

照程序设计的各部分实现的功能不同,将整个软件系统分成了三个块,并对每一个功能块所采用的元器件进行了详细介绍。此外还编写了主要功能模块的基本程序,详尽阐述了各模块的工作过程。还有总流程图,源代码,硬器件铺线图。

基于51单片机的简易计算器设计,急

//功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零  表3-1  3.2 计算器的软件设计 

#includereg51.h   //头文件

#define uint unsigned int //

#define uchar unsigned char

sbit lcden=P2^3; //定义引脚

sbit rs=P2^4;

sbit rw=P2^0;

sbit busy=P0^7;

char i,j,temp,num,num_1;

long a,b,c;     //a,第一个数 b,第二个数 c,得数

float a_c,b_c;

uchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号

uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0};

uchar code table1[]={

7,8,9,0x2f-0x30,

4,5,6,0x2a-0x30,

1,2,3,0x2d-0x30,

0x01-0x30,0,0x3d-0x30,0x2b-0x30};

void delay(uchar z) // 延迟函数

{

uchar y;

for(z;z0;z--)

for(y=0;y110;y++);

}   void check() // 判断忙或空闲

{

do{

P0=0xFF;

rs=0;     //指令

rw=1;     //读

lcden=0;     //禁止读写

delay(1); //等待,液晶显示器处理数据

lcden=1;     //允许读写

}while(busy==1); //判断是否为空闲,1为忙,0为空闲

}

void write_com(uchar com) // 写指令函数

{

P0=com;    //com指令付给P0口

rs=0;

rw=0;

lcden=0;

check();

lcden=1;

}

void write_date(uchar date) // 写数据函数

{

P0=date;

rs=1;

rw=0;

lcden=0;

check();

lcden=1;

}

void init() //初始化

{

num=-1;

lcden=1; //使能信号为高电平

write_com(0x38); //8位,2行

write_com(0x0c); //显示开,光标关,不闪烁*/

write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?

write_com(0x80); //检测忙信号

write_com(0x01); //显示开,光标关,不闪烁

num_1=0;

i=0;

j=0;

a=0;     //第一个参与运算的数

b=0;     //第二个参与运算的数

c=0;

flag=0; //flag表示是否有符号键按下,

fuhao=0; // fuhao表征按下的是哪个符号

}

void keyscan() // 键盘扫描程序

{

P3=0xfe;

if(P3!=0xfe)

{

delay(20); //延迟20ms

if(P3!=0xfe)

{

temp=P30xf0;

switch(temp)

{

case 0xe0:num=0;

break;

case 0xd0:num=1;

break;

case 0xb0:num=2;

break;

case 0x70:num=3;

break;

}

}

while(P3!=0xfe);

if(num==0||num==1||num==2)//如果按下的是'7','8'或'9

{

if(j!=0)

{

write_com(0x01);

j=0;

}

if(flag==0)//没有按过符号键

{

a=a*10+table[num];

}

else//如果按过符号键

{

b=b*10+table[num];

}

}

else//如果按下的是'/'

{

flag=1;

fuhao=4;//4表示除号已按

}

i=table1[num];

write_date(0x30+i);

}

P3=0xfd;

if(P3!=0xfd)

{

delay(5);

if(P3!=0xfd)

{

temp=P30xf0;

switch(temp)

{

case 0xe0:num=4;

break;

case 0xd0:num=5;

break;

case 0xb0:num=6;

break;

case 0x70:num=7;

break;

}

}

while(P3!=0xfd);

if(num==4||num==5||num==6num!=7)//如果按下的是'4','5'或'6'

{

if(j!=0)

{

write_com(0x01);

j=0;

}

if(flag==0)//没有按过符号键

{

a=a*10+table[num];

}

else//如果按过符号键

{

b=b*10+table[num];

}

}

else//如果按下的是'/'

{

flag=1;

fuhao=3;//3表示乘号已按

}

i=table1[num];

write_date(0x30+i);

}

P3=0xfb; if(P3!=0xfb)

{

delay(5);

if(P3!=0xfb)

{

temp=P30xf0;

switch(temp)

{

case 0xe0:num=8;

break;

case 0xd0:num=9;

break;

case 0xb0:num=10;

break;

case 0x70:num=11;

break;

}

}

while(P3!=0xfb);

if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'

{

if(j!=0)

{

write_com(0x01);

j=0;

}

if(flag==0)//没有按过符号键

{

a=a*10+table[num];

}

else//如果按过符号键

{

b=b*10+table[num];

}

}

else if(num==11)//如果按下的是'-'

{

flag=1;

fuhao=2;//2表示减号已按

}

i=table1[num];

write_date(0x30+i);

}

P3=0xf7;

if(P3!=0xf7)

{

delay(5);

if(P3!=0xf7)

{

temp=P30xf0;

switch(temp)

{

case 0xe0:num=12;

break;

case 0xd0:num=13;

break;

case 0xb0:num=14;

break;

case 0x70:num=15;

break;

}

}

while(P3!=0xf7);

switch(num)

{

case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"

break;

case 13:{                //按下的是"0"

if(flag==0)          //没有按过符号键

{

a=a*10;

write_date(0x30);

P1=0;

}

else if(flag==1)//如果按过符号键

{

b=b*10;

write_date(0x30);

}

}

break;

case 14:{j=1;

if(fuhao==1){write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处

write_com(0x04);     //设置从后住前写数据,每写完一个数据,光标后退一格

c=a+b;

while(c!=0)

{

write_date(0x30+c%10);

c=c/10;

}

write_date(0x3d);     //再写"="

a=0;b=0;flag=0;fuhao=0;

}

else if(fuhao==2){write_com(0x80+0x4f);   //光标前进至第二行最后一个显示处

write_com(0x04);     //设置从后住前写数据,每写完一个数据,光标后退一格

//(这个照理说顺序不对,可显示和上段一样)

if(a-b0)

c=a-b;

else

c=b-a;

while(c!=0)

{

write_date(0x30+c%10);

c=c/10;

}

if(a-b0)

write_date(0x2d);

write_date(0x3d);     //再写"="

a=0;b=0;flag=0;fuhao=0;

}

else if(fuhao==3){write_com(0x80+0x4f);

write_com(0x04);

c=a*b;

while(c!=0)

{

write_date(0x30+c%10);

c=c/10;

}

write_date(0x3d);

a=0;b=0;flag=0;fuhao=0;

}

else if(fuhao==4){write_com(0x80+0x4f);

write_com(0x04);

i=0;

c=(long)(((float)a/b)*1000);

while(c!=0)

{

write_date(0x30+c%10);

c=c/10;

i++;

if(i==3)

write_date(0x2e);

}

if(a/b=0)

write_date(0x30);

write_date(0x3d);

a=0;b=0;flag=0;fuhao=0;

}

}

break;

case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}

break;

}

}

}

main()

{

init();

while(1)

{

keyscan();

}

}