利用51单片机制作LCM显示的简单计算器程序 C的
从51单片机 RAM 数据存储器分布图可知,从80H—FFH地址单元(也是128个字节)为特殊寄存器(SFR)单元,地址从00H—7FH单元(共128个字节)为用户数据RAM,用户数据单元,只指用户在编程时可以定义的寄存器,一般用于计算、暂存或转换作用,如没有这些单元,那基本上单片机就没有作用了
所以作为单片机选型时,RAM的大小也直接决定了它的成本,不存在楼主所说的浪费现象,可以根据自己程序的复杂度来决定选型RAM的大小。
51单片机的RAM分布如下图
下面是我用STC89C52单片机编的程序,采用4*4矩阵键盘,键盘接P3口,采用六位数码管(共阴极)显示,数码管位选和片选信号分别通过两个锁存器接P0口,位选所存端接P^7口,段选所存端接P2^6口。矩阵键盘的具体接法和各位表示的含义楼主可以从程序里看的出来,楼主可以根据自己的硬件对我的程序加以修改应该就会好使,下面的程序是我自己设计的,并且用硬件检验过好使,可以实现两个整数的加减乘除,和平方,祝你成功!
#include
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
void display(long z);
long k, temp,num,num1,num2,num3,num4,f,f1,f2,f3,swan,wan,qian,bai,shi,ge,equ,biao;
/*f1=1 :有键按下.f=1 f2=1:有符号键按下.f3=0/1:输入第一个数/输入第二个数,biao=1/2/3/4:加减乘除
equ=1:按下等于号,num:keyscan中键值num1:得到连续输入的值num2:第一次输入的值,num3:第二次输入
的值,num4:被显示的值*/
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};//数码管段选代码
uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//数码管位选代码
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
long keyscan()//键盘扫描函数
{
P3=0xfe;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)//键盘去抖
{
temp=P3;
switch(temp)
{
case 0xee:num=7;f1=1;f2=0;break;
case 0xde:num=8;f1=1;f2=0;break;
case 0xbe:num=9;f1=1;f2=0;break;
case 0x7e:num='/';f1=1;f=1;f2=1;f3=1;biao=4;break;
}
while(temp!=0xf0)//松手检测
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xfd;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=4;f1=1;f2=0;break;
case 0xdd:num=5;f1=1;f2=0;break;
case 0xbd:num=6;f1=1;f2=0;break;
case 0x7d:num='*';f1=1;f=1;f2=1;f3=1;biao=3;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xfb;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=1;f1=1;f2=0;break;
case 0xdb:num=2;f1=1;f2=0;break;
case 0xbb:num=3;f1=1;f2=0;break;
case 0x7b:num='-';f1=1;f=1;f2=1;f3=1;biao=2;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
P3=0xf7;
temp=P3&0xf0;
while(temp!=0xf0)
{
delay(100);
temp=P3&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num='c';f1=1;f2=1;biao=5;equ=1;break;
case 0xd7:num=0;f1=1;f2=0;break;
case 0xb7:num='=';f1=1; f=1;f2=1;equ=1;break;
case 0x77:num='+';f1=1; f=1;f2=1;f3=1;biao=1;break;
}
while(temp!=0xf0)
{
temp=P3;
temp&=0xf0;
display(num4);
}
}
}
return num;
}
void display(long z)//显示函数
{
swan=z/100000;
wan=z%100000/10000;
qian=z%10000/1000;
bai=z%1000/100;
shi=z%100/10;
ge=z%10;
if(swan==0)//数码管最高位为0则不现实
{
P0=table1[0];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[0];
wela=1;
wela=0;
P0=table[swan];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan))//前两位都为0则不现实(后面类似)
{
P0=table1[1];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[1];
wela=1;
wela=0;
P0=table[wan];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian))
{
P0=table1[2];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[2];
wela=1;
wela=0;
P0=table[qian];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian||bai))
{
P0=table1[3];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[3];
wela=1;
wela=0;
P0=table[bai];
dula=1;
dula=0;
delay(2);
}
if(!(swan||wan||qian||bai||shi))
{
P0=table1[4];
wela=1;
wela=0;
P0=table[16];
dula=1;
dula=0;
}
else
{
P0=table1[4];
wela=1;
wela=0;
P0=table[shi];
dula=1;
dula=0;
delay(2);
}
P0=table1[5];
wela=1;
wela=0;
P0=table[ge];
dula=1;
dula=0;
delay(2);
}
void jisuan()//连续按键时计算出按的值(如按1计算出为1再按2计算出12再按3计算出123)
{
k=keyscan();
if(f1==1)//有键按下
{
f1=0;
if(f==1)//有符号键按下
{
f=0;
num1=0;
}
else
num1=10*num1+k;
if(f2==0)//有数字键按下
{
if(f3==0)
{
num2=num1;
num4=num2;
}
else
{
num3=num1;
num4=num3;
}
}
}
}
void jieguo()//按等号时进行相应的计算并将结果计算出来
{
if(equ==1)
{
switch(biao)
{
case 1:num4=num2+num3;break;
case 2:num4=num2-num3;break;
case 3:num4=num2*num3;break;
case 4:num4=num2/num3;break;
case 5:num4=num2*num2;break;
}
}
}
void main()
{
while(1)
{
jisuan();
jieguo();
display(num4);
}
}
用51单片机做的简单计算器的程序.
/**********************按键处理*******************/
void KeyDeal(unsigned char Key)
{
if(Key!=0) //判断 有无按键按下。
{
switch(Key)
{ //以下定义0~9的数字键。
case 0x11: K=0; break;
case 0x21: K=1; break;
case 0x41: K=2; break;
case 0x81: K=3; break;
case 0x12: K=4; break;
case 0x22: K=5; break;
case 0x42: K=6; break;
case 0x82: K=7; break;
case 0x14: K=8; break;
case 0x24: K=9; break;
//以下+。-,*,/ 键
case 0x44: K=10; break; //加
case 0x84: K=11; break; //减
case 0x18: K=12; break; //乘
case 0x28: K=13; break; //除
case 0x48: K=14; break; //等于
case 0x88: K=15; break; //清除
default: break;
}
if(K<10) //数字键
{
d[2]=d[1];
d[1]=d[0];
d[0]=K;
c[2]=c[1];
c[1]=c[0];
c[0]=b[K];
//以上数组数据赋值是保证数字按键入顺序移位。
}
if(K==10) //加
{ m=d[2]*100+d[1]*10+d[0],d[0]=0,d[1]=0,d[2]=0,d[3]=0,d[4]=0;p=1;
c[0]=0xc0, c[1]=0xc0, c[2]=0xc0, c[3]=0xc0, c[4]=0xc0; }
if(K==11)//减
{ m=d[2]*100+d[1]*10+d[0],d[0]=0,d[1]=0,d[2]=0,d[3]=0,d[4]=0;p=2;
c[0]=0xc0, c[1]=0xc0, c[2]=0xc0, c[3]=0xc0, c[4]=0xc0;}
if(K==12)//乘
{ m=d[2]*100+d[1]*10+d[0],d[0]=0,d[1]=0,d[2]=0,d[3]=0,d[4]=0;p=3;
c[0]=0xc0, c[1]=0xc0, c[2]=0xc0, c[3]=0xc0, c[4]=0xc0;}
if(K==13)//除
{ m=d[2]*100+d[1]*10+d[0],d[0]=0,d[1]=0,d[2]=0,d[3]=0,d[4]=0;p=4;
c[0]=0xc0, c[1]=0xc0, c[2]=0xc0, c[3]=0xc0, c[4]=0xc0;}
if(K==14) //此处是按 =键
{ n=d[2]*100+d[1]*10+d[0];
if (p==1) shu=m+n;
if (p==2) shu=m-n;
if (p==3) shu=m*n;
if (p==4) shu=m/n;
c[4]=b[shu/10000];
c[3]=b[shu%10000/1000];
c[2]=b[shu%1000/100];
c[1]=b[shu%100/10];
c[0]=b[shu%10]; //C[]存的是 计算结果 。
}
if(K==15) // 此处是按 清除键
{d[0]=0,d[1]=0,d[2]=0,d[3]=0,d[4]=0;
shu=0;
c[4]=b[shu/10000];
c[3]=b[shu%10000/1000];
c[2]=b[shu%1000/100];
c[1]=b[shu%100/10];
c[0]=b[shu%10]; }
}
}
void main()
{
while(1)
{
Key = Keycan();//键盘扫描获取一次按键的编码0x11-0x88
KeyDeal(Key); //对扫描到的键盘编码进行转换处理,变成数据键盘0-
display();
}
只做过做过数码管的计算器
51单片机如何设置与主函数并行运行的定时器?
在51单片机中,可以使用定时器(Timer)来实现与主函数并行运行。以下是一般的步骤:选择定时器:根据需要选择定时器0或定时器1。定时器0使用TH0和TL0寄存器,定时器1使用TH1和TL1寄存器。设置定时器模式:可以选择模式0到模式3中的一个模式。模式0为13位定时模式,模式1为16位定时模式,模式2为8位自动...
51单片机c语言编写一个流水灯程序,要求如下(不能用数组,8个led指示灯...
\/\/流水灯#include "reg52.h"#define LED_PORT P3void delay(unsigned char time){ unsigned char i,j,k; for(i=0;i<time;i++) { for(j=0;j<200;j++) { for(k=0;k<200;k++); } }}void main(){ unsigned char i,halfbyteh=0x80,halfbytel=0x01; while(1) { ...
51单片机做数字电子钟
数字电子钟是以1s为最小定时单位的,51单片机自身具有两个16位定时\/计数器,当晶振频率为6MHz时,最大定时时间为0.13s。而具有时、分和秒的数字电子钟只能以1s定时,所以要实现实现1s定时,必须采用软件计数和定时器定时相结合的方法。每1s定时到,修改显示值,送6位LED显示。本课题需用6个LED数码管显示时间值,并且...
51单片机为基础用汇编语言编写用数码管显示一个同时有"加""减""乘...
ORG 0000H LJMP MAIN ORG 0100H MAIN:MOV SP,#7EH MOV 22H,#00H CLR P2.0 CLR P2.3 MOV 20H,#00H MOV 21H,#00H MOV 30H, #00H MOV 31H, #00H MOV 32H, #00H ;初始化 SU: MOV 7DH,#0FFH MOV 7EH,#0FFH MOV 7FH,#0FFH KEYI:ACALL KS1 CJNE A,#0F0H,LK1 ACALL ...
51单片机设计的简易的计算器
2011-09-15 求助:关于80C51单片机简易计算器设计的程序,要求是汇编语... 20 2017-06-24 求助各位大神:用51单片机制作的简单计算器程序 4 2016-12-02 大神,求51单片机做简易计算器的那个c语言程序 12 2014-06-23 用51单片机实现一个简单计算器的功能 1 2018-06-30 求不用单片机的简易计算器设计?谢谢...
51单片机用L9110S驱动12V电机?
你买的这种L9110S驱动板是单电源供电的,也就是把L9110S控制端和驱动端的供电全接在了一起。现在你用12V供电,那么输入的逻辑信号也必须是12V的才行,至少要达到12×0.7 = 8.4V才能被判定为高电平。51单片机输出电压0~5V,在人家看来始终低电平,不需要动作……
51单片机最小系统原理图
说明单片机使用内部存储器.如果选择外部的存储器,太浪费单片机仅有的资源,所以这一脚永远接电源5V(如上图所示),使用单片机的内部存储器.5 如果内部存储器不够容量,最多选择更高级的容量,就可以解决容量不够的问题了,就是这么简单 .一天入门51单片机:点我学习 .我是岁月哥,愿你学习愉快!
51单片机如何用一个按键和一个定时器来模拟PWM控制一个LED灯的亮度...
ifndef _51LED_define _51LED_define led P1 \/\/P1总线连8个led灯,灯连573锁存器,P1置低电平点亮 define LED led define ON(x) P1&(~(1<<(x))) \/\/打开某个灯,开多个灯用 ON(m) & ON(n)define OFF(x) P1|(1<<(x)) \/\/关闭某个灯,关多个灯用 OFF(m)...
求基于51单片机P01,P2 LED接数码管,用三极管驱动的电子时钟程序,大神...
程序名称:51单片机数码管电子钟汇编程序 简要说明:实现24小时制电子钟,8位数码管显示,显示时分秒 显示格式:23-59-59(小时十位如果为0则不显示)P0口输出段选信号,P2口输出位选信号 P1.0为调时按钮,P1.1为调分按钮;晶振12M 编 写:JiangX.net \/ ORG 0000H ;程序入口地址 LJMP START ...
51单片机用汇编语言如何编写LED灯逐渐变亮在逐渐变暗啊
这个要用到软件的pwm,因为51的没有硬件的pwm所以只好自己写软件的了。首先,要做一个软件三角波发生器子程序,频率自己定,就是变亮变暗的周期。此函数的返回值作为pwm的输入值。再做一个pwm的模拟程序,占空比(0-100)是三角波发生器的输出,pwm模拟程序控制某个端口输出1和0的占空比来控制灯 的...
诸葛腾甲苯: 楼主,我给你一个代码,你参考一下和验证一下! 用51单片机做的简单计算器的程序./**********************按键处理*******************/void KeyDeal(unsigned char Key){ if(Key!=0) //判断 有无按键按下.{switch(Key) { //以下定义0~9的数字...
旌德县18766907148: 求51单片机,用1602lcd显示的简易计算器的程序.除了加减乘除,还要有开平方和平方的 - ?
诸葛腾甲苯: 电路图:把8位数据线接到单独一个P*口上,其他CS,RS,WR,RD分别接到另一个数据口上,再就是电源和地接上.程序:需要你提供IC型号的,不同的IC指令不同
旌德县18766907148: 利用51单片机、LCD显示器设计一个单片机显示系统,要求在液晶上显示“HELLO,PROTUS”. - ?
诸葛腾甲苯: #include<reg52.h> //包含头文件,这个嘛,就不用多说了~~ #define uint unsigned int //预定义一下 #define uchar unsigned char sbit rs=P2^5; //1602的数据/指令选择控制线 sbit rw=P2^6; //1602的读写控制线 sbit en=P2^7; //1602的使能控制线 /*P2...
旌德县18766907148: 51单片机简单的1062液晶显示程序求助 - ?
诸葛腾甲苯: 光看代码你是不能了解它的使用历程的,最好看看使用手册,下面的代码是用1602液晶#include#define uchar unsigned char#define uint unsigned intuchar code table[]="I LIKE MCU!";uchar code table1[]="(uchar com){lcdrs=0;P0=com;delay(5)...
旌德县18766907148: 初学51单片机,想做一个简单的示波器,有一个设想不知道可不可行:用告诉AD把模拟信号转换成数字信号 - ?
诸葛腾甲苯: 可以 我做过测脉搏的,但是频率那个跟那些什么的设备的综合速度有关系至于上位机或者是液晶显示的话,,试试就知道了 上位机串口也行,WiFi也行 但是初学的话,,学基础吧,,刚会走就要飞,你后面的东西学不过去
旌德县18766907148: 基于51单片机数码管动态显示程序 - ?
诸葛腾甲苯: P2.7-P2.4为选择数码管,P1口接数码管8个笔画#include<xxxxx.H> //你所用单片机的型号 main() { while(1) { P2 = 0x1F; P1 = SEG_TAB[a/1000]; //送A的最高位代码,求段码后送显//示,要求A值不要大于4位数 delay_ms(2); //延时2ms,延时函...
旌德县18766907148: 用51单片机设计简单的一个程序, - ?
诸葛腾甲苯: #include<reg52.h> code unsigned char led[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};#define uint unsigned int#define uchar unsigned char sbit K1=P3^2; sbit K2=P3^3; char i=0; // //全局变量 void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=...
旌德县18766907148: 51单片机点阵LED显示. - ?
诸葛腾甲苯: 作为小白你先不要跨步太大.先从简单的流水灯开始做吧,做出各种闪烁效果,然后数码管,都懂了然后再LED点阵就容易理解多了
旌德县18766907148: 基于AT89C51单片机,利用定时器设计一个两位数码 管显示电路.求详细的设计过程. - ?
诸葛腾甲苯: 硬件很简单,我就不画图了,简单描述一下吧.在单片机最小系统的基础上,P0口接数码管的数据端,P2.6,P2.7接数码管的控制端. 程序如下: #include #define uint unsigned int #define uchar unsigned char sbit s1=P2^6;//十位 ...
旌德县18766907148: 如何用51单片机设计16*128点阵的LED显示器?
诸葛腾甲苯: 1:Dais-PG206试验箱,这是教学用的,应该是你们学校的实验仪器,建议你到实验室了解一下.2:16*16点阵就是256个LED发光二极管集成在一块上,16个脚接高电平16脚通过限流电阻接地,通电就亮,原理很简单.3:通信原理这个定义很...