基于单片机的lcd1602的多功能计算器
51单片机控制lcd1602实现计算器

//利用51单片机控制LCD1602,实现加减乘除运算#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define DATE_IO P0//P0口并行传输数据(LCD1602的数据端接P0口)sbit RS=P1^0;//LCD1602寄存器选择端sbit E=P1^2; //使能信号端sbit RW=P1^1;//读写控制端sbit deng=P1^3;//结果sbit shuzi11=P3^2;//前面的数字加1(因为我的按键是与P3口相连的)sbit shuzi22=P3^7; //后面的数字加1sbit jia=P3^3;//加号sbit jian=P3^4;//减号sbit cheng=P3^5;//乘号sbit chu=P3^6;//除号uint countqian=0,counthou=0;//数值uchar qian,bai,shi,ge,a=0;uchar code table1[]="0123456789";uchar code table2[]="+-*/";//**********************延时函数***************************************** void delay_us(unsigned int n){if(n==0)return ;while(--n);}void delay_ms(uint i){unsigned char a,b;for (a=1;a<i;a++)for(b=1;b;b++);}void delay(uint z){uint x,y;for(x=110;x>0;x--)for(y=z;y>0;y--);}//***********************************************************************//*********************控制LCD1602的函数*******************************void write_command(uchar come)//写指令函数{RS=0;//选择指令寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=come;delay_us(5);E=0;RS=1;}void write_date(uchar date)//写数据函数{RS=1;//选择数据寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=date;delay_us(5);E=0;RS=0;}//***************************************************************************** ***//**************************液晶初始化函数(基本上就是这个模式)*******************void init()//液晶初始化函数{RW=0;//低电平时进行写操作(高电平时进行读操作)E=0;write_command(0x38);//设置LCD两行显示,一个数据由5*7点阵表示,数据由8跟线传输delay_ms(5);write_command(0x01);//清除屏幕显示delay_ms(5);write_command(0x06);//设定输入方式,增量不移位delay_ms(5);write_command(0x0c);//开整体显示,关光标,不闪烁delay_ms(5);}//***************************************************************************** *****void jiayiqian()//前边数字加1计数函数{if(shuzi11==0)//如果前面加1的按键按下{delay(50);//消除抖动countqian=countqian+1;}if(countqian==999)//记到999归0countqian=0;}void jiayihou()//后边数字加1计数函数{if(shuzi22==0)//如果后面加1的按键按下{delay(50);//消除抖动counthou=counthou+1;}if(counthou==999)//记到999归0counthou=0;}void fuhao()//+,-,*,/运算号{if(jia==0)//如果加号按下{while(!jia);//等待按键的释放write_date(table2[0]);//显示'+'a=1;//加号按下的标志}if(jian==0)//如果减号按下{while(!jian);//等待按键的释放write_date(table2[1]);//显示'-'a=2;//减号按下的标志}if(cheng==0)//如果乘号按下{while(!cheng);//等待按键的释放write_date(table2[2]);//显示'*'a=3; //乘号按下的标志}if(chu==0)////如果除号按下{while(!chu);//等待按键的释放write_date(table2[3]);//显示'/'a=4;//除号按下的标志}}void chaiqian()//将前边各位数字拆开函数{bai=countqian/100;//求百位数字shi=countqian%100/10;//求十位数字ge=countqian%10;//求各位数字}void chaihou()//将后边各位数字拆开函数{bai=counthou/100;//求百位数字shi=counthou%100/10;//求十位数字ge=counthou%10;//求各位数字}void chaijiejia()//将相加结果各位数字拆开函数{qian=(countqian+counthou)/1000;//求千位数字bai=(countqian+counthou)%1000/100;//求百位数字shi=(countqian+counthou)%100/10;//求十位数字ge=(countqian+counthou)%10;//求各位数字}void chaijiejian()//将相减结果各位数字拆开函数{qian=(countqian-counthou)/1000;//求千位数字bai=(countqian-counthou)%1000/100;//求百位数字shi=(countqian-counthou)%100/10;//求十位数字ge=(countqian-counthou)%10;//求各位数字}void chaijiecheng()//将相乘结果各位数字拆开函数{qian=(countqian*counthou)/1000;//求千位数字bai=(countqian*counthou)%1000/100;//求百位数字shi=(countqian*counthou)%100/10;//求十位数字ge=(countqian*counthou)%10;//求各位数字}void chaijiechu()//将相除结果各位数字拆开函数(只取了模值){qian=(countqian/counthou)/1000;//求千位数字bai=(countqian/counthou)%1000/100;//求百位数字shi=(countqian/counthou)%100/10;//求十位数字ge=(countqian/counthou)%10;//求各位数字}void xianshiqian()//显示前边数字{write_command(0x80);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位fuhao();//显示运算号delay(50);//改变数值可以修改数字滚动的速度}void xianshihou()//显示后边数字{write_command(0x80+4);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void xianshijie()//显示结果{write_command(0xc0);//设置显示地址为LCD第二行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[qian]);//第一位显示千位write_date(table1[bai]);//第二位显示百位write_date(table1[shi]); //第三位显示十位write_date(table1[ge]); //第四位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void main()//主函数{init();//调用液晶初始化函数while(1){jiayiqian();//调用前边数字加1计数函数chaiqian();//调用将前边数字各位数字拆开函数xianshiqian();//显示前边数字jiayihou();//调用后边数字加1计数函数chaihou();//调用将后边数字各位数字拆开函数xianshihou();//显示后边数字if(deng==0)//控制显示结果的按键按下{if(a==1)//计算的是加法{chaijiejia();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==2)//计算的是减法{chaijiejian(); //将结果的各位数字拆分开xianshijie();//显示结果}if(a==3)//计算的是乘法{chaijiecheng();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==4) //计算的是除法{chaijiechu();//将结果的各位数字拆分开xianshijie(); //显示结果}}}}。
51单片机的1602计算器

