能做计算器的单片机

单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活的各个领域,电子、科技、通信、汽车、工业等。本次设计是设计一个简易计算器,能够进行多位的加减乘除运算。它主要由51单片机的数码管,键盘等模块组成。本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程,实现计算器的设计。

把期中做的作业放上来哈哈

硬件电路描述

要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。 对于键盘的扫描,这里采用行列扫描的方法来完成对键盘的扫描。原理就是先确定按键在哪一行,接着再确定是哪一列,这样就可以知道是哪个按键被按下了。我是将P3口作为按键扫描口的,比如,先使行线输出全“0”,读列线,再使列线输出全为“0”,读行线。两次结果再相与,则得到一个值为键值。同理,每个按键都会有一个对应的十六进制值,把它们列出来进行一一对应就行了。如下图。

程序设计描述

1.程序总流程图

2.编程思路
在单片机接通电源后,单片机就会一直重复检测键盘上的按钮是否被按下。如果有键被按下,就会进入选择判断,当按下数字键,相应数字计入变量keynum中并在数码管上移位显示;当按下运算符键和特殊功能键,也将对应的10到15数字计入到keynum中并进行第二次判断,如果keynum是0~9,则将数据变量dat×10加上keynum;如果是10(加号对应值),进入加法程序(加法标识变量加1,其他运算符标识变量归零,把dat赋值给另一变量datA;当法标识变量大于1时,就是连加,需要将dat等于dat加上datA的值)。其他运算符也是差不多的程序。keynum等于14,就进入等于运算程序。这个程序中也就是四个if语句,如果运算符变量为1就运行相应代码。如加法运算符为1,则使dat加上datA的值赋给dat。最后将dat放入显示程序中显示,而无论何时按下keynum等于15时,所有状态清零。这就是我写的代码的主要思路。

源代码及注释

