基于AT89C51单片机四位加法计算器的设计

news2025/2/22 20:34:47

1.设计任务

利用AT89C51单片机为核心控制元件,设计一个四位加法计算器,设计的系统实用性强、操作简单,实现了智能化、数字化。

1)、通过4*4矩阵键盘输入数字及运算符;

2)、可以进行4位十进制数以内的加法算。如果计算结果超出四位数,则全部显示“E ”LED灯亮起

3)、可以进行加所有运算;

4)、添加其他功能。

2. 设计要求

2.1系统方案论证

根据设计任务,分析设计系统的组成,给出实现设计任务的几种方案,分析比较几种设计方案的优略,本着尽量以软件代替硬件,同时力求电路简单,工作可靠的原则,确定总体设计方案。

2.2系统硬件电路设计

根据系统设计方案进行软、硬件的分配,软、硬件设计分别进行。硬件设计包括单片机最小系统和扩展接口及配置,硬件结构在设计时要选择合适的元器件,硬件电路要简洁、工作可靠,需用Proteus绘制整个系统的电路仿真原理图。

2.3软件设计

根据该系统要求的功能进行软件设计,简述软件的功能,并根据每个模块的功能绘制软件流程图,根据流程图编写程序并汇编调试通过;列出软件清单,软件清单要求加以注释。

2.4 软硬件系统仿真

将编译后的程序软件加载到Proteus软件仿真的单片机ROM中,运行系统,实现软件程序对单片机系统的硬件电路的控制,并调试仿真结果,直至与设计任务相符。

#include <reg51.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
 
sbit rw=P2^5;
sbit rs=P2^6;
sbit e=P2^7;
sbit led=P2^0;
sbit beep=P2^1;
unsigned char key,num,ei,eii,p;

 
unsigned char dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x2a-0x30,
									0,0x01-0x30,0x3d-0x30,0x2b-0x30 };//保存显示的数据
unsigned char dat2[]="9999 revo rewsna";
unsigned char dat3[]="Hi welcome into";
unsigned char dat4[]="counter by yumo";
void delay(unsigned int i);
void lcdwrc(unsigned char c);//写入命令	
void lcdwrd(unsigned char dat);//写入数据
void lcdinit();//LCD初始化
 show();
void keyscan();
void do_beep();
void do_led(int x);									
void main()
{
	led=0;
	lcdinit();
	show();//个性化界面
	while(1)
	{		
		keyscan();	
	}
}									
									
void delay(unsigned int i)
{
	while(i--);
}
void lcdwrc(unsigned char c)//写入命令
{
	delay(1000);
	rs=0;//选择发送命令
	rw=0;//选择写入
	e=0;//使能
	
	P0=c;//放入命令
	e=1;//写时序
	delay(1000);//保持时间
	e=0;
}
void lcdwrd(unsigned char dat)//写入数据
{
	delay(1000);
	rs=1;//选择输入数据
	rw=0;//选择写入
	e=0;
	
	P0=dat;//写入数据
	e=1;//写入时序
	delay(1000);
	e=0;
	rs=0;
}
 