51单片机的1602计算器一、51 单片机和 1602 液晶显示屏简介51 单片机是指英特尔公司生产的 8051 系列单片机,它具有丰富的资源,包括 I/O 端口、定时器、中断等。
通过编程,可以让 51 单片机完成各种复杂的任务。
1602 液晶显示屏是一种字符型液晶显示模块,它能够显示两行,每行 16 个字符。
1602 液晶显示屏的控制方式相对简单,通过发送特定的指令和数据,就可以实现字符的显示。
二、硬件设计要实现 51 单片机的 1602 计算器,首先需要进行硬件设计。
硬件部分主要包括 51 单片机最小系统、1602 液晶显示屏、按键等。
51 单片机最小系统通常包括单片机芯片、晶振电路和复位电路。
晶振电路为单片机提供时钟信号,复位电路则保证单片机能够正常启动。
1602 液晶显示屏与51 单片机的连接需要用到一些数据线和控制线。
数据线用于传输要显示的数据,控制线用于控制显示屏的工作状态。
按键用于输入数字和运算符,常见的按键有数字键 0 9 、运算符+、、、/以及等于号=等。
三、软件编程软件编程是实现 51 单片机 1602 计算器的关键。
在编程过程中,需要实现以下几个主要功能:1、初始化 1602 液晶显示屏在程序开始时,需要对 1602 液晶显示屏进行初始化,设置显示模式、光标显示等。
2、按键扫描通过不断扫描按键状态,获取用户输入的数字和运算符。
3、数据处理根据用户输入的数字和运算符,进行相应的计算,并将结果存储起来。
4、显示结果将计算结果显示在 1602 液晶显示屏上。
```cinclude <reg52h> //包含 51 单片机的头文件//定义 1602 液晶显示屏的控制引脚sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;//定义 1602 液晶显示屏的数据引脚sbit D0 = P0^0;sbit D1 = P0^1;sbit D2 = P0^2;sbit D3 = P0^3;sbit D4 = P0^4;sbit D5 = P0^5;sbit D6 = P0^6;sbit D7 = P0^7;//定义按键引脚sbit key0 = P1^0;sbit key1 = P1^1;sbit key2 = P1^2;sbit key3 = P1^3;sbit key4 = P1^4;sbit key5 = P1^5;sbit key6 = P1^6;sbit key7 = P1^7;sbit key8 = P3^0;sbit key9 = P3^1;sbit key_add = P3^2;sbit key_sub = P3^3;sbit key_mul = P3^4;sbit key_div = P3^5;sbit key_eq = P3^6;//定义变量unsigned char num1, num2, op, result;unsigned char flag = 0; //标志位,用于判断输入状态//写指令函数void write_command(unsigned char command){RS = 0;RW = 0;EN = 0;P0 = command;EN = 1;EN = 0;}//写数据函数void write_data(unsigned char data){RS = 1;RW = 0;EN = 0;P0 = data;EN = 1;EN = 0;}//初始化 1602 液晶显示屏函数void init_1602(){write_command(0x38);// 8 位数据,2 行显示,5x7 点阵write_command(0x0c);//显示开,光标关,闪烁关write_command(0x06);//字符右移,地址指针加 1 write_command(0x01);//清屏}//按键扫描函数void key_scan(){if (key0 == 0){delay_ms(10);//消抖if (key0 == 0){if (flag == 0){num1 = num1 10 + 0;write_data('0');}else{num2 = num2 10 + 0;write_data('0');}}while (!key0);//等待按键松开}//其他按键扫描类似}//计算函数void calculate(){switch (op){case '+':result = num1 + num2;break;case '':result = num1 num2;break;case '':result = num1 num2;break;case '/':if (num2!= 0)result = num1 / num2;elsewrite_data('E');//除数为 0 ,显示错误break;}}//主函数void main(){init_1602();while (1){key_scan();if (key_add == 0 || key_sub == 0 || key_mul == 0 ||key_div == 0){delay_ms(10);//消抖if (key_add == 0){op ='+';flag = 1;write_data('+');}//其他运算符处理类似}if (key_eq == 0){delay_ms(10);//消抖if (key_eq == 0){calculate();write_data(result);num1 = 0;num2 = 0;flag = 0;}}}}```上述代码只是一个简单的示例,实际应用中还需要进行更多的优化和完善,比如处理输入错误、添加更多的功能等。
基于单片机的LCD1602科学计算器设计

