main.c

/*
液晶显示计算器
对按键输入进行判断
判断是输入第几个数
输入第一个数
对第一个数进行显示(实时)
输入符号
将数字1上移,
最左侧显示符号
最右侧显示0
输入第二个数
在0处显示第二个数字
回车进行计算
回车将上一个字符整体上移
输出等于符号,输出结果
建立相应的标志位,在标志位中进行相应操作
*/
#include <reg52.h>
unsigned char step=0;
unsigned char oprt=0;
signed long num1=0;
signed long num2=0;
signed long result=0;
extern unsigned char TORH;
extern unsigned char TORL;
extern void ConfigTimer0(unsigned int ms);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);
extern unsigned char LongToString(unsigned char *str,signed long dat);
extern void KeyDriver();
extern void LcdFullClear();
extern void LcdAreaClear(unsigned char x,unsigned char y,unsigned char len);
extern void KeyScan();
void main()
{EA=1;//开启总中断ConfigTimer0(1);//设置1ms定时InitLcd1602(); //初始化液晶LcdShowStr(15,1,"0"); //初始显示0while(1){KeyDriver();}
}
void Reset()
{num1=0;num2=0;step=0;LcdFullClear();
}
void ShowOprt(unsigned char y,unsigned char type)//对符号进行显示
{switch(type){case 0:   LcdShowStr(0,y,"+"); break; case 1:  LcdShowStr(0,y,"-"); break;case 2:    LcdShowStr(0,y,"*"); break;case 3:    LcdShowStr(0,y,"/"); break;default:break;}
}
void NumKeyAction(unsigned char n)
{unsigned char str[12];unsigned char len;if(step>1)Reset();else if(step==0)//输入第一个数据{num1=num1*10+n;len=LongToString(str,num1);LcdShowStr(16-len,1,str);}else if(step==1)//输入第二个数据{num2=num2*10+n;len=LongToString(str,num2);LcdShowStr(16-len,1,str);     }
}
void OprtKeyAction(unsigned char type)//运算符动作函数
{unsigned char str[12];unsigned char len;if(step==0){len=LongToString(str,num1);LcdAreaClear(0,0,16-len);LcdShowStr(16-len,0,str);//将数字1移到上一层ShowOprt(1,type);   //显示运算符LcdAreaClear(1,1,14);LcdShowStr(15,1,"0");//显示0oprt=type;step=1;}
}
void GetResult()
{unsigned char len=0;unsigned char str[12];if(step==1){step=2;switch(oprt){case 0:result=num1+num2;break;case 1:result=num1-num2;break;case 2:result=num1*num2;break;case 3:result=num1/num2;break;default:break;}//显示操作ShowOprt(0,oprt);//上移运算符len=LongToString(str,num2);LcdAreaClear(1,0,15-len);//清除第一行LcdShowStr(16-len,0,str);//上移显示len=LongToString(str,result); //结果显示LcdAreaClear(1,1,15-len);//清除第二行LcdShowStr(0,1,"="); //显示等号LcdShowStr(16-len,1,str); //显示数值}
}
void interruptimer0() interrupt 1
{TH0=TORH;TL0=TORL;KeyScan();
}

lcd1602.c

/*
液晶显示相关代码
*/
#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS=P1^0;
sbit LCD1602_RW=P1^1;
sbit LCD1602_E=P1^5;
void LcdWaitReady()//读状态
{unsigned char sta;LCD1602_DB=0XFF;//开始就进行读取LCD1602_RS=0;LCD1602_RW=1;do{LCD1602_E=1;sta=LCD1602_DB;LCD1602_E=0;}while(sta&0x80);//判断高位为1,即为忙状态
}
void LcdWriteCmd(unsigned char cmd)//写入命令
{LcdWaitReady();//写入之前需要判断状态LCD1602_RS=0;LCD1602_RW=0;LCD1602_DB=cmd;LCD1602_E=1;LCD1602_E=0;
}
void LcdWriteDat(unsigned char dat)//写入数据
{LcdWaitReady();    //进行状态的判断LCD1602_RS=1;LCD1602_RW=0;LCD1602_DB=dat;LCD1602_E=1;LCD1602_E=0;
}
void LcdSetCursor(unsigned char x,unsigned char y)//进行光标位置的判断
{unsigned char addr;if(y)//y为1addr=0x40+x;elseaddr=0x00+x;LcdWriteCmd(addr|0x80);
}
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)//对字符进行显示
{LcdSetCursor( x, y);while(*str!='\0'){LcdWriteDat(*str++);}
}
void InitLcd1602()//进行液晶显示的初始化
{LcdWriteCmd(0x38);LcdWriteCmd(0x0c);LcdWriteCmd(0x06);//文字不动,地址加1LcdWriteCmd(0x01);//进行清屏显示
}
void LcdAreaClear(unsigned char x,unsigned char y,unsigned char len)    //清除len长度的字符
{LcdSetCursor(x,y);while(len--)LcdWriteDat(' ');
}
void LcdFullClear()
{LcdWriteCmd(0x01);
}

keyboard.c

#include <reg52.h>sbit KEY_IN_1  = P2^4;
sbit KEY_IN_2  = P2^5;
sbit KEY_IN_3  = P2^6;
sbit KEY_IN_4  = P2^7;
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2;
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表{ '1',  '2',  '3', 0x26 }, //数字键1、数字键2、数字键3、向上键{ '4',  '5',  '6', 0x25 }, //数字键4、数字键5、数字键6、向左键{ '7',  '8',  '9', 0x28 }, //数字键7、数字键8、数字键9、向下键{ '0', 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键
};unsigned char pdata KeySta[4][4] = {  //全部矩阵按键的当前状态{1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
};
extern void Reset();
extern void GetResult();
extern void NumKeyAction(unsigned char n);
extern void OprtKeyAction(unsigned char type);
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);void KeyAction(unsigned char keycode)
{if((keycode >= '0') && (keycode <= '9')){NumKeyAction(keycode - '0');    }else if(keycode == 0x26)//上{OprtKeyAction(0);}else if(keycode == 0x28)  //下{OprtKeyAction(1);}else if(keycode == 0x25) //左{OprtKeyAction(2);}else if(keycode == 0x27)  //右{OprtKeyAction(3);}else if(keycode == 0x0D)  //回车{GetResult();}else if(keycode == 0x1B)  //esc键{Reset();LcdShowStr(15, 1, "0");}
}
/* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
void KeyDriver()
{unsigned char i, j;static unsigned char pdata backup[4][4] = {  //按键值备份,保存前一次的值{1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}};for (i=0; i<4; i++)  //循环检测4*4的矩阵按键{for (j=0; j<4; j++){if (backup[i][j] != KeySta[i][j])    //检测按键动作{if (backup[i][j] != 0)           //按键按下时执行动作{KeyAction(KeyCodeMap[i][j]); //调用按键动作函数}backup[i][j] = KeySta[i][j];     //刷新前一次的备份值}}}
}/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
void KeyScan()
{unsigned char i;static unsigned char keyout = 0;   //矩阵按键扫描输出索引static unsigned char keybuf[4][4] = {  //矩阵按键扫描缓冲区{0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},{0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}};//将一行的4个按键值移入缓冲区keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;//消抖后更新按键状态for (i=0; i<4; i++)  //每行4个按键,所以循环4次{if ((keybuf[keyout][i] & 0x0F) == 0x00){   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下KeySta[keyout][i] = 0;}else if ((keybuf[keyout][i] & 0x0F) == 0x0F){   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起KeySta[keyout][i] = 1;}}//执行下一次的扫描输出keyout++;         //输出索引递增keyout &= 0x03;   //索引值加到4即归零switch (keyout)   //根据索引,释放当前输出引脚,拉低下次的输出引脚{case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;default: break;}
}

configtimer0.c

#include <reg52.h>
unsigned char TORH=0;
unsigned char TORL=0;
void ConfigTimer0(unsigned int ms)
{unsigned long tmp;tmp=11059200/12*ms/1000;tmp=65536-tmp;TORH=(unsigned char)(tmp>>8);TORL=(unsigned char)(tmp);TMOD&=0XF0;TMOD|=0X01;TH0=TORH;TL0=TORL;ET0=1;TR0=1;
}

longyostring.c

#include <reg52.h>
//主要是将数字转化为字符串
unsigned char LongToString(unsigned char *str,signed long dat)
{unsigned char len=0;unsigned char buf[12];signed char i=0;if(dat<0){dat=-dat;*str++='-';len++;}while(dat){buf[i++]=dat%10;dat/=10;}len+=i;while(i-->0){*str++=buf[i]+'0';}*str='\0';return len;
}

1602液晶显示简易计算器相关推荐

  1. 51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告)

    本设计: 基于51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告) 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号S0001 芯片可以替换为 ...

  2. 【蓝桥杯】CT107D单片机--简易计算器

    用蓝桥杯CT107D单片机做了一个简易计算器,能实现int型的加减乘除运算 使用1602显示屏作为显示器,矩阵键盘作为按键输入 本文的代码只是刚学单片机随性而为的,并没有考虑可读性,最近很多人因为这篇 ...

  3. 基于51单片机的简易计算器的实现

    目录 一.硬件简介 1.LCD1602液晶显示器介绍 (1)LCD1602的组成 (2)各引脚功能介绍 (3)DDRAM 2.矩阵按键介绍 (1)矩阵按键的优点: (2)原理: (3)检测方法: (4 ...

  4. c语言51单片机计算器,新基于51单片机的简易计算器

    <新基于51单片机的简易计算器>由会员分享,可在线阅读,更多相关<新基于51单片机的简易计算器(24页珍藏版)>请在人人文库网上搜索. 1.基于51单片机的简易计算器1.前言: ...

  5. 51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真

    51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真 文章目录 51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真 实验内容 一.实验一 矩阵键盘中断实验 数码管显示 1.仿 ...

  6. 【C51单片机】简易计算器设计(仿真)

    1.功能描述 设计一个简易计算器,模拟常见计算器的加减乘除运算功能,通过1602液晶屏来显示数字.4*4的矩阵按键来模拟计算机的按键, 2.PROTEUS中设计的电路图 3.源代码 #include ...

  7. 怎么用python自制计算公式_手把手教你用python制作简易计算器,能够记录你使用的情况...

    话不多说,首先先看效果图,它能够记录你在使用过程中的历史,方便你查看是否有错: 接下来就仔细分析一下是如何制作的: 简易计算器 第一步:导入资源库 在过程中使用到了tkinter这个资源库,win+R ...

  8. python表达式计算器_Python正则表达式实现简易计算器功能示例

    本文实例讲述了Python正则表达式实现简易计算器功能.分享给大家供大家参考,具体如下: 需求:使用正则表达式完成一个简易计算器. 功能:能够计算简单的表达式. 如:1*2*((1+2)/(2+3)+ ...

  9. PyQt5 简易计算器

    剩下计算函数(self.calculator)未实现,有兴趣的朋友可以实现它 [知识点] 1.利用循环添加按钮部件,及给每个按钮设置信号/槽 2.给按钮设置固定大小:button.setFixedSi ...

最新文章

  1. linux——环境变量与文件查找
  2. 测试和恢复性的争论:面向对象vs.函数式编程
  3. 3月28日云栖精选夜读:小程序,会是下一个创业风口吗?
  4. ThinkPHP 数据库操作之数据表模型和基础模型 ( Model )
  5. 网站CSS样式不起作用,或只有一部分起作用?随手记
  6. 智能合约开发solidity编程语言实例
  7. 输入文字加下划线_微信昵称这样设置,文字加上下划线!
  8. css学习_css用户界面样式
  9. Spark 中 map 与 flatMap 的区别
  10. 20050611:超级伙伴?
  11. pr人像磨皮美容插件:Beauty Box for Premiere Pro
  12. linux安装文泉驿字体,文泉驿的安装及配置
  13. 风行状告芒果卫视,电视台“耍霸道”屡禁不止?
  14. matlab for循环与subs应用 求解
  15. Java通过快递鸟-查询物流
  16. 关于fstream的flush
  17. 瑞幸咖啡贵不贵?咖啡不贵,商业却很贵
  18. 字节流和字符流(详解)
  19. LeetCode_715. Range Module
  20. java 电子围栏_怎么画电子围栏,并进行电子围栏进出判断?

热门文章

  1. OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
  2. python获取文件路径名_python文件名获取文件路径
  3. 小米体脂秤2内部方案一览,附拆解维修记录
  4. 远程连接华为云服务器上的MySQL
  5. 【机器学习】专题学习丨1. 损失函数loss积累丨
  6. 实现软件GPS的软硬件设计讨论
  7. GeoStru.CVSoil.v2014.7.2.47 1CD
  8. 计算H时M分S秒以后是_消防考试必会计算题汇总!
  9. 通俗理解OvO与OvR
  10. web前端期末大作业网页设计与制作 ——汉口我的家乡旅游景点 5页HTML+CSS+JavaScript