void lcdinit()//LCD初始化
{
	delay(1500);
	lcdwrc(0x38);
	delay(500);
	lcdwrc(0x38);
	delay(500);
	lcdwrc(0x38);
	delay(500);
	lcdwrc(0x38);
	lcdwrc(0x08);
	lcdwrc(0x01);
	lcdwrc(0x06);
	lcdwrc(0x0c);
	key=0;
	num=0;
	flag=0;
	fuhao=0;
	a=0;
	b=0;
	c=0;
	d=0;
	
}
 
 show()
{
	for(eii=0;eii<15;eii++)
	{
		
		lcdwrd(dat3[eii]);
	}	
	lcdwrc(0xc0);//写命令函数使其到第二行第一个字符
	for(p=0;p<15;p++)
	{
		
		lcdwrd(dat4[p]);
	}	
	return 1;
}
void keyscan()
{
	P1=0xfe;   //令第一行为0,然后判断是哪一列按下
	if(P1!=0xfe)
	{
		delay(1000);
		if(P1!=0xfe)
		{
			key=P1&0xf0;
			switch(key)
			{
				case 0xe0: num=0;break;	  //1
				case 0xd0: num=1;break;	  //2
				case 0xb0: num=2;break;	  //3
				case 0x70: num=3;break;	  //加
			}
		}
		while(P1!=0xfe);
		if(num==0||num==1||num==2)	 //确认第一行的数1,2,3
		{
			if(flag==0)	 //没有按下符号键
			{

				a=a*10+dat1[num];
				do_led(a);
				
			}
			else
			{
				delay(1000);
				b=b*10+dat1[num];
				do_led(b);
			}		
		}
		if(num==3)
		{
			flag=1;
			fuhao=1;//加号+	运行
		}
		lcdwrd(0x30+dat1[num]);
	}
 
	P1=0xfd;				//令第二行为0,判断是哪一列按下
	if(P1!=0xfd)
	{
		delay(1000);
		if(P1!=0xfd)
		{
			key=P1&0xf0;
			switch(key)
			{
				case 0xe0: num=4;break;	  //4
				case 0xd0: num=5;break;	  //5
				case 0xb0: num=6;break;	  //6
				case 0x70: num=7;break;	  //违规
			}	
		}
		while(P1!=0xfd);
		if(num==4||num==5||num==6)
		{
			if(flag==0)	 //没有按下符号键
			{
				
				a=a*10+dat1[num];
			do_led(a);				
			}
			else
			{
				
				b=b*10+dat1[num];
				do_led(b);
			}			
		}
		if(num==7)
		{
		
			flag=1;
			do_beep();
		}
		lcdwrd(0x30+dat1[num]);
	}
 
	P1=0xfb;		 //令第三行为0,判断哪一列按下
	if(P1!=0xfb)
	{
		delay(1000);
		if(P1!=0xfb)
		{
			key=P1&0xf0;
			switch(key)
			{
				case 0xe0: num=8;break;	  //7
				case 0xd0: num=9;break;	  //8
				case 0xb0: num=10;break;  //9
				case 0x70: num=11;break;  //违规
			}	
		}
		while(P1!=0xfb);
		if(num==8||num==9||num==10)
		{
			if(flag==0)	 //没有按下符号键
			{
				
				a=a*10+dat1[num];
			do_led(a);				
			}
			else
			{	
				b=b*10+dat1[num];
				do_led(b);
			}			
		}
		else if(num==11)
		{
			flag=1;
			do_beep();
			
		}
		lcdwrd(0x30+dat1[num]);
	}
 
	P1=0xf7;		 //令第四行为0,判断哪一列按下
	if(P1!=0xf7)
	{
		delay(1000);
		if(P1!=0xf7)
		{
			key=P1&0xf0;
			switch(key)
			{
				case 0xe0: num=12;break;  //0
				case 0xd0: num=13;break;  //清除rst
				case 0xb0: num=14;break;  //等号=
				case 0x70: num=15;break;  //违规
			}	
		}
		while(P1!=0xf7);
		switch(num)
		{
			case 12: 
					if(flag==0)	 //没有按下符号键
					{			
						a=a*10+dat1[num];
						do_led(a);
						lcdwrd(0x30);	
					}
					else
					{
						b=b*10+dat1[num];
						do_led(b);
						lcdwrd(0x30);
					}
					break;			
			case 13: 
					lcdwrc(0x01);	//清屏指令			
					a=0;
					b=0;
			    c=0;
					flag=0;
					fuhao=0;
					break;
			case 15:
					flag=1;
					do_beep();
					break;					
			case 14: 					//如果是等于号
					if(fuhao==1)//加
					{
						lcdwrc(0x4f+0x80);
						lcdwrc(0x04);//设置光标左移,屏幕不移动
						c=a+b;
						
						if(c==0)
						{
							lcdwrc(0x4f+0x80);
							lcdwrc(0x04);
							lcdwrd(0x30);
						}
						while((c!=0)&&(c<=9999))	 //一位一位显示
						{
							
							lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
							c=c/10;//取前面的结果数据	
						}						
						if(c>9999)
						{
							for(ei=0;ei<=16;ei++)
							{
								lcdwrd(dat2[ei]);			
							}			
						}						
						lcdwrd(0x3d); //显示等于号=
						a=0;
						b=0;
						c=0;
						flag=0;
						fuhao=0;//全部清除为0
					}					
				
					break;
		}
	}
}
void do_beep()
{
	beep = 0;				//蜂鸣器报警
				delay(100000);
				beep = 1;
}
void do_led(int x)
{
	if(x>9999)
	{
	led=1;
	}
}