.作者: 学号:系:电子工程与光电技术系专业:电子信息工程题目:基于单片机的液晶计算器设计南京理工大学毕业设计(论文)评语学生姓名:班级、学号:题目:基于单片机的液晶计算器设计综合成绩:毕业设计(论文)评语毕业设计说明书(论文)中文摘要毕业设计说明书(论文)外文摘要目次1 绪论 (1)1.1 计算器的简介 (1)1.2 单片机的简介与发展趋势 (1)1.3 设计的目的与意义 (2)2 简易计算器的设计实现 (3)2.1 计算器系统模块 (3)2.2 核心控制器选择 (3)2.3 显示电路的设计选择 (3)2.4 键盘设计方案选择 (4)2.4.1 按键消抖方案选择 (4)2.5 本章小结 (4)3 硬件电路设计 (6)3.1 单片机介绍 (6)3.1.1 AT89C52管脚说明 (6)3.2 单片机最小系统 (7)3.2.1 复位电路 (8)3.2.2 时钟电路 (9)3.3 显示模块设计 (9)3.4 按键模块设计 (11)3.5 本章小结 (12)4 软件设计 (13)4.1 系统总设计流程 (13)4.2 按键程序流程设计 (14)4.3 LCD1602显示流程设计 (15)4.4 本章小结 (17)5 功能仿真及其结果 (18)5.1 软件简介 (18)5.1.1 KEIL软件简介 (18)5.1.2 PPOTUES ISIS简介 (18)5.2 仿真结果与操作说明 (18)5.2.1 系统总体仿真 (18)5.2.2 系统的操作说明 (19)5.3 加减乘除四则运算显示结果 (20)5.4 计算器扩展功能的实现 (22)5.4.1 三角函数的实现 (22)5.4.2 对数和指数函数的实现 (23)5.4.3 平方根与倒数以及余数的实现 (25)5.5 本章小结 (26)结论 (27)致谢 (28)参考文献 (29)1 绪论随着科技的日益更新,嵌入式系统与我们的生活愈发息息相关,一些能够使用单片机完成的工具也频繁出现于日常生活中,比如计算器。
STC51单片机开发板计算器LCD1602显示浮点计算设计报告

