找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机简易计算器,c程序+proteus仿真+原理图+PCB图+简易文档

[复制链接]
跳转到指定楼层
楼主
基于51单片机简易计算器的原理图如下

基于51单片机简易计算器的pcb图如下


任务书如下
一. 设计要求
(一) 基本任务
该简易计算器设计硬件电路采用三部分电路模块构成, 第一部分是键盘模块
电路, 采用 4*4 矩阵式键盘作为输入电路; 第二部分是 LCD1602 液晶显示模块;
第三部分是以 51 单片机作为控制核心。 软件程序主要由三部分组成: 主程序、
按键扫描程序和 LCD1602 显示程序。
(二) 性能指标
(1) 用单片机 stc89C51 设计一个简易计算器, 并用 1602 液晶显示相应的
数据。
(2) 可以进行简单的加减乘除运算。
(3) 最大可以 9999*9999, 。
(4) 可以通过 proteus 仿真。

附: 可供选用的元件清单
1)1602 液晶
2)排针*16
3)16p 母座
4)STC89C51 单片机
5)40 脚 IC 座
6)10k 电阻*2
7)1.5k 电阻
8)103 排阻
9)10uf 电解电容
10)12M 晶振
11)30pf 电容*2
12)按键*17
13)自锁开关等等
  
Proteus仿真如下


单片机源程序如下:
  1. #include "reg52.h"
  2. #include "string.h"
  3. #include "stdio.h"
  4. #include "lcd1602.h"
  5. #include "keyboard.h"

  6. #define keydeng                14
  7. #define keyzuoyi  12

  8. code unsigned char KeyDisPlaybuf[16] =
  9. {
  10.     '1', '2', '3', '+',\
  11.     '4', '5', '6', '-',\
  12.     '7', '8', '9', '*',\
  13.     '<', '0', '=', '/'
  14. };

  15. long Count(char *ch, char len)//简单计算器 仅支持+-*/
  16. {
  17.     unsigned char i = 0;
  18.     char Operation;
  19.     long Num1=0,Num2=0;
  20.     while(i<len && ch[i]!='+' && ch[i]!='-' && ch[i]!='*' && ch[i]!='/')
  21.     {
  22.         Num1*=10;
  23.         Num1+=ch[i]-'0';
  24.         i++;
  25.     }
  26.     Operation=ch[i++];
  27.     while(i<len && ch[i]!='=')
  28.     {
  29.         Num2*=10;
  30.         Num2+=ch[i]-'0';
  31.         i++;
  32.     }
  33.     switch(Operation)
  34.     {
  35.         case'+':return Num1+Num2;
  36.         case'-':return Num1-Num2;
  37.         case'*':return Num1*Num2;
  38.         case'/':return Num1/Num2;
  39.     }
  40.         return 0;
  41. }

  42. void EasyCounter(void)
  43. {
  44.         unsigned char buff[30];
  45.         unsigned char text[30];
  46.         unsigned char key;
  47.         unsigned char i = 0;
  48.         do
  49.   {
  50.                         key = keycan();//读取键值       
  51.                         if(key!=0xff)//键值不等于0
  52.                         {
  53.                                 text[i++]=KeyDisPlaybuf[key];//记录键值对应的字符
  54.                                 text[i]='\0';
  55.         LCD_ShowStr(0,0,"                ");
  56.                                 LCD_ShowStr(16-strlen(text),0,text);
  57.                         }
  58.         if(key==keyzuoyi&&i>0)//按下"<"时删除一位
  59.           i-=2;
  60.         }while(key!=keydeng);//按下'='时结束输入
  61.         sprintf(buff, "%ld", Count(text, strlen(text)));
  62.   LCD_ShowStr(0,1,"                ");
  63.         LCD_ShowStr(16-strlen(buff),1,buff);
  64. }

  65. void main(void)
  66. {
  67.   LCD_Init();
  68.   while(1)
  69.   {
  70.     EasyCounter();
  71.   }
  72. }