完整代码点开链接私信获取。

【iBot机器人工作室的个人空间-哔哩哔哩】 https://b23.tv/ryUWVKa

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1286147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线程池(Linux +C)

参考 手写线程池 - C语言版 | 爱编程的大丙 (subingwen.cn) 目录 1.为什么需要线程池&#xff1f; 1&#xff09;线程问题&#xff1a; 2&#xff09;如何解决线程问题&#xff08;线程池的优势&#xff09;&#xff1a; 2.线程池是什么&#xff1f; 1&#xff09;线程的…

某夕夕商家告诉你:这样寄快递居然这么省钱(便宜寄全国)

在当下很多时候寄快递成为了困扰很多人的问题&#xff0c;比如很多时候都会面临运费贵的问题&#xff0c;而且寄快递的效率也得不到保障&#xff0c;即使投诉快递员最终也是无济于事。其实在目前来看寄快递并没有这么难&#xff0c;闪侠惠递就能够有效的寄快递&#xff0c;而且…

试验数字化平台WDP 助力车企数据管理加速度

一 现状 随着现代测控技术的提高&#xff0c;数据结构变得越来越复杂多样&#xff0c;数据量也在日益增大。又因试验条件的限制&#xff0c;大多数企业的数据管理方式主要是通过各类电子文档将试验数据保存在每个工程师的移动电脑中&#xff0c;再进行汇总存储和共享。这种落后…

OpenHarmony 设备启动Logo和启动视频替换指南

前言 OpenHarmony源码版本&#xff1a;4.0release 开发板&#xff1a;DAYU / rk3568 一、Logo替换 替换其中的logo.bmp 和 logo_kernel.bmp文件 注意事项&#xff1a; 1、图片的分辨率需要和设备匹配 2、如果是非首次编译&#xff08;存在缓存&#xff09;需要将out目录删…

【Backbone】TransNeXt:最新ViT模型(原理+常用神经网络汇总)

文章目录 一、近几年神经网络 Backbone 回顾1.Densenet 与 Resnet2.CBP3.SENet4.GCNet5.DANet6.PANet 与 FPN7.ASPP8.SPP-net9.PSP-net10.ECA-Net 二、TransNeXt&#xff08;2023&#xff09;1.提出问题2.Aggregated Pixel-focused Attention2.1 Pixel-focused Attention&#…

如何一个月内发表一篇中文核心 干货分享

发论文经验教学 干货分享&#xff1a;如何在一个月内发表一篇中文核心 经验分享 干货分享_哔哩哔哩_bilibili

元宇宙红色展厅VR虚拟展馆提高受训者的参与感

生活在和平年代的新一代青少年&#xff0c;可能对革命先烈英勇事迹难以有很深的体会&#xff0c;无法切实感受到中国共产党无畏牺牲、誓死保家卫国的红色精神&#xff0c;因此借助VR虚拟现实制作技术&#xff0c;让参观者们走近革命先烈中&#xff0c;感受老一辈无产阶级革命家…

C语言-字符串变量

字符串变量 char* s “Hello, world!”&#xff1b; s是一个指针&#xff0c;初始化为指向一个字符串常量 由于这个常量所在的地方&#xff0c;所以实际上s是const char* s&#xff0c;但是由于历史的原因&#xff0c;编译器接受不带const的写法但是试图对s所指的字符串做写…

龙迅#LT8311X3 USB中继器应用描述!

1. 概述 LT8311X3是一款USB 2.0高速信号中继器&#xff0c;用于补偿ISI引起的高速信号衰减。通过外部下拉电阻器选择的编程补偿增益有助于提高 USB 2.0 高速信号质量并通过 CTS 测试。 2. 特点 • 兼容 USB 2.0、OTG 2.0 和 BC 1.2• 支持 HS、FS、LS 信令 • 自动检测和补偿 U…