嵌入式系统原理及应用课程设计报告姓名:学号:指导老师:目录引言 (3)第一章硬件介绍 (4)1.1单片机介绍 (4)1.2 设计所用开发板的介绍 (5)1.3 LCD1602的原理及其应用 (7)1.3.1开发板硬件连接关系 (7)1.3.2液晶屏LCD1602的功能及应用 (8)1.3.31602LCD的指令说明及时序 (9)1.3.4 1602LCD的RAM地址映射及标准字库表 (11)1.4开发板矩阵键盘原理及应用 (12)第二章设计思路、仿真及调试 (15)2.1 设计方法 (15)2.2 硬件简介 (15)2.3 软件设计 (15)2.3.1 矩阵键盘 (15)2.3.2 LCD1602 (22)第三章设计结果 (24)第四章设计总结 (27)附录 (28)引言目前单片机渗透到我们生活的各个领域.几乎很难找到哪个领域没有单片机的踪迹。
导弹的导航装置.飞机上各种仪表的控制.计算机的网络通讯与数据传输.工业自动化过程的实时控制和数据处理.广泛使用的各种智能IC卡.民用豪华轿车的安全保障系统.录像机、摄像机、全自动洗衣机的控制.以及程控玩具、电子宠物等等.这些都离不开单片机。
更不用说自动控制领域的机器人、智能仪表、医疗器械了。
因此.单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。
单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域.大致可分如下几个范畴:(1)在智能仪器仪表上的应用(2)在工业控制中的应用(3)在家用电器中的应用(4)在计算机网络和通信领域中的应用(5)单片机在医用设备领域中的应用(6)在各种大型电器中的模块化应用(7)单片机在汽车设备领域中的应用此外.单片机在工商.金融.科研、教育.国防航空航天等领域都有着十分广泛的用途。
随着智能化的逐步提高.单片机在我们生活中得到了越来越广泛的应用.其是一种集成在电路芯片.是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。
基于单片机的简易多功能计算器

目录一、设计总体思路,基本原理和框图 (1)1.1 设计总体思路 (1)1.2基本原理 (1)1.3设计框图 (1)1.3.1硬件原理图 (1)1.3.2软件流程图 (2)二、单元函数设计 (2)2.1 单片机模块 (2)2.2键盘控制模块 (2)2.3 LCD显示模块 (3)三、程序调试与结果 (4)3.1加法调试 (4)3.2幂运算调试 (4)3.3报错调试 (4)四、总结与体会................................ 错误!未定义书签。
附录. (4)参考文献 (21)一、设计总体思路,基本原理和框图1.1 设计总体思路本电路设计采用AT89S52单片机为核心,利用晶振产生频率为1HZ 的时钟脉冲信号,利用液晶屏LCD1602显示计算信息,通过对AT89S52单片机的编程控制液晶屏LCD1602的显示。
显示计算和简易计算的信息同在LCD1602,通过按键切换选。
1.2基本原理图1-11.3设计框图1.3.1硬件原理图图1-2AT89C51 单片机 模块 1602LCD 液晶显示矩阵键盘1.3.2软件流程图图1-3二、单元函数设计2.1 单片机模块本次设计采用AT89C51单片机,以下为其标准功能:4k 字节Flash 闪速存储器,128字节内部RAM,32 个I/O 口线,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
同时,AT89C51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式保存RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位2.2键盘控制模块本次设计使用的是PROTUES中的KEYPAD键盘。
使用此键盘的难度在于它的数据是分散的,并且不是由小到大排列的,这就要求我们在编写程序的时候对键值进行处理。
基于单片机的lcd1602的多功能计算器

单片机原理与应用技术课程设计基于51单片机的多功能计算器院系:机电工程学院专业(班级):电子信息工程1班姓名:学号: 20134081006指导教师:邵海龙职称:讲师完成日期:2015 年9月22日评定成绩:关键词:单片机;液晶显示;计算器;目录引言 (3)1 单片机及其应用……………………………………………………………………...3.1.1单片机介绍 (3)1.2单片机的应用 (4)1.3 STC89C52单片机 (4)2 液晶屏LCD1602原理及应用 (5)2.1液晶屏LCD1602介绍及工作原理 (5)2.2 液晶屏LCD1602的功能及应用 (5)3 设计思路、仿真及调试 (7)3.1设计方法 (7)3.2硬件设计............................................................................... . (7)3.2.1复位电路 (7)3.2.2 液晶屏LCD1602显示电路 (8)3.2.3 4*4键盘的设计 (9)3.2.5 多功能计算器的总电路 (10)3.3软件设计 (10)3.4软件仿真 (17)3.5硬件调试 (18)4 结束语.............................................................. .. (18)谢辞 (18)参考文献 (19)1 单片机及其应用1.1单片机介绍单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能1.2单片机的应用STC89C52 是STC公司推出的一款超强抗干扰,加密性强,在线可编程,高速,低功耗CMOS 8位单片机。
片内含 8k bytes 的可反复擦写Flash只读程序存储器和256 bytes 的随机数据存储器(RAM),器件采用STC公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和Flash 存储单元,功能强大的STC89C52单片机适合于许多较为复杂控制应用场合。
1602液晶显示计算器00.

