基于單片機(jī)的紅外稅收計(jì)算器
總結(jié):
一,一開(kāi)始就想做出來(lái),導(dǎo)致出現(xiàn)錯(cuò)誤不知道是那個(gè)地方。
二,由于一開(kāi)始方向錯(cuò)誤,導(dǎo)致時(shí)間用了很久。
三,由于不能調(diào)試,不知道怎樣檢查錯(cuò)誤之所在。
四,后面自己有寫(xiě)了子函數(shù)一個(gè)一個(gè)的調(diào)。
五,由于一開(kāi)始我調(diào)用了POW函數(shù),不知道為什么這個(gè)函數(shù)居然占用了大量的空間,導(dǎo)致程序反映很慢
這還不說(shuō),由于代碼有點(diǎn)長(zhǎng),居然編譯不過(guò),找了好久才找出原因,后來(lái)只有自己寫(xiě)一個(gè)函數(shù)了,所以以后
盡量不要亂調(diào)用函數(shù),能自己寫(xiě)代碼就自己寫(xiě)。哎?。?!
最后總結(jié):一,把任務(wù)模塊化,從最簡(jiǎn)單的開(kāi)始。
二,一定要先想好了,才開(kāi)始敲鍵盤(pán)
三,最事情一定要注意細(xì)節(jié),由于輸入的最大值超過(guò)了65535,而我調(diào)用函數(shù)的時(shí)候卻返回了一個(gè)int
導(dǎo)致自己始終不知道那個(gè)地方出錯(cuò)了,要是一個(gè)變量我應(yīng)該很容易想到溢出,但是函數(shù)返回值溢出第一次碰見(jiàn)。本程序完整版的下載地址:http://www.51hei.com/f/suishoujisu.rar
//本單片機(jī)紅外直接由外部中斷1連起來(lái)的為紅外輸入你的工資,再通過(guò)稅收的公式算出你要交的稅//按一下外部中斷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位數(shù)組變量來(lái)存儲(chǔ)接收的時(shí)間參數(shù)void delay (void) //空5個(gè)指令{unsigned char i=13;while(i)i--;}void delay1(){int i=100 ;while(i--);}long power( int i) //10的i次方函數(shù){long sum=1;unsigned char j;for(j=0;ji;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() //由于只有兩位小數(shù),所以就單獨(dú)顯示{int tmp=recond ;P2=P2+0x80;delay1(); P1=wei+1;P2=table[tmp/10] ;delay1(); P1++; P2=table[tmp%10];delay1(); }void intandfloat(){//這個(gè)地方要根據(jù)你輸入數(shù)字的位數(shù),如果是4位,i4//如果是五位i5int i; if(cout4);else{if(b[0]>=2){for(i=0;icout ;i++)temp=temp+b[i]*power(cout-1-i); //10的i次方temp=temp-2000; //稅收規(guī)定:工資-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;//記住整數(shù)部分 recond=temp1*5*i; recond=100*(recond-temp*100);//記住小數(shù)部分 recond=recond/100; }void tax(){int c ;long b;b=temp;if(b=500)c=1;elseif(b=2000)c=2;elseif(b=5000)c=3;elseif(b=20000)c=4;elseif(b=40000)c=5;elseif(b=60000)c=6;elseif(b=80000)c=7;elseif(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;icout;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(); //顯示整數(shù) displayf() ; //顯示小數(shù)}} } void zhongduan() interrupt 0{flag++;intandfloat(); //整數(shù)和小數(shù)分開(kāi)tax();//稅收函數(shù)chuli(temp); //處理整數(shù)EX0=0;}void hongwai(void) interrupt 2
//外部中斷 1 ,INT1(P3^3)連接紅外線(xiàn)接收IC數(shù)據(jù)腳{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(tmp21000){ //小于1000個(gè)記數(shù)的判斷為干擾退出接收EX1=1;return;}//P2=0x76; //數(shù)碼管輸出顯示H,作為紅外接收的指示while(j){ tmp=0;l_lhj[i]=1; while(!hwx){ //檢測(cè)高低電平的變化l_lhj[i]++; //沒(méi)變繼續(xù)加1delay();
//加入延時(shí),是因?yàn)槲覀儾捎?位二進(jìn)來(lái)存儲(chǔ),如果不加延時(shí),時(shí)間量將計(jì)滿(mǎn)tmp++; //此變量為防止干擾帶來(lái)的死循環(huán)if(tmp==250)break;}i++;tmp=0;l_lhj[i]=1; //時(shí)間量從1開(kāi)始while(hwx){ //檢測(cè)高低電平的變化l_lhj[i]++; //沒(méi)變繼續(xù)加1 delay(); //同上tmp++;if(tmp==250)break;} i++; j--;}i=255; //加入循環(huán)延時(shí),處理數(shù)據(jù)while(i){tmp=255;while(tmp){P2=0XF0;tmp--;}i--; }tmp=0;//這里顯示了全部的四段碼,包括地址位兩段,控制位兩段,每段用點(diǎn)分開(kāi) for(i=35;i51;i++,i++) //同上,這里處理控制位前8位{ tmp>>=1;if(l_lhj[i]>30)tmp+=0x80;}b[cout]=tmp%16;cout++;EX1=1; }
評(píng)論