【MATLAB源码-第95期】基于matlab的协作通信中(AF模式)中继选择算法对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 最大最小中继选择 (Max-Min Relay Selection)&#xff1a;这种算法选择能够提供最大最小信号强度的中继。它首先计算所有可用中继的信号强度&#xff0c;然后选择那些在最差信道条件下仍能保持最高信号强度的中继。其目的…

Vue3引入markdown编辑器--Bytemd

字节跳动开源了一款markdown编辑器&#xff0c;bytemd&#xff0c;项目地址&#xff1a;GitHub - bytedance/bytemd: ByteMD v1 repository 安装 npm i bytemd/vue-next 引入方式如下&#xff0c;再main.js中引入样式 import bytemd/dist/index.css 直接封装一个Markdown编…

1.vue学习笔记(vue简介+API风格+开发前的准备)

1.介绍 1.一款用于构建用户页面的JavaScript框架 2.基于HTML、CSS、JavaScript 3.官方文档&#xff1a;cn.vuejs.org2.渐进式框架 1.注重灵活性/可被逐步集成 根据需求场景&#xff1a;1.无需构建步骤&#xff0c;渐进式增强静态的HTML2.在任何页面中作为Web Components嵌入&…

生命在于折腾——Android Studio网络设置(MAC)

一、前言 在macos上面&#xff0c;能使用的android模拟器是真不如windows多&#xff0c;各个厂家似乎抛弃了macos的安卓模拟器&#xff0c;当然&#xff0c;我使用的mac是2019款16寸的inter芯片&#xff0c;之前使用arm架构M2芯片的时候&#xff0c;更是可怕&#xff0c;不过q…

博客文章SEO:提升博客排名和吸引更多读者的方法来啦!

互联网发展到现在&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;一直发挥着不可替代的作用。搜索引擎的流量往往更加定向&#xff0c;来自搜索引擎的流量转化率更高&#xff0c;可以帮助企业更好地实现销售和推广目标。因此&#xff0c;通过合理的SEO策略&#xff0c;你…

【FreeRTOS】消息队列——简介、常用API函数、注意事项、项目实现

在嵌入式系统开发中&#xff0c;任务间的通信是非常常见的需求。FreeRTOS提供了多种任务间通信的机制&#xff0c;其中之一就是消息队列。消息队列是一种非常灵活和高效的方式&#xff0c;用于在不同的任务之间传递数据。通过消息队列&#xff0c;任务可以异步地发送和接收消息…

泛型和Object的区别

什么时候使用 泛型&#xff1a;只要确定了用哪类对象&#xff0c;并且用到这个对象里的方法。选择泛型&#xff0c;泛型更加精确&#xff0c;只要用到Object的地方基本都能用泛型代替。Object类&#xff1a;Object是所有类的父类&#xff0c;更加笼统&#xff0c;且只能使用固…

找不到客户?交你一招

在当今社会中&#xff0c;获取潜在客户的信息对于企业的成功至关重要。然而&#xff0c;许多企业却面临着找不到潜在客户的难题。 企业想要成交的第一步就是寻找客户&#xff0c;将产品和目标客户进行匹配才能提高成交率。 因此企业首先需要明确自己的目标客户群体&#xff0…

GAN:WGAN-DIV

论文&#xff1a;https://arxiv.org/pdf/1712.01026.pdf 代码&#xff1a; 发表&#xff1a;2018 摘要 在计算机视觉的许多领域中&#xff0c;生成对抗性网络已经取得了巨大的成功&#xff0c;其中WGANs系列被认为是最先进的&#xff0c;主要是由于其理论贡献和竞争的定性表…

Leetcode—538.把二叉搜索树转换为累加树【中等】

2023每日刷题&#xff08;四十九&#xff09; Leetcode—538.把二叉搜索树转换为累加树 实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(…

Node包管理工具 - nvm、npm、yarn、cnpm、pnpm

转载说明 原文地址 简介 nvm : 可以实现一台电脑&#xff0c;拥有多个版本的Node npm : node package manager 下载Node后自带的一个包管理工具 yarn : npm 的升级版&#xff0c;更优秀 cnpm : 配置下载非官方地址的依赖&#xff08;淘宝、华为、腾讯镜像&#xff09; pnpm :…