1602液晶显示计算器院系:机械工程学院班级:测控1003姓名:金飞完成时间:2012年11月18日摘要本设计由51单片机作为核心,4*4矩阵键盘作为输入,将数据输入到单片机内部处理,并通过1602液晶显示出来运算及其结果。
本设计具有成本低廉,操作简单。
可作为日常简单计算使用。
关键词:51单片机、矩阵键盘、1602液晶。
一、外观介绍:二、电路仿真:P0.0~P0.7引脚接lcd的D0-D7,P3口接矩阵键盘。
单片机的P2.4、P2.0、P2.3脚分别接到LCD的RS、R/W、E管。
三、显示电路,LCD1602A的引脚详细介绍:采用LCD1602A来显示,要求能显示两行。
它的D—7D引脚分别接到单片机的P0.0~P0.7引脚;RS、R/W、E管脚分别接到单片机的P2.4、P2.0、P2.3 。
具体连接见后面的电路图。
以下是1602的16进制ASCII码表三、矩阵键盘扫描电路P3口的P3.0,P3.1,P3.2和P3.3四根线作为按键的行输出线,用P3.4,P3.5,P3.6和P3.7作为按键的列输入线。
依次给某一行低电平,再判断哪一列是低电平。
于是就判断出哪行和哪列导通。
对于不同的组合可以确定所有按键位置,将位置赋值到一个变量中,以供使用。
具体来说:假如按下的是数字5键(编号6——位于第二行第二列),首先置第一行为低电平其他7位为高电平P0=0xfe,再检测高四位的电平(P0=P&0xf0 ),因为列没有一条与第一行相导通,所以P0的高位还是高电平的。
然后再换第二行P0=0xfd,同理检测高四位(P0=P&0xf0 )得出P0=0xd0,则5键所在位置为第二行第二列,然后num赋值为6。
四、程序分析可知共分为七个模块:键盘扫描部分,定义各个位置上的键值部分,延迟部分,存贮部分,液晶显示部分,运算部分,动态显示部分。
主程序流程图如下:否判断是否有键按下五、程序#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit 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;float a_c,b_c;uchar 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;z>0;z--)for(y=0;y<110;y++);}void check(){do{P0=0xFF;rs=0;rw=1;lcden=0;delay(1);lcden=1;}while(busy==1);}void write_com(uchar com){P0=com;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(0x01);write_com(0x38);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;fuhao=0;}void keyscan(){P3=0xfe;if(P3!=0xfe){delay(20);if(P3!=0xfe){temp=P3&0xf0;{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){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;}i=table1[num];write_date(0x30+i);}P3=0xfd;if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;{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==6&&num!=7) {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;}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;{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) {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;}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){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:{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-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)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();}}以下程序才对#include<reg52.h> //头文件#define uint unsigned int //#define uchar unsigned charsbit lcden=P2^5; //定义引脚sbit rs=P2^4;sbit rw=P2^0;sbit busy=P0^7;char chufa=0;char chenfa=0;char jiafa=0;char jianfa=0;/***sbit dula=P2^6;sbit wela=P2^7;***/uchar code table2[]="overflow";char i,j,temp,num,num_1;long a,b,c; //a,第一个数b,第二个数c,得数long a_c,b_c; //floatuchar 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;z>0;z--)for(y=0;y<110;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;/***dula=0;wela=0;***/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); //延迟20msif(P3!=0xfe){temp=P3&0xf0;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'或'9if(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表示除号已按chufa++;if (chufa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chufa = 0;}/*** chenfa++;if(chenfa==1){write_date(0x21);chenfa=0;}***/}i=table1[num];write_date(0x30+i);}if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;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==6)//如果按下的是'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表示乘号已按chenfa++;if (chenfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chenfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;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表示减号已按jianfa++;if (jianfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jianfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;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;rw=0;rs=0;if(fuhao==1){write_com(0x0f);//按下等于键,光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格c=a+b;delay(10);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(0x0f);//光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x0f); //0x80+0x4fwrite_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);//write_date(0x30);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x40+0x4f); //0x80+0x4fwrite_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;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;jiafa++;if (jiafa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jiafa = 0;}}break;}}}/*void key(){P3=0xfe;if(P3!=0xfe){delay(5);if(P3!=oxfe){temp=P3&0xf0;}}}*/main(){init();while(1) {keyscan(); }}。
lcd1602计算器

