基于51最小系统计算机制作
一、设计目标
1. 矩阵按键控制的LCD显示计算器
附带 加、减、乘、除和复位以及报错功能;
除法运算结果显示包括三位小数;
2. 计数器(定时器实现)
3. DXP布线
二、硬件要求
51单片机最小系统
矩阵按键
LCD液晶显示屏
三、软件设计
(1)程序框图
(2)根据要求写出51程序
四、设计思路与原理分析
设计思路:
按键赋值,给每个按键赋予一种特定的功能(例如代表数字1、2、3或者+、-、*、/)
通过安检扫描识别被按下的按键,并给出相应的反馈(即键值);
配置LED,初始化,忙检测;
设计原理:
(1)按键检测(移位检测)
按键检测
uchar code key[]={0xef,0xdf,0xbf,0x7f}; //行检测
uchar code key1[]={0x7f,0xbf,0xdf,0xef};//列检测
uchar i,j,temp;
for(i=0;i<4;i++)
{
P1=key[i]; //高四位一次置低电平
temp=P1;
temp=temp<<4|0x0f;
for(j=0;j<4;j++) //一次检测按键按下使得那一列置低电平
{
if(key1[j]==temp)
{
number=i*4+j;//按键位置计算
}
}
}
(2)LCD初始化以及相关命令操作
①LCD管脚说明
②LCD初始化时序
③初始化设置
④读写操作时序
⑤忙检测
⑥其余相关命令设置
五、程序框图
六、测试程序
/********************************************************
*********矩阵按键完成基本计算器功能同时兼有报错功能*****
********************************************************/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define P 0x80 //用于忙检测
sbit rs=P2^6;// 1602
sbit rw=P2^5;// 使能
sbit e=P2^7;// 控制端
uchar code tab1[]={'c',0,'=','+',1,2,3,'-',4,5,6,'*',7,8,9,'/'};//按键对应键值
uchar code table[]=" error!!! ";
uint flag0=0; // = 标志位
uint flag1=0; // +
uint flag2=0;// -
uint flag3=0;// *
uint flag4=0; // /
uint fuhao=0; // 负号
uint point=0; //小数点
uchar T=0; //报错标志位
ulong a=0,b=0;//储存键值变量
uchar number;//按键标号
uchar code key[]={0xef,0xdf,0xbf,0x7f};//行检测
uchar code key1[]={0x7f,0xbf,0xdf,0xef};//列检测
void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=115;y>0;y--);
}
uchar busy() //忙检测
{
rs=0;
rw=1;
e=1;
delay(1);
while(P0&P); //判断数据位高位是否为0(允许)
e=0;
return P0;
}
void wdat(uchar dat) //写数据函数
{
P0=dat;
busy();
rs=1;
rw=0;
delay(5);
e=1;
delay(5);
e=0;
}
void wcmd(uchar cmd,uchar Q) //写命令Q决定是否需要检测忙
{
P0=cmd;
if(Q)
busy();
rs=0;
rw=0;
delay(5);
e=1;
delay(5);
e=0;
}
void init() //
{
e=0;
wcmd(0x38,0);//2*16 显示5*7 8位数据显示
wcmd(0x38,0);
wcmd(0x38,0);
wcmd(0x38,1);
wcmd(0x01,1); //清屏
wcmd(0x06,1); //地址加一
wcmd(0x0c,1); //开显示屏 无光标
wcmd(0x01,1); //清屏
}
void ankey() //按键输入反馈
{
uchar i,j,temp;
uchar w;
for(i=0;i<4;i++)
{
P1=key[i];
temp=P1;
temp=temp<<4|0x0f;
for(j=0;j<4;j++)
{
if(key1[j]==temp)
{
number=i*4+j;
switch(number)
{
case0:{wcmd(0x01,1);T=1;flag0=0;flag1=0;flag2=0;flag3=0;
flag4=0;fuhao=0;point=0;a=0;b=0;} break; 复位
case 2:flag0=1;break; // =
case 3:{flag1=1;wdat(0x2b);}break;//+
case 7:{flag2=1;wdat(0x2d);}break;//
case 11:{flag3=1;wdat(0x2a);}break; //
case 15:{flag4=1;wdat(0x2f);}break; //
case 4://1
case 5://2
case 6://3
case 8://4
case 9://5
case 10://6
case 12://7
case 13://8
case 14://9
case 1: //0
if(flag2||flag3||flag4||flag1)//
{
b=b*10+tab1[number]; // wdat(0x30+tab1[number]);
{
wcmd(0x01,0);
wcmd(0xc0,0);
for(w=0;w<16;w++)
{
wdat(table[w]);
delay(1);
}
b=0;
}
}
else
{
if(flag0) //
{
flag0=0;
wcmd(0x01,1);
wdat(0x30 +tab1[number]);
}
else
{
a=a*10+tab1[number];//
wdat(0x30+tab1[number]);
if(a>1000000000)//¾¯½äΪ ±¨´í
{
wcmd(0x01,0);
wcmd(0xc0,0);
for(w=0;w<16;w++)
{
wdat(table[w]);
delay(1);
}
a=0;
}
}
} break;
default:break;
}
}
while((key[i]!=P1)&&(key1[j]!=P1))
P1=key[i];
P1=key1[j];
delay(3);
}
}
}
void keysure()//ÑÓʱÏû¶¶
{
P1=0x0f;
if((P1&0x0f)!=0x0f)
{
delay(10);
if((P1&0x0f)!=0x0f)
ankey(); //È¡°´¼üÊäÈëÖµnumber
}
}
ulong ji_suan()//
{
uchar w=0;
ulong ans;
if(flag0==1)//
{
if(flag2||flag3||flag4||flag1)//
{
if(flag1==1)//
{
ans=a+b;
}
if(flag2==1)//
{
if(a>=b)
{
ans=a-b;
}
else
{
ans=b-a;
fuhao=1;//
}
}
if(flag3==1)//Èç¹û³ËºÅ¼ü°´ÏÂ
{
ans=a*b;
}
if(flag4==1)//
{
ans=(ulong)(((float)a/b)*1000);
point=1;//
}
}
}
return ans;
}
void result()//
{
uchar w;
uchar c=0;
ulong res;//½á¹û
res=ji_suan();//
if(flag0==1)//
{
if(res>1000000000)//
{
wcmd(0x01,0);
wcmd(0xc0,0);//
while(T)//
{
for(w=0;w<16;w++)
{
wdat(table[w]);
delay(1);
}
delay(500);
T=0;
}
}
else{
wcmd(0x04,0);//
wcmd(0xcf,0);//
do
{
wdat(0x30+res%10);
c++;
if(c==3&point)
wdat(0x2e);
res=res/10;
delay(10);
}
while(res);
if(point&res==0&&c==3)
wdat(0x30);
if(point&c<3)
{
while(3-c)
{
wdat(0x30);
c++;
}
wdat(0x2e);
wdat(0x30);
}
if(fuhao)
wdat(0x2d);
wdat(0x3d);
flag1=0;
flag2=0;
flag3=0;
flag4=0;
a=0;
b=0;
}
}
}
/*********************************************************************
*************************主函数***************************************
*********************************************************************/
void main()
{
init();//
while(1)
{
keysure(); //
result();//
}
}