C8051矩阵计算器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "C8051F020.h"
#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={'0','1','2','3','4','5','6','7','8','9','+','-','*','/','=','.'};
uchar key,flag1,js,k1,k2;
uchar a[20],b[20];
float jieguo=0;
void delay(unsigned char z)//延时函数
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_cmd(unsigned char cmd)//LCD写命令函数
{
P4=0x00;
P5=cmd;
delay(5);
P4=0x80;
delay(5);
P4=0x00;
}
void write_data(unsigned char date)//写数据函数
{
P4=0x20;
P5=date;
delay(5);
P4=0xA0;
delay(5);
P4=0x00;
}
void init()//液晶初始化函数。
{
delay(15);
write_cmd(0x38); //8为数据口 两行显示 5*7点阵
write_cmd(0x08); //显示关闭
write_cmd(0x01); //清DDRAM内容 及清屏
write_cmd(0x06); //显示光标移动设置
write_cmd(0x0c); //显示开及光标设置
}
void keyscan() //键盘扫描程序
{
unsigned char temp,uu=0xf7;
unsigned int i;
for(i=0;i<4;i++)
{
uu=_crol_(uu,1); //_crol_为左移函数
P2=uu;
temp=P2;
temp=temp&0x0f;
if(temp!=0x0f)
{
delay(10);
temp=P2;
temp=temp&0x0f;
if(
temp!=0x0f)
{
temp=P2;
switch(temp)
{
case 0xd7: key=0; break;
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0xed: key=4; break;
case 0xdd: key=5; break;
case 0xbd: key=6; break;
case 0xeb: key=7; break;
case 0xdb: key=8; break;
case 0xbb: key=9; break;
case 0x7e: key=10; break;
case 0x7d: key=11; break;
case 0x7b: key=12; break;
case 0x77: key=13; break;
case 0xb7: key=14; break;
case 0xe7: key=15; break;
default: key=16;break;
}
while(temp!=0x0f)
{
temp=P2;
temp=temp&0x0f;
}
flag1=1;
}
}
}
}
void jsxs() //计算并显示函数
{
unsigned char i,j,n;
float s,temp2;
long int s1,s2,a1,b1,c1,temp1;
a1=b1=1;
s1=s2=0;
s=0;
if(k2!=0)
{
for(j=0;j
for(i=0;i
s1=s1+a[j]*a1;
a1=1;
}
for(j=k1+1;j
for(i=0;i
s2=s2+a[j]*b1;
b1=1;
}
if(js==10) //判断是什么运算,并执行运算
{
s=s1+s2;
}
if(js==11)
{
s=s1-s2;
}
if(js==12)
{
s=s1*s2;
}
if(js==13)
{
s=(s1*0.001)/(s2*0.001);
}
jieguo=s;
}
else
s=jieguo;
c1=(long int)(s*1000)%10;
if(c1>5 || c1==5)
s=s+0.01;
temp1=(long int)(s); //以下部分处理结果
temp2=s-temp1;
n=0;
while(temp1)
{
b[n]=temp1%10;
temp1=temp1/10;
n++;
}
b[n]=temp2*10;
b[n+1]=(unsigned char)(temp2*100)%10;
for(i=n;i>0;i--) //在液晶上显示结果
{
write_data(table[b[i-1]]);
}
write_data(ta
ble[15]);
write_data(table[b[n]]);
write_data(table[b[n+1]]);
}
void SysClkInit(void) //配置系统时钟
{
int n = 0;
OSCXCN = 0x67; //启动外部时钟
for (n = 0; n < 255; n++) ; //延时等待外部时钟启振
while ( (OSCXCN & 0x80) == 0 ); //查询外部时钟是否启动完成
OSCICN = 0x0c; //切换到外部时钟
}
void CloseWDT(void)//关闭看门狗
{
WDTCN = 0xDE; // 关闭 WDT
WDTCN = 0xAD; //关闭看门狗
}
void PortInit(void)//端口配置
{
// 交叉开关配置
// XBR0 = 0x04;
// XBR1 = 0x00;
XBR2 = 0xc0; //弱上拉关闭,交叉开关打开
//输出方式设置
P74OUT = 0x00; //P4~P7输出形式为漏极开路
P0MDOUT = 0xff; //P0输出形式为漏极开路
P1MDOUT = 0x00; //P1输出形式为漏极开路
P2MDOUT = 0xf0; //键盘端口初始化,高4位为输出模式,低四位为漏极开路
P3MDOUT = 0x00; //P3输出形式为漏极开路
P1MDIN = 0xFF;//数字输入方式
//默认输出数据设置
P4 = 0xff;
P5 = 0xff;
}
void main()
{
unsigned char i,j;
init();
SysClkInit();
CloseWDT();
PortInit();
write_cmd(0x80); //将液晶指针定位在第一行第一个单元
key=15;
i=flag1=0;
while(1)
{
keyscan();
if(flag1==1)
{
if(key==15)
{ write_cmd(0x01);
i=0;
for(j=0;j<20;j++)
a[j]=b[j]=0;
k1=k2=0;
}
else if(key<10)
{
write_data(table[key]);
a[i]=key;
i++;
}
else if(key<14)
{
write_data(table[key]);
k1=i-1;
js=key;
}
else
{
write_data(table[key]);
if(i==0)
k2=0;
else
k2=i-1;
write_cmd(0x80+0x40); //将液晶指针定位在第二行第一个单元
jsxs();
}
flag1=0;
}
}
}