基于51单片机的简易计算器
1.简介
本计算器是以MCS-51系列AT89C51单片机为核心构成的简易计算器系统。该系统通过单片机控制,实现对4*4键盘扫描进行实时的按键检测,并由LCD1602显示屏将过程与结果显示出来。
2.硬件原理图
硬件主要由四部分组成
- 单片机最小系统
- 4*4矩阵键盘
- LCD1602显示屏
- 系统电源
3.程序设计
(1)矩阵键盘驱动程序
/*------------------------------------------------矩阵键盘按键值| 1 | 2 | 3 | + | | 4 | 5 | 6 | - | | 7 | 8 | 9 | * | | 0 | . | = | / | #define KeyPort P1/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法
{unsigned char cord_h,cord_l;//行列值中间变量KeyPort=0x0f; //行线输出全为0cord_h=KeyPort&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{DelayMs(10); //去抖if((KeyPort&0x0f)!=0x0f){cord_h=KeyPort&0x0f; //读入列线值KeyPort=cord_h|0xf0; //输出当前列线值cord_l=KeyPort&0xf0; //读入行线值while((KeyPort&0xf0)!=0xf0);//等待松开并输出return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值
}
/*------------------------------------------------按键值处理函数,返回扫键值可以根据需要改变返回值
------------------------------------------------*/
unsigned char KeyPro(void)
{switch(KeyScan()){case 0x7e:return '1';break;//0 按下相应的键显示相对应的码值case 0x7d:return '2';break;//1case 0x7b:return '3';break;//2case 0x77:return '+';break;//3case 0xbe:return '4';break;//4case 0xbd:return '5';break;//5case 0xbb:return '6';break;//6case 0xb7:return '-';break;//7case 0xde:return '7';break;//8case 0xdd:return '8';break;//9case 0xdb:return '9';break;//acase 0xd7:return 'x';break;//bcase 0xee:return '0';break;//ccase 0xed:return '.';break;//dcase 0xeb:return '=';break;//ecase 0xe7:return '/';break;//fdefault:return 0xff;break;}
}
(2)LCD1602驱动程序
#define CHECK_BUSYsbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;#define RS_CLR RS=0
#define RS_SET RS=1#define RW_CLR RW=0
#define RW_SET RW=1 #define EN_CLR EN=0
#define EN_SET EN=1#define DataPort P0/*------------------------------------------------判忙函数
------------------------------------------------*/bit LCD_Check_Busy(void) {
#ifdef CHECK_BUSYDataPort= 0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET;return (bit)(DataPort & 0x80);
#elsereturn 0;
#endif}
/*------------------------------------------------写入命令函数
------------------------------------------------*/void LCD_Write_Com(unsigned char com) { while(LCD_Check_Busy()); //忙则等待RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR;}
/*------------------------------------------------写入数据函数
------------------------------------------------*/void LCD_Write_Data(unsigned char Data) { while(LCD_Check_Busy()); //忙则等待RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_();EN_CLR;}/*------------------------------------------------清屏函数
------------------------------------------------*/void LCD_Clear(void) { LCD_Write_Com(0x01); DelayMs(5);}
/*------------------------------------------------写入字符串函数
------------------------------------------------*/void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) { while (*s) { LCD_Write_Char(x,y,*s); s ++; x++; }}
/*------------------------------------------------写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0) { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } LCD_Write_Data( Data); }
/*------------------------------------------------初始化函数
------------------------------------------------*/
void LCD_Init(void)
{LCD_Write_Com(0x38); /*显示模式设置*/ DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); /*显示关闭*/ LCD_Write_Com(0x01); /*显示清屏*/ LCD_Write_Com(0x06); /*显示光标移动设置*/ DelayMs(5); LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
(3)主函数
/*------------------------------------------------主程序
------------------------------------------------*/
main()
{unsigned char num,i,sign; unsigned char temp[16]; //最大输入16个bit firstflag;float a=0,b=0;unsigned char s;LCD_Init(); //初始化液晶屏DelayMs(10); //延时用于稳定,可以去掉LCD_Clear();LCD_Write_String(0,0," LCD calculator"); //写入第一行信息,主循环中不再更改此信息,所以在while之前写入LCD_Write_String(0,1," Fun: + - x / "); //写入第二行信息,提示输入密码while (1) //主循环{num=KeyPro(); //扫描键盘if(num!=0xff) //如果扫描是按键有效值则进行处理{ if(i==0) //输入是第一个字符的时候需要把改行清空,方便观看LCD_Clear();if(('+'==num)|| (i==16) || ('-'==num) || ('x'==num)|| ('/'==num) || ('='==num))//输入数字最大值16,输入符号表示输入结束{i=0; //计数器复位if(firstflag==0) //如果是输入的第一个数据,赋值给a,并把标志位置1,到下一个数据输入时可以跳转赋值给b{sscanf(temp,"%f",&a);firstflag=1;}else sscanf(temp,"%f",&b);for(s=0;s<16;s++) //赋值完成后把缓冲区清零,防止下次输入影响结果temp[s]=0;LCD_Write_Char(0,1,num); ///if(num!='=') //判断当前符号位并做相应处理sign=num; //如果不是等号记下标志位else{ firstflag=0; //检测到输入=号,判断上次读入的符合switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case 'x':a=a*b;break;case '/':a=a/b;break;default:break;}sprintf(temp,"%g",a); //输出浮点型,无用的0不输出LCD_Write_String(1,1,temp);//显示到液晶屏sign=0;a=b=0; //用完后所有数据清零for(s=0;s<16;s++)temp[s]=0;}}else if(i<16){if((1==i)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符{if(num=='.') //如果是小数点则正常输入,光标位置加1{temp[1]='.';LCD_Write_Char(1,0,num);//输出数据i++;} //这里没有判断连续按小数点,如0.0.0 else{temp[0]=num; //如果是1-9数字,说明0没有用,则直接替换第一位0LCD_Write_Char(0,0,num);//输出数据}}else{temp[i]=num; LCD_Write_Char(i,0,num);//输出数据i++; //输入数值累加}}} }
}
源码+AD电路图 下载:关注公众号,首页回复“计算器”获取资料
基于51单片机的简易计算器相关推荐
- c语言51单片机计算器,新基于51单片机的简易计算器
<新基于51单片机的简易计算器>由会员分享,可在线阅读,更多相关<新基于51单片机的简易计算器(24页珍藏版)>请在人人文库网上搜索. 1.基于51单片机的简易计算器1.前言: ...
- 基于51单片机的简易计算器的实现
目录 一.硬件简介 1.LCD1602液晶显示器介绍 (1)LCD1602的组成 (2)各引脚功能介绍 (3)DDRAM 2.矩阵按键介绍 (1)矩阵按键的优点: (2)原理: (3)检测方法: (4 ...
- 51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告)
本设计: 基于51单片机的简易计算器设计(仿真+程序+原理图+PCB+设计报告) 仿真:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号S0001 芯片可以替换为 ...
- 基于51单片机的简易电子计算器——有温度显示和万年历等额外功能
基于51单片机的简易电子计算器--有温度显示和万年历等额外功能 设计实际所实现的功能 模式一可显示日期.时钟.温度,模式二可进行计算器的计算,且显示日期温度模式和计算器模式可随意切换,模式三可以滚动显 ...
- 【006】基于51单片机的简易电子计算器Proteus仿真设计
一.压缩包资料内容(私信获取) (1).基于51单片机的简易电子计算器proteus仿真设计一份: (2).基于51单片机的简易电子计算器proteus仿真设计keli源代码一份: (3).基于51单 ...
- 基于51单片机的简易游戏机
基于51单片机的简易游戏机 目录 基于51单片机的简易游戏机 一.绪论 二.设计方案 三.系统原理框图及模块的作用 四.硬件设计及说明 五.实际的程序流程图,写清楚程序模块的功能 六.系统使用说明 七 ...
- 【Proteus仿真】51单片机制作简易计算器+ LCD1602显示
[Proteus仿真]51单片机制作简易计算器+ LCD1602显示 Proteus仿真效果演示 程序代码 #include<reg51.h> //头文件 #define uint uns ...
- 【C51】基于51单片机的简易频率计(附代码、无需外设、小白简单易上手)
基于51单片机的简易频率计(无需外设.小白简单易上手) 代码较为简单,大概思路是通过定时器单位时间内外部中断上升沿触发的次数来计算实际频率. /基于51单片机的简易频率计#include<r ...
- 基于51单片机的简易mp3的制作
基于51单片机的简易mp3制作原理 1. 项目要求 基于AT89C51系列单片机的音乐播放器,采用AT89C51作为主控芯片,采用12864LCD作为液晶显示屏,通过按键实现播放器对应按键功能. 2 ...
- 基于51单片机的简易抢答器设计
基于51单片机的简易抢答器 具体功能: 1.主持人按下抢答开始按键,抢答者才可以开始抢答,数码管抢答倒计时20S. 2.抢答者按下按键,数码管显示抢答者的编号. 3.可以通过按键修改倒计时时间. 部分 ...
最新文章
- Linux_指令杂烩
- python语法基础知识-python_基础知识_安装和基础语法
- 详细地图_一目了然:蒙城学区划分详细地图
- 详解 Solidity 事件Event
- zabbix数据库分表的实现
- python入门教程pdf-python基础教程第4版pdf
- JZOJ5371 组合数问题
- 时间序列数据建模分析利器sktime初体验
- pass平台java,mPass 微服务开发平台
- WdatePicker开始时间与结束时间
- 前端知识:使用layui模板搭建页面,简单快捷
- 总资产周转率、资产负债率、销售净利率、资产收益率、净资产利润率、劳动生产率、人均利润率
- 缺陷检测论文回顾(一)
- 不可不学的摄影技巧.1—构图
- Xiaocao's first blog post
- 云脉档案管理系统助力档案信息化建设
- 该战斗的时候战斗,该转身的时候转身,但请保持优雅
- 记一次网页打印小票、收据
- Java实现一个学生成绩管理系统,要求存储学生信息并进行增删改查操作。
- 羞羞的和成人机器人恋爱,或许这是“寂寞经济”催生的新风口