HD7279是一款用于擴展單片機I/O口的芯片,至少我是這么認為的,雖然它占用了單片機4個I/O但是真正作為傳輸的僅僅是一根總線,它可以同時驅動8位共陰數碼管(或者8×8點陣),及8×8的矩陣鍵盤,而同時接在單片機上的話,至少需要3~4組I/O,當然單總線控制的芯片基本需要自己的指令和時序。
接到這個課程設計之前我自己懶懶散散地看了一段時間的C51(用C語言編寫單片機代碼),之前老師教的是A51(用匯編編寫單片機代碼),我玩了很久,但是發現A51真的很局限,匯編這種語言是寫給機器看的,真正地寫0和寫1,真正是一個寄存器一個寄存器的調用,對于8位的51單片機來說,要實現1000×1000或者小數是比較困難的。老師推薦用C,之前只是看書實現過一些小東西這回要做比較大的項目了,雖然還有其他課題比如溫度計和數字鐘,不過都做過,只是環境不一樣,修改一下代碼太沒有挑戰性了。
確實開始輕敵了,真正做的時候發現不是那么簡單,
高中的時候學過一點VB做過計算器,如果讓我現在做,也許給我幾天我可以做出來,用C我也沒什么問題,但是C51就有難度了,要考慮太多硬件的東西,特別是顯示這個模塊好不容易瘦下去的頭又兩個大了。等我真正意識到的時候,已經過去幾個禮拜了,呵呵,要和朋友說抱歉了,雖然我答應“等我做完計算器之后再幫你改下程序”但是沒一個實現。
當然,此程序因為基本全是自己寫的,被方晉甬老師稱之為“程序設計不成熟、比較亂”的,額,本來準備用switch語句,但是呂昂老師說switch語句會產生過多閑置寄存器(可是他沒有考慮到我僅僅是實現很少的功能),這段程序只實現+-×÷,符號閃爍,過八位報錯等功能但是沒有小數,只能計算一步(加少數程序即可計算多部)。其實程序挺早就寫出來了,只是一直出不來效果,后來在仿真和VC++編譯環境下修改了很多,理論上是可以實現了,可是還是沒有顯示,于是抓狂了“看來我已處在瓶頸...”,晃了最后一個禮拜,周日周一看了兩天晚上,依然沒有看出什么來,禮拜二去方晉甬老師辦公室請教,查了近3個鐘頭【基本看過了我所有奇形怪狀的子程序—。—||||】,在仿真多遍之后發現就少了一句“while(!key)【檢測釋放按鍵】”【程序中紅字部分即主程序最后一句】囧啊~~~~以至于周四答辯的時候我演示之后,剛點看ppt他就說直接給A,不用答了。。。。
程序的完整版下載地址:http://www.izizhuan.cn/ziliao/file/jsjq.rar
/////////////////////////////****************程序*****************///////////////////////
#include<reg51.h>
#include<math.h>
sbit cs=P2^6;
sbit clk=P1^0;
sbit dat=P1^1;
sbit key=P3^3;
bit add,sub,mul,div,equ,clr;
unsigned char times,st,l,data_jp,flag,d;
unsigned int tmr;
unsigned long num[8],sn[8],disp[8],sh,result,hp=100000000;
void send(unsigned char);
unsigned char receive(void);
unsigned long real(unsigned long ,unsigned char);
unsigned long calcu(unsigned long, unsigned long);
void display(unsigned long);
unsigned long write_key(unsigned char);
void char_flk(void);
void test(void);
void error(void);
void long_delay(void);
void short_delay(void);
void delay10ms(unsigned char);
/////////**************主函數****************//////////
void main ()
{
times=0;
l=times;
st=0;
flag=0;
test();
while(1)
{
unsigned char i;
if(!key)
{
send(0x15);
data_jp=receive();
cs=1;
d=write_key(data_jp);
if (data_jp<=9)
{
flag=0;
num[times]=d;
}
else
{
flag=1;
//times-=1;
}
if(flag!=1)
{
if(num[0]==0)
{
times=0;
continue;
}
if(7>times>=1)
{
send(0xa1);
}
send(0x80);
send(num[times]);
while(!key);
delay10ms(1);
times=times+1;
cs=1;
if(times>7)
{
send(0xa4);
error() ;
times=0;
send(0xa4);
}
}
else
{
send(0xa4);
char_flk();
times-=1;
l=times;
for(i=0;i<=times;i++)
{
num[i]=real(num[i],l);
sh=sh+num[i];
l--;
}
sn[st]=sh;
if(st>=1)
{
result=calcu(sn[st],sn[st-1]);
sn[st-1]=result;
st--;
}
st++;
times=0;
flag=0;
sh=0;
if(equ==1)
{
st=0;
send(0xa4);
display(result);
equ=0;
}
if(clr==1)
{
st=0;
times=0;
flag=0;
sh=0;
add=0;
sub=0;
mul=0;
div=0;
equ=0;
clr=0;
send(0xa4);
}
while(!key);
}
}
}
}
/////////*********************測試子函數****************////////
void test(void)
{
char i;
delay10ms(2);
send(0xbf);
cs=1;
for (i=0;i<=3;i++)
{
delay10ms(100);
}
send(0xa4);
cs=1;
delay10ms(20);
}
///////***********************讀鍵盤程序**************///////
unsigned long write_key(unsigned char data_jp)
{
unsigned char shuzi;
if(data_jp<10)
{
shuzi=data_jp;
}
else
{
if(data_jp==10)
{
add=1;
}
else if(data_jp==11)
{
sub=1;
}
else if(data_jp==12)
{
mul=1;
}
else if(data_jp==13)
{
div=1;
}
else if(data_jp==14)
{
equ=1;
}
else if(data_jp==15)
{
clr=1;
}
shuzi=0xff;
}
return(shuzi) ;
}
///////***********************發送子函數*************//////
void send(unsigned char data_out)
{
unsigned char i;
cs=0;
long_delay();
for(i=0;i<=7;i++)
{
if(data_out&0x80)
{
dat=1;
}
else
{
dat=0;
}
clk=1;
short_delay();
clk=0;
short_delay();
data_out=data_out<<1;
}
dat=0;
}
/////************************接收鍵盤子函數************//////
unsigned char receive(void)
{
unsigned char i,data_in;
dat=1;
long_delay();
for(i=0;i<=7;i++)
{
clk=1;
short_delay();
data_in=data_in<<1;
if(dat)
{
data_in=data_in|0x01;
}
else
{
data_in=data_in|0x00;
}
clk=0;
short_delay();
}
dat=0;
return(data_in);
}
/////////***************************顯示數字處理子函數***********/////////
unsigned long real(unsigned long so, unsigned char s)
{
unsigned char z;
if(s!=0)
{
for(z=0;z<=(s-1);z++)
{
if(s!=0)
{
so=so*10;
}
else
{
so=so;
}
}
}
else
{
so=so;
}
return(so);
}
//////////*************************計算子函數*******************///////////
unsigned long calcu(unsigned long sn0,unsigned long sn1 )
{
if(add==1)
{
sn0=sn0+sn1;
add=0;
}
if(sub==1)
{
sn0=sn1-sn0;
sub=0;
}
if(mul==1)
{
sn0=sn0*sn1;
mul=0;
}
if(div==1)
{
if(sn0>0)
sn0=sn1/sn0;
else
error();
div=0;
}
return(sn0);
}
////////****************************報錯錯誤子函數***************/////////
void error(void)
{
while(key)
{
send(0x96);
send(0x4f);
delay10ms(2);
send(0x95);
send(0x05);
delay10ms(2);
send(0x94);
send(0x05);
delay10ms(2);
send(0x93);
send(0x1d);
delay10ms(2);
send(0x92);
send(0x05);
delay10ms(2);
}
}
///////////********************顯示子函數*********////////////
void display(unsigned long display)
{
unsigned char i,asus=8;
if(display>99999999)
error();
else
{
for(i=0;i<=7;i++)
{
if((display/hp)>=1)
break;
else
{
hp=hp/10;
asus-=1;
}
}
for(i=0;i<=asus;i++)
{
disp[i]=display/hp;
if(hp>1)
{
display=display%hp;
hp=hp/10;
}
}
for(i=0;i<=asus;i++)
{
if(i>0)
{ send(0xa1); }
send(0x80);
send(disp[i]);
}
}
}
///////////********************符號判斷閃爍顯示*********////////////
void char_flk(void)
{
if(add==1)
{
send(0x97);
send(0x77);
}
else if(sub==1)
{
send(0x97);
send(0x01);
}
else if(mul==1)
{
send(0x97);
send(0x37);
}
else if(div==1)
{
send(0x97);
send(0x49);
}
else if(clr)
{
;
}
send(0x88);
send(0x7f);
}
//////************************延時子函數*************///////
void long_delay(void)
{
char i;
for(i=0;i<=25;i++) ;
}
void short_delay(void)
{
char j;
for(j=0;j<=4;j++);
}
void delay10ms(unsigned char time)
{
unsigned char i;
unsigned int j;
for (i=0;i<=time;i++)
{
for(j=0;j<=0x390;j++);
}
}
///////////////////////////************效果圖*************////////////////////

以上演示的為9876543÷234,其本來的結果是42207.4487179……無法顯示小數位,所以結果為42207 。