#include <reg51.h>
#define long unsigned long
#define KEYPORT P3
sbit beep=P1^4;
bit dot;
typedef unsigned char byte;long dat;       //数据
long datA;      //过度数据
byte addflag;   //加法标志位
byte subflag;   //减法标志位
byte mulflag;   //乘法标志位
byte divflag;   //除法标志位
byte clrflag;   //数据处理标志位
byte scanok;
int checkok;
int keynum;    //按键键值
static byte dispbuf[6];
//数码管字段表
sbit duan=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//变量定义void delayms(int ms)//这个软件大约可以等待ms毫秒
{int i,k;for(k=0; k<ms;k++)   {   for(i=0;i<50;i++);  }
}/*---------------------------------------------------------------
查询是否有键按下,有键按下返回键值,无键按下则返回0xff
---------------------------------------------------------------*/
byte keysearch(void)
{byte k;KEYPORT=0xf0;k=KEYPORT;KEYPORT=0x0f;k=KEYPORT|k;scanok=1;return k;
}
void HEX_TO_BCD(int num)
{   dispbuf[5]  = num%1000000/100000;dispbuf[4]  = num%100000/10000;dispbuf[3]  = num%10000/1000;dispbuf[2]  = num%1000/100;dispbuf[1]  = num%100/10;dispbuf[0]  = num%10;
}
/*---------------------------------------------------------------
显示子程序
轮流导通各位数码管,再送出字段码
延时显示一段时间后再继续导通下一位
---------------------------------------------------------------*/
void scandisp(void)
{byte posi=0x1f,i,temp;//posi,为position的缩写,指显示哪一个8字for(i=0;i<6;i++){temp= dispbuf[i];         //显示缓存区数据查表temp= table[temp];if(i==2&&dot)temp|=0x80;  //i是小数点位置,变量dot=1,点亮小数点P0 = 0;      duan=1;   duan=0;//先关闭数码管,再切换P0 = posi;   wela=1;   wela=0;    P0 = temp;   duan=1;   duan=0;delayms(5);//延时 posi>>=1;  posi|=0x20;    //循环右移}
}/*---------------------------------------------------------------
移位显示子程序
把显示数组中的最低3位赋给高3位,使最新输入的键盘值赋给数组的最低位
输入:键值
返回:无
---------------------------------------------------------------*/
void digitin(byte val)
{ dispbuf [3]= dispbuf [2];dispbuf [2]= dispbuf [1];dispbuf [1]= dispbuf [0];dispbuf [0]= val;
}/*---------------------------------------------------------------
扫描得到的键值和实际需要的键盘任务的转换函数
也叫键盘码散转程序
输入:键值,有0x00~0xff钟可能性,根据显示的键值可以修改此函数
返回:无
---------------------------------------------------------------*/
void keybranch(byte k)
{   if(scanok){scanok=0;switch(k){case 0x00:break;case 0xee:keynum=1;break;case 0xde:keynum=2;break;case 0xbe:keynum=3;break;case 0xed:keynum=4;break;case 0xdd:keynum=5;break;case 0xbd:keynum=6;break;case 0xeb:keynum=7;break;case 0xdb:keynum=8;break;case 0xbb:keynum=9;break;case 0xd7:keynum=0;break;case 0x7e:keynum=10;break;//加法case 0x7d:keynum=11;break;//减法case 0x7b:keynum=12;break;//乘法case 0x77:keynum=13;break;//除法case 0xb7:keynum=14;break;//等于case 0xe7:keynum=15;break;//清零default:break;} checkok=1;
} }
/*---------------------------------------------------------------
处理程序,键值为15时或者清除标志为1时,数据清零
---------------------------------------------------------------*/
void datchuli(void)
{if(keynum==15){dat=0;  datA=0;HEX_TO_BCD(dat);}
else if(clrflag)                    //清除标志为1,则执行以下。{        dat=0;clrflag=0;                 //为下次使用准备。HEX_TO_BCD(dat);}if(keynum<10){digitin(keynum);dat=dat*10+keynum;}
}void add(void)
{addflag++;                          //加法标志置1。。。subflag=mulflag=divflag=0;          //将其它运算标志清零。。(一次只能作一种运算)clrflag=1;                          //清零标标置1,(当按下加号后,再按第二个加数时,这时应该显示第二加数。。所以要清掉第一个加数。)if(addflag>1){dat=datA+dat;datA=dat;}datA=dat;
}
void sub(void)                         //减法
{ subflag++;addflag=mulflag=divflag=0;clrflag=1;if(subflag>1){dat=datA-dat;datA=dat;}datA=dat;
}
void mul(void)                          //chengfa
{ mulflag++;addflag=subflag=divflag=0;clrflag=1;if(mulflag>1){dat=dat*datA;datA=dat;}datA=dat;
}
void div(void)                          //chufa
{ divflag++;addflag=subflag=mulflag=0;clrflag=1;if(divflag>1){dat=datA/dat;datA=dat;}datA=dat;
}
void equ(void)
{if(addflag)                           //如果些时做加法运算。。{dat=dat+datA;                     //计算各存入dat(显示程序会将dat显示的。。)}if(subflag){dat=datA-dat;}if(mulflag){dat=datA*dat;}if(divflag){dat=datA/dat;}addflag=subflag=mulflag=divflag=0;//运算一次完成后将所有运标志清零。为下次运算作准备。。HEX_TO_BCD(dat); clrflag=1;
}
void calculate_handle(void)//计算函数。。
{   if(checkok)//如果检测键值完。则执行以下。{checkok=0;//检测完标志清零..switch (keynum)//如果是+,-,*,/,=则进入相应的函数。。{case 10 : {add();HEX_TO_BCD(dat);} break;    //如果是按了"+",则进入加法函数。case 11 : {sub();HEX_TO_BCD(dat);} break;    //如果是按了"-",则进入减法函数。case 12 : {mul();HEX_TO_BCD(dat);} break;    //如果是按了"*",则进入乘法函数。case 13 : {div();HEX_TO_BCD(dat);} break;    //如果是按了"/",则进入除法函数。case 14 : equ(); break;    //如果是按了"=",则进入等于函数。default : datchuli();       //如果不是,计算符(即为数字),则进入数据处理函数。}}}
/*---------------------------------------------------------------
主函数:将4X4键盘的键值显示在数码管上
---------------------------------------------------------------*/
void main(void)
{byte k;while(1){k=keysearch();if(k!=0xff)   {delayms(10);//有键按下k=keysearch();keybranch(k);do{k=keysearch();scandisp();} while(k!=0xff);      //等待键释放}calculate_handle();scandisp();}
}

设计体会

一开始只是会矩阵键盘和LCD扫描显示,所以当时是想做一个计算器应该还是挺容易的,但直到真正开始做的时候,才发现并不简单。一开始,想的就是,把运算键前输入的数值存到一个变量,后面的数值存到另一个变量内,然后再运算。但问题就来了,如何让单片机知道两次输入的数值要存到不同的变量去?如何把这些变量分别显示到显示管上?然后就要引入更多的变量、设计更多的函数。做出来的第一个版本,能实现加减乘除了,但还有一些问题。按下运算符时,数码管就会直接清零,不像真正计算器那样,按下运算符数码管上数值先不变,等下一数值输入时才变。还有不能实现连续运算的问题,最后还是修改好了。总的来说,这次设计的过程是很有挑战的,尤其对于我这种不善于编程的人来讲,遇到的问题,虽说比较麻烦,但还是车到山前必有路

基于51单片机的计算器设计相关推荐

  1. 用计算机设计电路图,基于51单片机的计算器设计(含电路图,程序)

    基于51单片机的计算器设计(含电路图,程序)(课题申报表,任务书,开题报告,中期检查表,外文翻译,论文11200字,程序,答辩PPT) 摘 要 计算器一般是指"电子计算器",能进行 ...

  2. 51单片机计算机设计报告,基于51单片机的计算器设计与制作.docx

    摘要:科技日新月异,发展迅猛,其中电子计算机是运用现代电子技术记录.运算.加工数字信息并以数字.图像或其他形式给出结果的运算工具,由于其运算效率高,所以能代替人完成大规模的计算工作,已成为现代化事业所 ...

  3. 51单片机c语言编写计算器仿真,基于51单片机的计算器设计c程序代码加proteus仿真...

    可实现加减乘除各类运算,带有清零复位功能 仿真原理图如下(proteus仿真工程文件可到本帖附件中下载) 0.png (24.71 KB, 下载次数: 9) 2019-1-10 04:05 上传 程序 ...

  4. 基于51单片机信号发生器仿真设计

    本设计 基于51单片机信号发生器仿真设计 (仿真+程序源码+设计说明书) 仿真原版本:proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0015 目录标题 ...

  5. 基于51单片机数字电压表的设计 仿真、程序、原理图(转发)

    摘 要 数字电压表简称DVM,数字电压表基本原理是将输入的模拟电压信号转化为数字信号,再进行输出显示.而A/D转换器的作用是将连续变化的模拟信号量转化为离散的数字信号,器基本结构是由采样保持,量化,编 ...

  6. stc89c51单片机音乐盒系统设计_基于51单片机音乐盒课程设计1.doc

    基于51单片机音乐盒课程设计1 课程名称: 微机原理课程设计 题 目: 基于单片机的音乐盒设计 摘要 随着人类社会的发展,人们对视觉.听觉方面的享受提出了越来越高的要求.小小的音乐盒可以给人们带来美好 ...

  7. 基于51单片机自行车码表设计

    [毕设课设]基于51单片机自行车码表设计 ​效果图 Proteus仿真: 功能简介: 文件内容: 程序框架: 网盘链接: ​效果图 更多内容请关注@WENJIE电子科技 ​ 基于51单片机proteu ...

  8. c语言 计步算法,基于51单片机的计步器设计

    基于51单片机的计步器设计(任务书,开题报告,外文翻译,论文15000字) 摘  要 随着科技发展和国民健康意识的提高,许多检测健康状态的电子产品开始普及.电子计步器作为一种越来越流行的平民锻炼检测装 ...

  9. 基于51单片机的温度报警器设计

    目 录 前言.............................................................................................. ...

最新文章

  1. 一步一步学Silverlight 2系列(32):图形图像综合实例—“功夫之王”剧照播放_转载...
  2. TPO 按主题刷题记录
  3. Debug Tensorflow: yolo模型检测框位置正确但类别不正确
  4. js实现php中sleep()延时的功能
  5. OAuth2.0授权流程分析
  6. android o 结构光流程,惊艳亮相!一分钟看懂OPPO Find X 3D结构光技术是什么鬼,太牛了...
  7. 将python算法转为scala_将Python转换为scalaasp
  8. Spring Cloud学习总结(1)——Spring Cloud及微服务入门
  9. 反编译代码遇到的问题
  10. (日常搬砖)windows下如何查看并导出文件夹目录
  11. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)...
  12. oracle的时间取的到底是谁的时间
  13. 【2019杭电多校第五场1006=HDU6629】string matching(求后缀字符串和本串的最长公共前缀长度之和--扩展kmp)
  14. java获取动态输入_java-如何在Spring中以bean形式接收动态生成的输入值
  15. 网页设计的常用字体规范
  16. AWVS 10.5 配置选项
  17. 计算机打字键盘亮怎么设置,键盘指示灯亮着却不能打字的解决方法
  18. 饮料自动售货机模拟(小项目)
  19. iOS-xcode模拟器录屏
  20. 夺冠!小米在 IWSLT 2022国际机器同传比赛中获佳绩

热门文章

  1. java如何还原被转义的HTML特殊字符
  2. 阿里升级消费运营和服务企业能力:蒋凡兼任天猫总裁
  3. 基于AList实现网盘挂载和WebDAV本地挂载网盘
  4. 如何监听HH660型号扫码枪并输出中文
  5. 2022-2027年中国特浓咖啡粉囊市场规模现状及投资规划建议报告
  6. python调用msfconsole全自动永恒之蓝攻击_永恒之蓝漏洞攻击完整步骤
  7. Vscode快速入门、 插件安装、插件位置、修改vscode默认引用插件的路径、在命令行总配置code、快捷键
  8. cnvd批量提交以及漏洞盒子
  9. html标按钮往左移,按右箭头按钮,往左移
  10. DIY 老毛桃PE+360急救盘+CDlinux