{
uchar y;
for(z;z>0;z--)
for(y=0;y<110;y++);
}
void check()
{
do{
P0=0xFF;
rs=0;
rw=1;
lcden=0;
delay(1);
lcden=1;
}while(busy==1);
}
void write_com(uchar com)
1.实验目的。
1、掌握单片机定时器、中断、键盘扫描、动态显示及数值计算的综合运用能力;
2、掌握编程的运用能力;
3、设计一只简易的16键计算器。
2.实验内容。
图5-1 简易16键计算器
编程实现图5-1的简易16键4位十进制整数计算器的功能。要求:
1.设计4*4的键盘,其中10个数字键0~9,其余6个为“+” “-” “*”“/” “=”和“C”
3、计算器的主程序读取键盘缓冲区的键码,驱动计算器的运行。
4、计算中需要十进制与十六进制(或二进制)转化。
3、系统硬件设计电路图
矩阵键盘的硬件接线仿真图
LCD1602的接线仿真图
P0.0~P0.7引脚接lcd的D0-D7,P3口接矩阵键盘。单片机的P2.4、P2.0、P2.3脚分别接到LCD的RS、R/W、E管。
分析可知共分为七个模块:键盘扫描部分,定义各个位置上的键值部分,延迟部分,存贮部分,液晶显示部分,运算部分,动态显示部分。运用了proteus软件仿真电路,使用keil软件进行程序的编写与调试。
Keil软件编写过程截图:
Proteus软件仿真电路图编写过程截图:
主程序流程图如下:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机原理与应用技术课程设计基于51单片机的多功能计算器院系:机电工程学院专业(班级):电子信息工程1班姓名:学号: 20134081006指导教师:邵海龙职称:讲师完成日期:2015 年9月22日评定成绩:关键词:单片机;液晶显示;计算器;目录引言 (3)1 单片机及其应用……………………………………………………………………...3.1.1单片机介绍 (3)1.2单片机的应用 (4)1.3 STC89C52单片机 (4)2 液晶屏LCD1602原理及应用 (5)2.1液晶屏LCD1602介绍及工作原理 (5)2.2 液晶屏LCD1602的功能及应用 (5)3 设计思路、仿真及调试 (7)3.1设计方法 (7)3.2硬件设计............................................................................... . (7)3.2.1复位电路 (7)3.2.2 液晶屏LCD1602显示电路 (8)3.2.3 4*4键盘的设计 (9)3.2.5 多功能计算器的总电路 (10)3.3软件设计 (10)3.4软件仿真 (17)3.5硬件调试 (18)4 结束语.............................................................. .. (18)谢辞 (18)参考文献 (19)1 单片机及其应用1.1单片机介绍单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能1.2单片机的应用STC89C52 是STC公司推出的一款超强抗干扰,加密性强,在线可编程,高速,低功耗CMOS 8位单片机。
片内含 8k bytes 的可反复擦写Flash只读程序存储器和256 bytes 的随机数据存储器(RAM),器件采用STC公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和Flash 存储单元,功能强大的STC89C52单片机适合于许多较为复杂控制应用场合。
1.3 STC89C52单片机3.2 STC89C52外部结构及特性其外形封装有两种方式:双列直插式40脚封装(DIP)和方形44脚封装(PLCC),直插式40 脚封装(DIP)和外部总线结构如图2和图3所示:图3.1 STC89C52引脚排列图3.2 外部总线STC89C52的 4 个 8 位I/O口的功能说明如下:(1)P0口:P0 口是一个 8 位漏极开路的双向 I/O 口。
作为输出口,每位能驱动8个TTL逻辑电平。
对P0端口写“1”时,引脚用作高阻抗输入。
当访问外部程序和数据存储器时,P0口也被作为低 8 位地址/数据复用。
在这种模式下,P0具有内部上拉电阻。
在flash 编程时,P0口也用来接收指令字节;在程序校验时,输出指令字节。
程序校验时,需要外部上拉电阻。
(2)P1口:P1口是一个具有内部上拉电阻的8位双向 I/O口,p1输出缓冲器能驱动4个TTL 逻辑电平。
对P1端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
此外,P1.0 和 P1.2 分别作定时器/计数器 2 的外部计数输入(P1.0/T2)和定时器/计数器 2 的触发输入(P1.1/T2EX)。
在 flash 编程和校验时,P1口接收低8位地址字节。
(3)P2口:P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4 个 TTL 逻辑电平。
对 P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在访问外部程序存储器或用 16 位地址读取外部数据存储器(例如执行MOVX @DPTR)时,P2口送出高八位地址。
在这种应用中,P2口使用很强的内部上拉发送 1。
在使用8 位地址(如 MOVX @RI)访问外部数据存储器时,P2 口输出 P2 锁存器的内容。
在 flash 编程和校验时,P2 口也接收高 8 位地址字节和一些控制信号。
(4)P3口:P3口是一个具有内部上拉电阻的8位双向I/O口,p2 输出缓冲器能驱动4个TTL逻辑电平。
对P3端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在 flash 编程和校验时,P3 口也接收一些控制信号。
P3 口亦作为AT89C52特殊功能(第二功能)使用,如下所示:P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 INTO(外部中断0 输入口)P3.3 INT1(外部中断 1 输入口)P3.4 TO(定时器 0 外部输入)P3.5 TI(定时器 1 外部输入)P3.6 WR(外部数据存储器写选通信号)P3.7(外部数据存储器读选通信号)3.3 STC89C52内部组成STC89C52单片机在一块芯片中集成了 CPU、RAM、ROM、定时器/计数器、看门狗和多种功能的 I/O 口设备的等,相当于一台计算机所需要的基本功能部件。
STC89C52单片机内包含的具体部分如下:一个8 位 CPU。
一个片内振荡器及时钟电路。
8KB Flash 程序存储器。
256 B RAM 数据存储器。
三个16 位定时器/计数器。
可寻址 64KB 的外部数据存储器和 64KB 的外部程序存储器空间的控制电路。
32 条可编程的 I/O线(4组8 位并行 I/O端口)。
一个可编程全双工串口通信。
8 个中断源、两个优先级嵌套中断结构。
STC89C52单片机的框图如图3.3所示,各功能部件由内部总线连接在一起。
图3.3 STC89C52单片机框图2 液晶屏LCD1602原理及应用2.1液晶屏LCD1602介绍LCD1602已很普遍了,具体介绍我就不多说了,市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚)2.2 液晶屏LCD1602的功能及应用5.2.1 1602LCD液晶显示屏1602LCD显示屏是一种工业字符型液晶,所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符,目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
1602液晶模块内部的字符发生存储器已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
其管脚功能表和寄存器选择控制表如表5.1和表5.1所示:表5.1 管脚功能表表5.2寄存器选择控制表3 设计思路、仿真及调试3.1设计方法本电路设计采用STC89C51单片机为核心,利用晶振产生频率为1HZ的时钟脉冲信号,利用液晶屏LCD1602显示计算器,通过对STC89C51单片机的编程控制液晶屏LCD1602的显示。
显示计算和简易计算的信息同在LCD1602.3.2硬件设计本系统以STC89C51单片机为核心,本系统选用12MHZ的晶振,使单片机有合理的运行速度。
起振电容30pf对振荡器的频率高低,振荡器的稳定性和起振的快速性影响较合适,复位电路为按键高电平复位。
3.2.1复位电路为确保微机系统中电路稳定可靠工作,复位电路是必不可少的一部分,复位电路的基本功能是:系统上电时提供复位信号,直至系统电源稳定后,撤销复位信号。
为可靠起见,电源稳定后还要经一定的延迟才撤销复位,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。
当单片机的复位引脚出现2个机器周期以上的高电平时,单片机就执行复位操作。
如果RST持续为高电平,单片机就处于循环复位状态。
所以复位引脚的电容大一点没多大关系,顶多是复位时间长一点;但如果电容太小,高电平持续时间太短,则单片机无法正常复位,就不能工作,电容通常取10UF或22UF,铝电解电容即可。
单片机的复位电路在刚接通电时,刚开始电容是没有电的,电容内的电阻很低,通电后,5V的电源通过电阻给电解电容进行充电,电容两端的电会由0V慢慢的升到4V左右(此时间很短一般小于0.3秒),正因为这样,复位脚由低电位升到高电位,引起了内部电路的复位工作;当按下复位键时,电容两端放电,电容又回到0V了,于是又进行了一次复位工作。
电路图如图5.1。
图5.1 复位电路3.2.2 液晶屏LCD1602显示电路3.2.3 4*4键盘的设计其功能如下3.2.5 多功能计算器的总电路 (14)3.3软件设计程序如下:#include<reg51.h>#define lcd1602_DATAPINS P0#define uint unsigned int#define uchar unsigned charsbit lcd1602_E=P2^7;sbit lcd1602_RS=P2^6;sbit lcd1602_RW=P2^5;uchar code digit[]={"0123456789+-x/=."};uchar code key_code[]={0xd7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb,0x7e,0x7d,0x7b,0x77,0xb7, 0xe7 };uchar code str[]=" Input Data: ";uchar key;void delay1ms(uchar c) //误差0us{uchar a,b;for (; c>0; c--){for (b=199;b>0;b--){for(a=1;a>0;a--);}}}void lcdwritecom(uchar com ){lcd1602_E=0;lcd1602_RS=0;lcd1602_RW=0;lcd1602_DATAPINS=com;delay1ms(1);lcd1602_E=1;delay1ms(5);lcd1602_E=0;}void lcdwritedata(unsigned char dat){lcd1602_E=0;lcd1602_RS=1;lcd1602_RW=0;lcd1602_DATAPINS=dat;delay1ms(1);lcd1602_E=1;delay1ms(5);lcd1602_E=0;}void init(){lcdwritecom(0x38);lcdwritecom(0x0c);lcdwritecom(0x06);lcdwritecom(0x01);lcdwritecom(0x80);}void key_scan(){uchar scan1,scan2,keycode,i;P1=0xf0;scan1=P1;if((scan1&0xf0)!=0xf0){ //判断是否按键delay1ms(15); //延时消陡scan1=P1;if((P1&0xf0)!=0xf0){P1=0x0f;scan2=P1;keycode=scan1|scan2;}for(i=0;i<16;i++){if(keycode==key_code[i]){ //查表得键值key=i;}}}else{P1=0xff; //P1口写1,输入状态}}void main(){uchar i;uchar x,y,sign=0;uchar flag;int a,b;P1=0xff; //写1,读状态delay1ms(15);init();lcdwritecom(0x80);for(i=0;i<16;i++){lcdwritedata(str[i]);delay1ms(10);}lcdwritecom(0xc0);delay1ms(5);//lcdwritedata('0');while(1){P1=0xf0;if((P1&0xf0)!=0xf0){delay1ms(15);if((P1&0xf0)!=0xf0){key_scan();if(key<=9){if(sign==0){lcdwritedata(digit[key]);if(x==0)a=key;if(x==1)a=a*10+key;if(x==2)a=a*10+key;x++;}else{lcdwritedata(digit[key]);if(y==0)b=key;if(y==1)b=b*10+key;if(y==2)b=b*10+key;y++;}delay1ms(200);}if(key==15){lcdwritedata(digit[key]);delay1ms(200);}if((key==10)||(key==11)||(key==12)||(key==13)||(key==14)) {if(key==10){sign++;flag=1;lcdwritedata(digit[key]);delay1ms(200);}else if(key==11){sign++;flag=2;lcdwritedata(digit[key]);delay1ms(200);}else if(key==12){sign++;flag=3;lcdwritedata(digit[key]);delay1ms(200);}else if(key==13){sign++;flag=4;lcdwritedata(digit[key]);delay1ms(200);}else if(key==14){sign=0;lcdwritedata(digit[key]);delay1ms(200);switch(flag){case 1:a=a+b;break;case 2:a=a-b;break;case 3:a=a*b;break;case 4:a=a/b;break;}if(a>0&&a<10){lcdwritedata(digit[a%10]);}if(a>9&&a<100){lcdwritedata(digit[a/10]);lcdwritedata(digit[a%10]);}if(a>99&&a<1000){lcdwritedata(digit[a/100]);lcdwritedata(digit[a/10%10]);lcdwritedata(digit[a%10]);}if(a>999&&a<10000){lcdwritedata(digit[a/1000]);lcdwritedata(digit[a%1000/100]);lcdwritedata(digit[a%1000/10%10]);lcdwritedata(digit[a%10]);}}}}}}}3.4软件仿真在硬件设计完成后,利用软件进行仿真,以尽可能减少做板子的次数,这次我采用了protues软件进行仿真如图多功能计算器的的显示3.5硬件调试 (16)4 结束语在用单片机实现多功能计算的设计中使用了STC89C51,LCD1602及其4*4键盘的使用,在设计过程中我通过在网上和图书馆查阅资料,收集了相关的单片机和液晶屏LCD1602显示方面的资料,通过这些资料的学习,我了解了单片机的基本结构和单片机在生活和生产中发挥的作用:液晶屏的原理和使用。