51单片机——计算器编写的一种办法(C语言版)
计算器功能包括:
1、支持8位数内(0~99999999)的包括加、减、乘、除的非负整数运算。
2、软件清零功能。
3、通过串口通信输入功能。
4、八位共阴极数码管显示。
注:
不具有断电后储存的功能,参与计算的数字一旦超出规定,如果是运算数按前8位记录。
在程序实现上核心有两个模块:显示和键扫。
程序实现:
显示:
通过取模获得每位数,然后通过查库(数列)获得对应的段码和位码,再依次扫描显示到数码管上。显示程序如下:
#include <Delay.h>//调用延时函数
#define DataPort P1//定义数码管数据来源端口sfr P1=0x90;
sfr P2=0xA0;
//定义P1和P2口
sbit LATCH1=P2^1;//定义段锁存
sbit LATCH2=P2^2;//定义位锁存void Display(unsigned long int Number)
{unsigned int segment_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsigned int bit_code[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//设置段码和位码unsigned int x[8];//将数字分离出来的每一位unsigned int i,j;for(i=0;Number>=1;i++){x[i]=Number%10;Number=(Number-x[i])/10;}j=i;for(i=0;i<j;i++){DataPort=bit_code[i];LATCH2=1;LATCH2=0;DataPort=segment_code[x[i]];LATCH1=1;LATCH1=0;DelayMs(1);}
}
因为数码管是动态扫描的,肉眼会捕捉到数码管变化,类似动漫的原理,加上1ms左右延时即可在8位内“静态显示”。
延时函数如下(tms的延时效果):
void DelayUs2x(unsigned char t)
{while(--t);
}void DelayMs(unsigned char t)
{while(t--){DelayUs2x(245);DelayUs2x(245);}
}
调试样例如下:
void Display(unsigned long int Number);main()
{Display(99999999);
}
调试结果如下:
键扫:
本方法采用行列扫描的方法,键盘定义如下:
键扫代码如下:
#define KeyPort P0//定义键盘端口void Delay(unsigned int xms);//声明延时函数sfr P0=0x80;//定义P0端口sbit h_1=P0^0;
sbit h_2=P0^1;
sbit h_3=P0^2;
sbit h_4=P0^3;
sbit l_1=P0^4;
sbit l_2=P0^5;
sbit l_3=P0^6;
sbit l_4=P0^7;
//定义行列unsigned char KeyScan()
{unsigned char KeyCode=0;KeyPort=0xff;l_4=0;if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=1;}if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=2;}if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=3;}if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=4;}KeyPort=0xff;l_3=0;if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=5;}if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=6;}if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=7;}if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=8;}KeyPort=0xff;l_2=0;if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=9;}if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=10;}if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=11;}if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=12;}KeyPort=0xff;l_1=0;if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=13;}if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=14;}if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=15;}if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=16;}return KeyCode;//返回码用于查表
}void Delay(unsigned int xms)
{unsigned char i,j;while(xms--){i=2;j=239;do{while(--j);}while(--i);}
}
再通过查表的方法避免返回0的情况,代码如下:
unsigned char KeyTab(unsigned char Char)
{switch (Char){case 1:return 7;break;case 2:return 4;break;case 3:return 1;break;case 4:return 0;break;case 5:return 8;break;case 6:return 5;break;case 7:return 2;break;case 8:return '~';break;case 9:return 9;break;case 10:return 6;break;case 11:return 3;break;case 12:return '=';break;case 13:return '+';break;case 14:return '-';break;case 15:return '*';break;case 16:return '/';break;}
}
计算程序如下:
unsigned long int Regulation(unsigned long int x,unsigned long int y,char m)
{unsigned long int z;switch(m){case '+':z=x+y;break;case '-':z=x-y;break;case '*':z=x*y;break;case '/':z=x/y;break;}return z;
}
综上结合后主函数:
#include <Function.h>sfr P2=0xA0;sbit Switch=P2^0;//另外定义的整个清零开关main()
{unsigned char X,Y,M,p;unsigned long int A=0,B=0,Num;while(1){if(!Switch){p=0;A=0;B=0;Num=0;}X=KeyScan();if(X){if(X>0&&X<12&&X!=8){if(p==0){Y=KeyTab(X);A=A*10+Y;Num=A;}else{Y=KeyTab(X);B=B*10+Y;Num=B;}}else if(X==12){if(p==0){Num=A;}else{Num=Regulation(A,B,M);}}else if(X==8){if(p==0){A=(A-Y)/10;Num=A;}else{B=(B-Y)/10;Num=B;}}else{M=KeyTab(X);p++;}}Display(Num);}
}
Function头文件:
#ifndef _FUNCTION_H_
#define _FUNCTION_H_void Display(unsigned long int Number);unsigned char KeyScan();unsigned char KeyTab(unsigned char Char);unsigned long int Regulation(unsigned long int x,unsigned long int y,char m);#endif
其中因为数组位数问题Display函数定义如下:
#define DataPort P1sfr P1=0x90;
sfr P2=0xA0;sbit LATCH1=P2^1;
sbit LATCH2=P2^2;void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);void Display(unsigned long int Number)
{unsigned int segment_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsigned int bit_code[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};unsigned int x[9];unsigned int i,j;for(i=1;Number>=1;i++){x[i]=Number%10;Number=(Number-x[i])/10;}j=i;for(i=0;i<j;i++){if(i==0){DataPort=0x7f;LATCH2=1;LATCH2=0;DataPort=0x00;LATCH1=1;LATCH1=0;DataPort=0;LATCH1=1;LATCH1=0;DelayMs(1);}else{DataPort=bit_code[i-1];LATCH2=1;LATCH2=0;DataPort=segment_code[x[i]];LATCH1=1;LATCH1=0;DelayMs(1);}}
}void DelayUs2x(unsigned char t)
{while(--t);
}void DelayMs(unsigned char t)
{while(t--){DelayUs2x(245);DelayUs2x(245);}
}
51单片机——计算器编写的一种办法(C语言版)相关推荐
- 一本通c语言在线测评答案,51单片机典型项目实战全能一本通(C语言版)(视频版)最新章节_张毅刚著_掌阅小说网...
1.6 单片机系统的原理电路设计与虚拟仿真 前面介绍了Proteus ISIS软件平台的基本功能及使用.本节通过一个"流水灯制作"的案例,介绍Proteus下的单片机系统原理电路的 ...
- c语言T1中断程序编写步骤,用51单片机中断编写的4x4键盘程序
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章 用51单片机中断编写的4x4键盘程序 作者:未知 来源:山涧一溪流 点击数:- 更新时间:2014年06 ...
- 51单片机计算器(源程序+流程图+答辩报告+综合设计)
由于本文较早,这里推荐一下近期刚优化的:[优化]51单片机计算器(LCD1602液晶显示)_Gxtoeilee的博客-CSDN博客 1 设计目标 设计可选模式的计算器 2 主要功能 功能一:可选两种计 ...
- 秒表系统的设计c语言程序,51单片机秒表计时器课程设计报告(含C语言程序).doc...
51单片机秒表计时器课程设计报告(含C语言程序) XXXXXX学院 51单片机系统设计 课程设计报告 题 目: 秒表系统设计 专业.班级: 学生姓名: 学 号: 指导教师: 分 数 : [摘要]本设计 ...
- 单片机六位抢答器c语言程序,八路电子抢答器(基于51单片机的8路抢答器设计C语言程序)...
哥,你还有AT89C51单片机8路抢答器的资料吗 哥,你还有AT89C51单片机8路抢答器的资料吗 AT89C51单片机8路抢答器的资料 源程序如下 #include #define uchar un ...
- c语言键盘中断扫描码,用51单片机中断编写的4x4键盘程序
应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长(详见2013年9月29日博文<MSP430和AT89C51单片机4x4键盘C程序>),如果用中断编写,设置中断响应在下 ...
- 51单片机计算器_基于51单片机的倒计时温度检测报警器
基于51单片机的倒计时温度检测报警器 学习单片机断断续续半年了,在学长学姐的教学帮助下,完成了51单片机的入门学习,开始实践做项目,在一周时间内设计和制作出个人项目.起初,我设计和选择的是12864显 ...
- c语言51单片机计算器,新基于51单片机的简易计算器
<新基于51单片机的简易计算器>由会员分享,可在线阅读,更多相关<新基于51单片机的简易计算器(24页珍藏版)>请在人人文库网上搜索. 1.基于51单片机的简易计算器1.前言: ...
- 用c语言编写振铃检测程序,利用51单片机2进8出的程控交换机C语言源码
这个是利用51单片机加上超长的语音芯片合为一体的2进8出的程控交换机C语言源码 /************************** 6-23日 修改总台来显 ******************* ...
最新文章
- 使用STC8H1K的高级PWM的正交编码器计数方式
- 再向“乡镇青年”下沉,“资讯界拼多多”趣头条也难成为另一个拼多多
- sas infile和filename
- Python学习之==第三方模块的安装、模块导入
- 三星Nexus S刷回官方4.0.4教程
- 踩坑:VScode 集成 eslint 插件
- python psutil 进行系统管理 no.2
- 进军杀毒市场!百度杀毒软件2013正式发布
- ws2812b灯带容易坏_树莓派控制WS2812B灯带 - Python
- C# Emoji在Web端显示
- CTPN论文翻译——中英文对照
- 双纵坐标绘图-Plotyy
- https://www.52pojie.cn/thread-688820-1-1.html
- jenkins 使用过程问题解决方法
- MySQL存储布类型的值_mysql 字段存储类型
- 档案数字化中的OCR应用
- jQuery添加元素的方法
- 架构:多源异构数据。
- PortTunnel端口转发
- python错误Errors与异常Exceptions
热门文章
- 通俗理解卷积神经网络
- 如何利用积分系统提升社群活跃度与留存率?
- idea Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Progra
- 基于BCIduino脑电模组和OpenVibe的P300意念打字系统搭建
- 基于CNN实现视频动作分类任务
- IDEA运行工程时报错:java: java.lang.OutOfMemoryError: GC overhead limit exceeded
- 数字电路设计之Leon系列处理器结构
- 转:所谓美好,就是摆脱了功利之心
- bzoj2683:简单题(树状数组套CDQ分分治)
- 驱动给我带来的麻烦,我在OpenGpu上论坛发的两个求助帖(让我百思不得其解呀。),都是因为驱动的原因。。...