基于51单片机简易计算器设计
本文将详细介绍设计一个简单的基于单片机51的计算器的整个过程,包括硬件电路设计、软件实现、仿真、PCB制造等步骤。使用Proteus7.8进行仿真,结合AltiumDesigner完成电路图和PCB设计,使用Keil4/5作为编译器并编写C程序,具体和设计步骤如下。
硬件设计由三部分组成:按钮模块、LCD1602显示模块和作为主控单元的51单片机。
按键模块采用4*4矩阵键盘进行输入功能; LCD1602负责显示数据; 微控制器作为系统控制中心,实现数据处理和控制逻辑。
软件主要由主程序、按键扫描程序和LCD1602显示程序组成。
主程序负责总体协调,按键扫描程序负责读取输入的按键,显示程序根据计算结果显示数据。
性能指标如下:制作一个简单的计算器,使用了51单片机,支持加、减、乘、除的基本运算,运算结果最大可达9999*9999。
使用Proteus仿真验证设计的正确性。
仿真图显示了硬件电路连接以及在LCD1602上显示数据所需的关键操作。
通过键盘输入测试加、减、除等运算功能,结果正确显示在第二行。
电路图是使用AD软件绘制的,详细说明了各个元件的连接。
PCB设计是使用Proteus完成的。
与实物作品相比,Proteus仿真在运行环境、调试方法、电路连接、操作速度和功能实现。
在源程序中,主程序代码实现了系统的通用控制逻辑。
项目报告包含详细的信息列表,包括常见问题的解决方案、流程、仿真、原理图和PCB、提案报告、功能需求、设计报告、讲解视频等。
为了帮助读者更好地设计,文章还提供了相关链接资源,包括 AltiumDesigner 安装和破解、KEIL+Proteus 微控制器建模指南、KEIL 安装和破解、查找 Proteus 组件、Proteus 安装、简单指南 使用Proteus 和单片机进行培训。
材料、数据指南、安全技巧、设计报告概述等。
单片机的简易计算器
介绍单片机计算器的基本功能:简单的加、减、乘、除运算。时间显示功能,可实现计算器模块和时间模块之间的任意切换。
按键音的功能发生了变化。
原理:多功能单片机计算器是实现加、减、乘、除和时间功能的计算器。
主要硬件为AT89s52单片机芯片、LED液晶(1602液晶)、4*4键盘、4个特殊功能键。
时钟芯片(DS1302)和蜂鸣器。
单个硬件模块介绍 AT89S52:由8kflash、256BRAM和6个中断源组成的主控芯片。
有关详细信息,请参阅 1602 LCD 模块内部字符生成存储器 (CGROM) 的技术文档。
存储160种不同的点阵字符图形。
这些字符包括阿拉伯数字、大小写英文字母以及常用符号。
固定代码,例如大写英文字母“A”的代码是01000001B(41H)。
显示时,模块在地址41H处显示点阵字符图形,可见字母“A”。
实现一些复杂的字符操作:1:清除显示,复位光标到地址00H,2:设置光标移动方向和显示模式,高电平向右移动,低电平向左移动,是否全部文字在屏幕上向左移动或向右移动。
级别越高表示有效,级别越低表示无效。
3:显示开关控制,控制整个显示的开与关,高电平表示显示开,低电平表示显示关,控制光标亮灭,高电平表示控制光标闪烁。
较低级别移动显示的文本。
,低电平时光标移动 5:功能设置命令 DL:高电平时 4 位总线,低电平时 8 位总线 N:低电平时显示一行,高电平时显示两行 F:低电平时 5x7 显示级别点阵字符,级别高时显示5x10点阵字符(高级别和低级别按照相应准则执行)。
请参阅 1602 上的技术文章了解更多详细信息。
1602采用标准16针接口。
引脚1:VSS为地电源。
引脚2:VDD 连接至5V 正极电源。
引脚3:V0为LCD对比度调节端。
当连接到正极电源时,当电源接地时对比度最弱。
它具有最高的对比度。
如果对比度太高,就会出现“重影”。
对比度可以通过10K电位器调节。
RS为高电平时为寄存器选择。
选择数据寄存器,低电平时选择指令寄存器。
引脚5:RW为读写信号线。
当电平为高时进行读操作,当电平为低时进行写操作。
当RS和RW都为低电平时,可以写入命令或显示地址。
当RS为低电平、RW为高电平时,可以读取忙信号。
。
引脚6:E端为使能端。
当E端从高电平跳变到低电平时,液晶模块执行命令。
引脚7-14:D0-D7 是8 位双向数据线。
脚 15-16:空脚。
1602液晶屏和单片机怎么连接 4*4键盘和4个特殊功能键 K(开关机键) 无(复位键)(时间设置键)C(清除键) +123-456*789%(不包括) - / +0。
=前四个是特殊功能键,最后16个使用键盘扫描连接方法。
首先将111111110(0XFE)分配到P3端口,然后阅读P3端口值是11101110(0xee)。
,这意味着按下第一项。
11011110(0xde)是指第一项。
如果行的第二个项目是10111110(0xbe),则表示按下第一行的第三个项目(0x7e)。
第二,第三和第四行被分配给P3端口的不同值,只要读取和判断P3端口的值,也使用相同的方法按下按钮。
此方法可用于扫描4*4键盘。
此方法使您可以在微控制器中大大保存IO端口资源。
有关更多信息,请参阅Internet上的键盘扫描原理时钟芯片(DS1302)。
DS1302是达拉斯发布的Seryu充电时钟芯片。
芯片包括真实的时钟/日历和31个字节静态RAM。
微控制器通过简单的串行接口。
真实的时间表/日历电路提供了有关每个月的天数和LEAP年数的信息。
可以自动顺时针通过AM/PM命令确定使用24或12小时格式。
DS1302和微控制器只能与1RES RESET 2I/O数据线3SCLK的三个端口线进行通信。
字符串行时钟/RAM读取或写入字节或最多31个字符的字符组。
有功能可以计算2100年之前的第二,分钟,时间,日期,周,月和年(请参阅DS1302技术文档X1X232.768KHz Crystal有关更多信息)振荡器PIN GND GND GND GND REST REST REST REST REST REST REST REST REST REST REST REST REST PIN I/O数据输入/O量引脚SCLK串行时钟VCC1,VCC2电源引脚计算器大约任务
怎样用51单片机做计算器啊?
1. 第一步,找到零件并将其放置在原理图上,如下图所示。
2.
3. include
#include voiddisp(void); void(uintvalue); 4. 在输出的HEX中观察仿真结果是否正确,如下图所示。
提供数据 计算机模拟:
Keil微控制器是一种先进的集成开发系统。
它代表了微控制器系统开发汇编语言的最新发展。
作者将多项战略技术和编程/模拟/调试/编写/加密开发的所有过程集成到一起,无需任何编译或运行。
教堂之间
值得注意的功能:
1. 可以模拟64Kxdata的空间,全部6个4K 16位地址空间; 3. UV2货物、速度等作业; 5. 当鼠标放置时,会建立某个变量,即显示其值;
7. 您可以在模拟中使用这些并执行 x 模拟数据; 9. -38400bps全波特率通讯速率; 12. 尺寸很小,方便插入到用户的表中,避免模拟时间。
13. 仿真扣采用金扣,可以有效及时防止生锈。
桌子。
; 商店和用户代码分离,不可能产生无法模拟的软缺陷;
15这根本不是普通的三极管简单电路可比的。
功能限制:
仿真器持有端口和定时器2单片机,与KeilC(PC)通信,因此不支持端口Vide和定时器2 . 模拟功能。
全速运行时,微控制器的视频端口和计时器可供 2 个用户使用。
使用说明:
1. ;
2. 用于模拟和调试。基于51单片机的简易计算器设计,急
//函数0123456789+-×÷=清除表3-1 3.2计算器软件开发
#include
#defineu intunsignedint //
#defineucharunsignedchar
sbitlcden=P2^3;//引脚定义
sbitrs=P2^4;
sbitrw=P2^0;
sbitbusy=P0^7;
chari,j,temp,num,num_1;
longa,b,s; //a,第一个数字b,第二个数字c,获取数字
floata_c,b_c;
ucharflag, fuhao;//flag表示符号键是否被按下, fuhao 表示按下的是哪个符号
<ucharcodetable[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};
ucharcodetable1[] ={
7,8,9,0x2 f-0x30,
4,5,6,0x2a-0x30,
1,2,3,0x2d-0x30,
0x01-0x30,0 ,0x3d-0x30,0x2b-0x30} <; /p>
voiddelay(ucharz)//延迟函数
{
uchary;
0;z--)for(y=0;y<110;y++);
} voidcheck()//我们评估是否忙或 无效
{
do{
P0=0xFF;
rs=0 //命令
rw=1; //读取
lcden=0; //禁止读写
delay(1);//等待液晶显示器处理数据
lcden= 1; //允许读写
} while(bu sy==1);//判断是否空闲,1忙,0空闲
}
voidwrite_com(ucharcom)//写一个命令函数
{
P0=com; //命令支付端口P0
rs=0;
rw=0;
lcden=0;
check() ;
lcden=1;
}
voidwrite_date(uchardate)//数据写入函数
{
P0=日期;
rs=1;
rw=0;
lcden =0;
check();
lcden=1;
}
voidinit()//初始化
{
num=-1;
lcden=1;//高分辨率信号 level
write_com(0x38);//8位,2行
write_com(0x0c);//显示亮,光标灭,不闪烁*/
write_com(0x06);//增量模式不移位显示?
write_com(0x80);//检测到信号 busy
write_com(0x01);//显示开启,光标关闭,不闪烁
num_1=0;
i=0;
j=0;
a=0; //成为第一个参与操作的号码
b=0 //第二个参与操作的号码
c=0;
flag=0;//flag表示字符键是否按下
fuhao=0;//fuhao表示按下的是哪个字符
}
fuhao=0;//fuhao表示按下的是哪个字符
}
voidkeyscan()//键盘 扫描仪
{
P3=0xfe;
if(P3!=0xfe)
{
延迟(20);//延迟20毫秒
if(P3!=0x fe)
{
temp=P3&0xf0;
开关(温度)
{
case0xe0:num =0;
break;
case0xd0:num=1;
中断;
case0xb0:num=2;
中断
case0x70:num=3;
中止;
}
while(P3!=0xfe);
if(num==0 ||num==1||num==2)//如果按'7'、'8'或'9
{
if(j!=0)
{
if(j!=0)
{
write_com(0x01);
j=0;
}
if(fla ag==0)//符号键没有按下
{
a=a*10+table[num]
};
else//如果按下了符号键
{
b= b*10+table[num];
else//如果按'/'
{
flag=1
fuhao=4;//4表示按下除号
i=table1[num]
write_date(0x30+我);
}
P3=0xfd;
if(P3!=0xfd)
{
延迟(5);
if(P3!=0xfd)
{
temp=P3&0xf0;
开关(临时)
{
case0xe0:num=4
中断;
case0xd0:num=5;
中断;
好的。
se0xb0:num=6;
break;
case0x70:num=7;
break;
while(P3!=0x fd);
if(num==4||num==5||num==6&&num!=7)//如果您按“4”、“5”或“6”
{
if(j!=0)
{
write_com(0x01);
j=0;
if(flag==0)//未按下按键符号
{
a=a*10+table[num];
else//如果按下了符号键
{
b=b*10 +表[编号]
}
else//如果按下'/'
{
flag=1
fuhao=3;//3,表示按下了乘号
i=table1[num];
write_date(0x30+i);
P3 =0xfb;if(P3!=0xfb)
{
延迟(5);
如果 (P3!=0xfb)
{
temp=P3&0xf0;
开关(temp)
{
case0xe0:num=8
break;
case0xd0:num=9;
中断
case0xb0:num=10;
中断;
case0x70:num=11;
中断;
}
while(P3!=0xfb );
if(num==8||n um==9||num==10)//如果按'1'、'2'或'3'
{
if(j!=0)
{
write_com(0x01);
j=0;
}
if(flag==0)//字符键没有按下
{
a=a*10+table[num];
{
a=a*10+table[num];
{
a=a*10+table[num];
}
else//如果按下了符号键
{
b=b*10+table[num];
}
elseif(num==11)//如果按'-'
{
flag=1;
fuhao=2;//2,表示按下了减号
i=table1[num];
write_date(0x30+i);
P3=0xf7;
if(P3!=0xf7)
{ p >
延迟(5);
if(P3!=0xf7)
{
temp=P3&0xf0;
切换(临时)
{
case0xe0:num=12 ;
中断;
case0xd0:num=13;
中断
case0xb0:num=14;
中断;
case0x70:num=15;
break;
}
while(P3!=0xf7) ;
开关(数字 )
{
case12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//点击“清除”
break;
a = a*10; write_date(0x30);P1=0;
}
elseif(flag==1)//如果按下了符号键
{
b=b*1 0;
write_date(0x30);
中断;
case14:{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 ;
els eif(fuhao== 2){write_com(0x80+0x4f); //光标移动到第二行最后一个显示位置
write_com(0x04); //设置数据记录来自后者。
向前,每次记录数据片段后,光标都会向后移动一个差距
//(从逻辑上相信这是错误的顺序,并且可以以与上一段相同的方式显示)
0)c = a-b;
否则
c = b-a; (C!= 0)
{
write_date(0x30+c%10);
i f(a-b <0)
write_date(0x2d); //再次写入“ =”
a = 0;
}
elseif(fuhao == 3){write_com(0x80+0x4f);
write_com(0x04);
c = a*b;
while(c!= 0)
{
c/p> i = 0;c =(long)((float)a/b)*1000) {
write_date(0x30+c%10);
如果(i == 3;)
write_date(0x2e);
}
if(a/b <= 0) )
write_date(0x30);
write_d ate(0x3d);
}
main()
{
init();
while(1)
{
keyscan();
}
}