|
我是一名在校學(xué)生,這次是單片機(jī)的課程設(shè)計(jì),要求做一個(gè)簡(jiǎn)易計(jì)算器,實(shí)現(xiàn)支持5個(gè)一位數(shù)的混合計(jì)算,以及可以回讀10次計(jì)算結(jié)果,但是出現(xiàn)了兩個(gè)問(wèn)題無(wú)法解決,老師又是打太極懶得看程序。故求各位幫幫忙指導(dǎo)一下。
程序如下:( = =新手,多余代碼或者寫(xiě)法繁瑣請(qǐng)見(jiàn)諒。。。。)
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit R=P2^0; //使能
sbit W=P2^1;
sbit E=P2^2;
void delay(unsigned int k); //延時(shí)
void init(); //LCD初始化
void write_com_1602(uchar command); //寫(xiě)命令
void write_data_1602(uchar datum); //寫(xiě)數(shù)據(jù)
void desplay(uint a); //顯示程序
void show(ulong x ); //顯示第二行
uchar anjian(void) ; //鍵盤(pán)掃描
ulong js(void) ; //計(jì)算函數(shù)
uint key;
uint a[9]; //存儲(chǔ)九次按鍵
uint du[10]; //存儲(chǔ)十次計(jì)算結(jié)果
uchar time,p,t,r;
void DelayMS(uint x) //延時(shí)函數(shù)
{
uchar i;
while(x--)
for(i=0;i<250;i++);
}
void main()//主函數(shù)
{
ulong x,i,j;//
_nop_();
init();
t=0;
j=0;
r=0;
P1=0xf0; //p1賦值后 矩陣鍵盤(pán)開(kāi)啟
time=9; //倒計(jì)時(shí)初值,在定時(shí)函數(shù)里進(jìn)行自減
p=0;
IT0=1;//選擇外部中斷0為跳沿觸發(fā)方式
TMOD=0x01;
ET0=1; //定時(shí)器中斷允許
EA=1;
EX0=1;//外中斷0允許
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TR0=1;
while(time==-1?0:1);//倒計(jì)時(shí)歸零判斷
TR0=0;
write_com_1602(0X01);//清屏
while(1)
{
while(P1==0xf0);
key=anjian(); //按鍵輸入
if(key<=9&&key>=0) //判定鍵值
{
a[j]=key; //數(shù)字鍵值,顯示數(shù)字
desplay(key);
j++;
while(P1!=0xf0);
delay(30);
}
else if(key<=13&&key>=10) //符號(hào)鍵值,顯示加減乘除號(hào)
{
switch (key)
{
case 10: write_data_1602('+'); a[j]=10; j++; break;
case 11: write_data_1602('-'); a[j]=11; j++; break;
case 12: write_data_1602('*'); a[j]=12; j++; break;
case 13: write_data_1602('/'); a[j]=13; j++; break;
default: break;
delay(130);
}
delay(130);
}
else if(key==15) //等號(hào)鍵值
{
write_com_1602(0x80+0x40); //給AC送值
write_data_1602('=');
x=js();
du[r]=x;
t=r;
r++;
show(x);
}
else if(key==14) //清零鍵值
{
write_com_1602(0X01); //清屏
write_com_1602(0X80); //給AC送值
for(i=0;i<9;i++)
a=0;
j=0;
}
}
}
void init() //LCD初始化
{
E=0;
W=0;
write_com_1602(0X38);//數(shù)據(jù)位為8位,顯示2行字符.5*7點(diǎn)陣字符體
write_com_1602(0X0F);//開(kāi)顯示,光標(biāo)消失,不閃爍
write_com_1602(0X06);//光標(biāo)右移,AC遞增
write_com_1602(0X01);//清屏
write_com_1602(0X80);//給AC送值
}
void write_com_1602(uchar command)//寫(xiě)命令
{
E = 0;
R = 0;
W = 0;
P0 = command;
delay(2);
E = 1;
delay(4);
E = 0;
}
void write_data_1602(uchar datum)//寫(xiě)數(shù)據(jù)
{
E = 0;
W = 0;
R = 1;
P0 = datum;
delay(2);
E = 1;
delay(4);
E = 0;
}
uchar anjian(void) //鍵盤(pán)掃描
{
uchar x;
while(P1==0xf0);
P1=0XFE; //鍵掃第一行
if (P1!=0XFE)
{
DelayMS(20);
if (P1!=0XFE)
{
switch (P1)
{
case 0XEE : while(P1==0XEE); x=7;//P1=0XFf;
break;
case 0XDE :while(P1==0XDE); x=8;// P1=0XFf;
break;
case 0XBE :while(P1==0XBE); x=9; //P1=0XFf;
break;
case 0X7E :while(P1==0X7E); x=10;// P1=0XFf;
break;
}
}
}
P1=0XFD; //鍵掃第二行
if (P1!=0XFD)
{ DelayMS(20);
if (P1!=0XFD)
{
switch (P1)
{
case 0XED : while(P1==0XED); x=4;// P1=0XFf;
break;
case 0XDD : while(P1==0XDD);x=5; // P1=0XFf;
break;
case 0XBD : while(P1==0XBD);x=6; //P1=0XFf;
break;
case 0X7D : while(P1==0X7D);x=11; // P1=0XFf;
break;
}
}
}
P1=0XFB; //鍵掃第三行
if (P1!=0XFB)
{ DelayMS(20);
if (P1!=0XFB)
{
switch (P1)
{
case 0XEB : while(P1==0XEB); x=1;// P1=0XFf;
break;
case 0XDB : while(P1==0XDB);x=2;// P1=0XFf;
break;
case 0XBB : while(P1==0XBB);x=3; //P1=0XFf;
break;
case 0X7B : while(P1==0X7B);x=12;// P1=0XFf;
break;
}
}
}
P1=0XF7; //鍵掃第四行
if (P1!=0XF7)
{ DelayMS(20);
if (P1!=0XF7)
{
switch (P1)
{
case 0XE7 : while(P1==0XE7); x=14; // P1=0XFf;
break;
case 0XD7 : while(P1==0XD7); x=0;// P1=0XFf;
break;
case 0XB7 : while(P1==0XB7); x=15; // P1=0XFf;
break;
case 0X77 : while(P1==0X77); x=13; //P1=0XFf;
break;
}
}
}
P1=0xf0;
while(P1!=0xf0);
return x;
}
void desplay( uint a) // 一位數(shù)輸出顯示
{
uchar b;
b=a+0x30;
write_data_1602(b);
}
void delay(uint k) //延時(shí)函數(shù)
{
int l;
while(--k!=0)
{
for(l=0;l<125;l++);
}
}
void show( ulong x )//LCD多位數(shù)顯示
{
uint num,c,j;
ulong a=1,k;
uchar table[]={"0123456789"};
uchar y;
num=0;
write_com_1602(0x80+0x41);
k=x;
while(k!=0)
{
num++;
k=k/10;
}
for(j=1;j<num;j++)
{
a=a*10;
}
while(num)
{
c=x/a;
x=x%a;
a=a/10;
y=table[c];
num--;
write_data_1602(y);
delay(50);
}
}
ulong js(void) //計(jì)算函數(shù)(判定符號(hào),計(jì)算,左移位)
{
ulong x,i,j;
for(i=1;i<9;i=i+2)
{
if(a==12||a==13)
{
if(a==12)
{
a[i-1]=a[i-1]*a[i+1];
for(j=i;j<9;j++)
a[j]=a[j+2];
a[7]=0;
a[8]=0;
}
if(a==13)
{
a[i-1]=a[i-1]/a[i+1];
for(j=i;j<9;j++)
a[j]=a[j+2];
a[7]=0;
a[8]=0;
}
i=-1;
}
}
for(i=1;i<9;i=i+2)
{
if(a==10||a==11)
{
if(a==10)
{
a[i-1]=a[i-1]+a[i+1];
for(j=i;j<9;j++)
a[j]=a[j+2];
a[7]=0;
a[8]=0;
}
if(a==11)
{
a[i-1]=a[i-1]-a[i+1];
for(j=i;j<9;j++)
a[j]=a[j+2];
a[7]=0;
a[8]=0;
}
i=-1;
}
}
x=a[0];
return x;
}
void time0() interrupt 1 //定時(shí)中斷
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
p++;
if(p==20)
{
write_com_1602(0X01);
write_data_1602(time+0x30);
time--;//倒計(jì)時(shí)變量自減
p=0;
}
}
void int0() interrupt 0 //回讀函數(shù)
{
uint num,c,j;
ulong a=1,k;
uchar table[]={"0123456789"};
uchar y;
num=0;
write_com_1602(0x80+0x41);
k=du[t];
write_com_1602(0X01);
while(k!=0)
{
num++;
k=k/10;
}
for(j=1;j<num;j++)
{
a=a*10;
}
while(num)
{
c=du[t]/a;
du[t]=du[t]%a;
a=a/10;
y=table[c];
num--;
write_data_1602(y);
delay(50);
}
t--;
}
仿真圖:

開(kāi)發(fā)板矩陣鍵盤(pán)原理圖:

問(wèn)題1:仿真時(shí),回讀數(shù)據(jù)只能回讀上一次回讀后的。即先開(kāi)機(jī)然后連續(xù)計(jì)算5個(gè)結(jié)果后,回讀是從5讀回1。接著又計(jì)算兩個(gè)結(jié)果后,回讀僅只有上兩個(gè)結(jié)果,再之前的5個(gè)沒(méi)了。但是編寫(xiě)程序的時(shí)候沒(méi)有將前5個(gè)數(shù)據(jù)清除呀。
問(wèn)題2:仿真完全可以實(shí)現(xiàn)計(jì)算部分,然后導(dǎo)入開(kāi)發(fā)板之后,符號(hào)位那一列按鍵失效。仿真圖的矩陣鍵盤(pán)與開(kāi)發(fā)板一致的,線也沒(méi)接反。換了好幾個(gè)開(kāi)發(fā)板都是同樣的結(jié)果。
簡(jiǎn)易計(jì)算器.rar
(21.35 KB, 下載次數(shù): 9)
2015-4-1 18:13 上傳
點(diǎn)擊文件名下載附件
|
|