1602液晶显示简易计算器
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液晶显示简易计算器相关推荐
- 51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告)
本设计: 基于51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告) 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号S0001 芯片可以替换为 ...
- 【蓝桥杯】CT107D单片机--简易计算器
用蓝桥杯CT107D单片机做了一个简易计算器,能实现int型的加减乘除运算 使用1602显示屏作为显示器,矩阵键盘作为按键输入 本文的代码只是刚学单片机随性而为的,并没有考虑可读性,最近很多人因为这篇 ...
- 基于51单片机的简易计算器的实现
目录 一.硬件简介 1.LCD1602液晶显示器介绍 (1)LCD1602的组成 (2)各引脚功能介绍 (3)DDRAM 2.矩阵按键介绍 (1)矩阵按键的优点: (2)原理: (3)检测方法: (4 ...
- c语言51单片机计算器,新基于51单片机的简易计算器
<新基于51单片机的简易计算器>由会员分享,可在线阅读,更多相关<新基于51单片机的简易计算器(24页珍藏版)>请在人人文库网上搜索. 1.基于51单片机的简易计算器1.前言: ...
- 51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真
51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真 文章目录 51单片机开发 矩阵键盘中断实验与简易计算器及proteus仿真 实验内容 一.实验一 矩阵键盘中断实验 数码管显示 1.仿 ...
- 【C51单片机】简易计算器设计(仿真)
1.功能描述 设计一个简易计算器,模拟常见计算器的加减乘除运算功能,通过1602液晶屏来显示数字.4*4的矩阵按键来模拟计算机的按键, 2.PROTEUS中设计的电路图 3.源代码 #include ...
- 怎么用python自制计算公式_手把手教你用python制作简易计算器,能够记录你使用的情况...
话不多说,首先先看效果图,它能够记录你在使用过程中的历史,方便你查看是否有错: 接下来就仔细分析一下是如何制作的: 简易计算器 第一步:导入资源库 在过程中使用到了tkinter这个资源库,win+R ...
- python表达式计算器_Python正则表达式实现简易计算器功能示例
本文实例讲述了Python正则表达式实现简易计算器功能.分享给大家供大家参考,具体如下: 需求:使用正则表达式完成一个简易计算器. 功能:能够计算简单的表达式. 如:1*2*((1+2)/(2+3)+ ...
- PyQt5 简易计算器
剩下计算函数(self.calculator)未实现,有兴趣的朋友可以实现它 [知识点] 1.利用循环添加按钮部件,及给每个按钮设置信号/槽 2.给按钮设置固定大小:button.setFixedSi ...
最新文章
- linux——环境变量与文件查找
- 测试和恢复性的争论:面向对象vs.函数式编程
- 3月28日云栖精选夜读:小程序,会是下一个创业风口吗?
- ThinkPHP 数据库操作之数据表模型和基础模型 ( Model )
- 网站CSS样式不起作用,或只有一部分起作用?随手记
- 智能合约开发solidity编程语言实例
- 输入文字加下划线_微信昵称这样设置,文字加上下划线!
- css学习_css用户界面样式
- Spark 中 map 与 flatMap 的区别
- 20050611:超级伙伴?
- pr人像磨皮美容插件:Beauty Box for Premiere Pro
- linux安装文泉驿字体,文泉驿的安装及配置
- 风行状告芒果卫视,电视台“耍霸道”屡禁不止?
- matlab for循环与subs应用 求解
- Java通过快递鸟-查询物流
- 关于fstream的flush
- 瑞幸咖啡贵不贵?咖啡不贵,商业却很贵
- 字节流和字符流(详解)
- LeetCode_715. Range Module
- java 电子围栏_怎么画电子围栏,并进行电子围栏进出判断?
热门文章
- OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
- python获取文件路径名_python文件名获取文件路径
- 小米体脂秤2内部方案一览,附拆解维修记录
- 远程连接华为云服务器上的MySQL
- 【机器学习】专题学习丨1. 损失函数loss积累丨
- 实现软件GPS的软硬件设计讨论
- GeoStru.CVSoil.v2014.7.2.47 1CD
- 计算H时M分S秒以后是_消防考试必会计算题汇总!
- 通俗理解OvO与OvR
- web前端期末大作业网页设计与制作 ——汉口我的家乡旅游景点 5页HTML+CSS+JavaScript