复制代码
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. sbit LCD_RS= P2^4;
  4. sbit LCD_RW = P2^5;
  5. sbit LCD_E = P2^6;

  6. #define LCD_DATA P0

  7. static void LCD_Delay(unsigned char ms)
  8. {
  9.   unsigned char i;
  10.   while(ms--)
  11.   {
  12.     for(i = 0; i< 250; i++)
  13.     {
  14.       _nop_();
  15.       _nop_();
  16.       _nop_();
  17.       _nop_();
  18.     }
  19.   }
  20. }

  21. bit LCD_Busy()
  22. {
  23.   bit result;
  24.   LCD_RS = 0;
  25.   LCD_RW = 1;
  26.   LCD_E = 1;
  27.   _nop_();
  28.   _nop_();
  29.   _nop_();
  30.   _nop_();
  31.   result = (bit)(LCD_DATA & 0x80);
  32.   LCD_E = 0;
  33.   return result;
  34. }

  35. void LCD_WriteCmd(unsigned char cmd)
  36. {
  37.   while(LCD_Busy());
  38.   LCD_RS = 0;
  39.   LCD_RW = 0;
  40.   LCD_E = 0;
  41.   _nop_();
  42.   _nop_();
  43.   LCD_DATA = cmd;
  44.   _nop_();
  45.   _nop_();
  46.   _nop_();
  47.   _nop_();
  48.   LCD_E = 1;
  49.   _nop_();
  50.   _nop_();
  51.   _nop_();
  52.   _nop_();
  53.   LCD_E = 0;
  54. }

  55. void LCD_Pos(unsigned char row,unsigned char pos)
  56. {
  57.   row &= 0x1;
  58.   pos &= 0xF;
  59.   if (row) pos |= 0x40;
  60.   LCD_WriteCmd(pos | 0x80);
  61. }

  62. void LCD_WriteDat(unsigned char dat)
  63. {
  64.   while(LCD_Busy());
  65.   LCD_RS = 1;
  66.   LCD_RW = 0;
  67.   LCD_E = 0;
  68.   LCD_DATA = dat;
  69.   _nop_();
  70.   _nop_();
  71.   _nop_();
  72.   _nop_();
  73.   LCD_E = 1;
  74.   _nop_();
  75.   _nop_();
  76.   _nop_();
  77.   _nop_();
  78.   LCD_E = 0;
  79. }

  80. void LCD_ShowStr(unsigned char x, unsigned char y, unsigned char *dat)
  81. {
  82.   unsigned char i=0;
  83.   LCD_Pos(y,x);
  84.   while(dat[i] != '\0')
  85.   {
  86.     LCD_WriteDat(dat[i]);
  87.     i++;
  88.   }
  89. }

  90. void LCD_Init(void)
  91. {
  92.   LCD_WriteCmd(0x38);
  93.   LCD_Delay(1);
  94.   LCD_WriteCmd(0x0c);
  95.   LCD_Delay(1);
  96.   LCD_WriteCmd(0x06);
  97.   LCD_Delay(1);
  98.   LCD_WriteCmd(0x01);
  99.   LCD_Delay(1);
  100. }
复制代码
  1. #include "reg52.h"
  2. #include "keyboard.h"

  3. #define Key   P1

  4. code unsigned char KeyValueL[]={0xf7,0xfb,0xfd,0xfe};
  5. code unsigned char KeyValueH[]={0x70,0xb0,0xd0,0xe0};

  6. void KeyDelay(unsigned char xms)
  7. {
  8.   unsigned char i;
  9.   while(xms--)
  10.   {
  11.     for(i=0; i<120; i++);
  12.   }
  13. }
  14. unsigned char keycan(void)
  15. {
  16.   unsigned char i,j;
  17.   unsigned char tmp;
  18.   Key=0xf0;
  19.   if(Key!=0xf0)
  20.   {
  21.     KeyDelay(10);
  22.     if(Key!=0xf0)
  23.     {
  24.       for(i=0; i<4; i++)
  25.       {
  26.         Key=KeyValueL[i];
  27.         for(j=0; j<4; j++)
  28.         {
  29.           if((Key&0xf0)==KeyValueH[j])
  30.           {
  31.             tmp=i+j*4;
  32.             while(Key!=KeyValueL[i]);
  33.             return tmp;
  34.           }
  35.         }
  36.       }
  37.     }
  38.   }
  39.   return 0xff;
  40. }
复制代码






所有资料51hei提供下载:
原理图andPCB图.zip (9.1 MB, 下载次数: 58) 简易计算器.doc (676.5 KB, 下载次数: 53) c程序,和仿真.zip (89.59 KB, 下载次数: 75)




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:849787 发表于 2021-2-1 17:03 | 只看该作者
楼主的那个代码,关于LCD1602中RS和EN脚的标注是错位的,移植代码的时候要注意。功能能正常实现,就是对于除法和乘法,不能保留小数位,感觉实用性就不是很强了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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