發了我將近一天半時間
總結:
一,一開始就想做出來,導致出現錯誤不知道是那個地方。
二,由于一開始方向錯誤,導致時間用了很久。
三,由于不能調試,不知道怎樣檢查錯誤之所在。
四,后面自己有寫了子函數一個一個的調。
五,由于一開始我調用了POW函數,不知道為什么這個函數居然占用了大量的空間,導致程序反映很慢
這還不說,由于代碼有點長,居然編譯不過,找了好久才找出原因,后來只有自己寫一個函數了,所以以后
盡量不要亂調用函數,能自己寫代碼就自己寫。哎。。
最后總結:一,把任務模塊化,從最簡單的開始。
二,一定要先想好了,才開始敲鍵盤
三,最事情一定要注意細節,由于輸入的最大值超過了65535,而我調用函數的時候卻返回了一個int
導致自己始終不知道那個地方出錯了,要是一個變量我應該很容易想到溢出,但是函數返回值溢出第一次碰見。本程序完整版的下載地址:http://m.izizhuan.cn/f/suishoujisu.rar
//本單片機紅外直接由外部中斷1連起來的為紅外輸入你的工資,再通過稅收的公式算出你要交的稅//按一下外部中斷0,表示輸入完成
#include <reg51.h>
unsigned a[5],b[5],flag;
unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int wei;
long temp=0 ;
double recond;
sbit hwx=P3^3; //定義紅外接收腳,
char cout;
unsigned char l_lhj[66] ; //定義66位數組變量來存儲接收的時間參數
void delay (void) //空5個指令
{
unsigned char i=13;
while(i)
i--;
}
void delay1()
{
int i=100 ;
while(i--);
}
long power( int i) //10的i次方函數
{
long sum=1;
unsigned char j;
for(j=0;j<i;j++)
sum=sum*10;
return sum;
}
void display()
{
int i;
P1=0;
P2=table[a[wei]];
for(i= 1;i<=wei;i++)
{
delay1();
P2=table[a[wei-i]];
P1++;
}
}
void displayf() //由于只有兩位小數,所以就單獨顯示
{
int tmp=recond ;
P2=P2+0x80;
delay1();
P1=wei+1;
P2=table[tmp/10] ;
delay1();
P1++;
P2=table[tmp%10];
delay1();
}
void intandfloat()
{
//這個地方要根據你輸入數字的位數,如果是4位,i<4
//如果是五位i<5
int i;
if(cout<4)
;
else
{
if(b[0]>=2)
{
for(i=0;i<cout ;i++)
temp=temp+b[i]*power(cout-1-i); //10的i次方
temp=temp-2000; //稅收規定:工資-2000
}
}
}
void chuli(int temp)
{
int i;
for(i=0;;i++)
{
a[i]=temp%10;
temp=temp/10;
if(temp<=0)
break;
wei++;
}
}
void f(int i) //
{
int temp1;//保留變量
temp1=temp;
temp=temp*0.05*i;//記住整數部分
recond=temp1*5*i;
recond=100*(recond-temp*100);//記住小數部分
recond=recond/100;
}
void tax()
{
int c ;
long b;
b=temp;
if(b<=500)
c=1;
else
if(b<=2000)
c=2;
else
if(b<=5000)
c=3;
else
if(b<=20000)
c=4;
else
if(b<=40000)
c=5;
else
if(b<=60000)
c=6;
else
if(b<=80000)
c=7;
else
if(b<=100000)
c=8;
switch(c)
{
case 1: f(c);
break;
case 2:
f(c);
temp=temp-25;
break;
case 3:
f(c);
temp=temp-125;
break;
case 4:
f(c);
temp=temp-375;
break;
case 5:
f(c);
temp=temp-1375;
break;
case 6:
f(c);
temp=temp-3375;
break;
case 7:
f(c);
temp=temp-10375;
break;
case 8:
f(c);
temp=temp-17375;
break;
}
}
void show()
{
int i;
P1=0;
for(i=0;i<cout;i++)
{
P2=table[b[i]];
delay1();
if(i>=cout-1)
break;
P1++;
}
}
void main()
{
EA=1;
EX0=1;
EX1=1;
IT0=1;
IT1=1;
while(1)
{
if(flag==0)
show();
else
{
display(); //顯示整數
displayf() ; //顯示小數
}
}
}
void zhongduan() interrupt 0
{
flag++;
intandfloat(); //整數和小數分開
tax();//稅收函數
chuli(temp); //處理整數
EX0=0;
}
void hongwai(void) interrupt 2 //外部中斷 1 ,INT1(P3^3)連接紅外線接收IC數據腳
{
unsigned char i,j,tmp ;
unsigned int tmp2;
EX1=0;
// hwx=1;
j=33;
i=0;
tmp2=0;
while(!hwx){
tmp2++;
if(tmp2==1000)
break;
}
if(tmp2<1000){ //小于1000個記數的判斷為干擾退出接收
EX1=1;
return;
}
//P2=0x76; //數碼管輸出顯示H,作為紅外接收的指示
while(j){
tmp=0;
l_lhj[i]=1;
while(!hwx){ //檢測高低電平的變化
l_lhj[i]++; //沒變繼續加1
delay(); //加入延時,是因為我們采用8位二進來存儲,如果不加延時,時間量將計滿
tmp++; //此變量為防止干擾帶來的死循環
if(tmp==250)
break;
}
i++;
tmp=0;
l_lhj[i]=1; //時間量從1開始
while(hwx){ //檢測高低電平的變化
l_lhj[i]++; //沒變繼續加1
delay(); //同上
tmp++;
if(tmp==250)
break;
}
i++;
j--;
}
i=255; //加入循環延時,處理數據
while(i){
tmp=255;
while(tmp){
P2=0XF0;
tmp--;
}
i--;
}
tmp=0;
//這里顯示了全部的四段碼,包括地址位兩段,控制位兩段,每段用點分開
for(i=35;i<51;i++,i++) //同上,這里處理控制位前8位
{
tmp>>=1;
if(l_lhj[i]>30)
tmp+=0x80;
}
b[cout]=tmp%16;
cout++;
EX1=1;
}
