|
自行車速度里程測量,使用的是外部中斷0計數(shù)里程脈沖,定時器0計算時間
PWM調(diào)速,使用定時器1產(chǎn)生PWM波形
兩個程序單獨使用都沒問題,
但是合在一起,兩個定時器一起用就出現(xiàn)問題,錯誤首先在數(shù)碼管位選端出現(xiàn)流水燈效果,第一次切割后恢復(fù)正常,沒有了流水燈效果,速度測量失效。里程測量還能用
附程序代碼:
- //速度:單位為 m/h 里程單位cm
- #include<reg51.h>
- #define duan P0 //段選
- #define wei P2 //位選P2^4-P2^7
- #define zhouchang 200 //車輪周長200cm
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
- uchar code display1[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管驅(qū)動信號0---9,共陽
- uchar code bitcode[]={0x7f,0xbf,0xdf,0xef}; //數(shù)碼管位選掃描信號 0111 1111
- sbit change = P3^4; //切換按鍵
- bit flag = 1; //切換標(biāo)記
- bit flag1=0; //第一次切割
- uchar point1 = 0; //小數(shù)點標(biāo)記,速度
- uchar buf1[]={0,0,0,0}; //數(shù)碼管該顯示的數(shù)字,高-----低,速度
- uchar point2 = 0; //小數(shù)點標(biāo)記,里程
- uchar buf2[]={0,0,0,0}; //數(shù)碼管該顯示的數(shù)字,高------低,里程
- uchar num = 4; //數(shù)碼管第num位
- uint time_counter = 0; //每10次切割時差,定時計數(shù)
- uint time_counter8 = 0; //8s定時計數(shù)
- uint external_counter = 0; //外部中斷計數(shù)
- ulong s = 0;//里程
- ulong speed = 0;//速度
- sbit PWM=P1^0; //PWM所使用的一些量
- sbit key1=P1^1;
- sbit key2=P1^2;
- uchar zkb,w;// zkb指占空比
- void delay1m(uchar x)//MS級延時函數(shù)
- {
- uchar i,j;
- for(i = 0;i < x;i++) //連續(xù)x次,約 x ms
- for(j=0;j<120;j++); //數(shù)120 次,約1 ms
- }
- void keyscan() //鍵盤掃描
- {
- P1=0XFF;
- while(1)
- {
- if(key1==0)
- {
- delay1m(5);
- if(key1==0)
- {
- if(zkb<10)
- {
- zkb++;
- zkb++;
- }
- while(!key1);
- }
- }
- if(key2==0)
- {
- delay1m(5);
- if(key2==0)
- {
- if(zkb>0)
- {
- zkb--;
- }
- while(!key2);
- }
- }
- }
- }
- void init_display() //初始顯示0.0.0.0
- {
- uchar i;
- for(i = 0;i < 4;i++)
- {
- wei = bitcode[num - 1];
- duan = display1[buf1[num--]];
- delay1m(1);
- if(num == 0)num = 4;
- }
- }
- void time0_int0_init() //定時器0和外部中斷0的初始化函數(shù)
- {
- TMOD |= 0x11;
- TH1=(65536-10)/256;
- TL1=(65536-10)%256;
- TL0 = (65536 - 5000) % 256;//12M晶振,5ms定時
- TH0 = (65536 - 5000) / 256;
- IT0 = 1;//外部中斷0,負(fù)跳變觸發(fā)方式
- TR0 = 0;
- ET0 = 1;
- EX0 = 1;
- EA = 1;
- ET1=1;
- TR1=1;
- }
- void display_function() //顯示函數(shù)
- {
- if(flag == 0)//顯示速度
- {
- switch(point1)
- {
- case 0:wei = bitcode[num-1];
- duan = display1[buf1[num-1]];
- num--;
- break;//速度顯示 0
- case 1:if(num == 1)
- { wei = bitcode[num-1];
- duan = 0x7f&display1[buf1[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf1[num-1]];
- num--;
- }
- break;//最高位小數(shù)點亮
- case 2:if(num == 2)
- {
- wei = bitcode[num-1];
- duan = 0x7f&display1[buf1[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf1[num-1]];
- num--;
- }
- break;//第二高位小數(shù)點亮
- case 3:if(num == 3)
- {
- wei = bitcode[num-1];
- duan = 0x7f&display1[buf1[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf1[num-1]];
- num--;
- }
- break;//第三高位小數(shù)點亮
- default:break;
- }
- if(num == 0)num = 4;
- }
- else if(flag == 1)//顯示里程
- {
- switch(point2)
- {
- case 0:wei = bitcode[num-1];
- duan = display1[buf2[num-1]];
- num--;
- break;//里程顯示 0
- case 1:if(num == 1)
- {
- wei = bitcode[num-1];
- duan = 0x7f&display1[buf2[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf2[num-1]];
- num--;
- }
- break;//最高位小數(shù)點亮
- case 2:if(num == 2)
- {
- wei = bitcode[num-1];
- duan = 0x7f&display1[buf2[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf2[num-1]];
- num--;
- }
- break;//第二高位小數(shù)點亮
- case 3:if(num == 3)
- {
- wei = bitcode[num-1];
- duan = 0x7f&display1[buf2[num-1]];
- num--;
- }
- else
- {
- wei = bitcode[num-1];
- duan = display1[buf2[num-1]];
- num--;
- }
- break;//第三高位小數(shù)點亮
- default:break;
- }
- if(num == 0)num = 4;
- }
- }
- //====================================主函數(shù)=========================================================
- void main()
- {
- time0_int0_init();//定時器0和外部中斷0的初始化
- while(!TR0) //上電一直未切割時就顯示 0.0.0.0
- {
- init_display();
- }
- zkb=4;
- while(1)
- {
- keyscan();
- if(!change)//按下切換按鍵顯示里程
- {
- delay1m(5);
- if(!change)
- {
- flag = ~flag;
- }
- while(!change);
- }
- }
- }
- //==================================定時器0中斷函數(shù)================================
- void time0_interrupt() interrupt 1
- {
- TL0 = (65536 - 5000) % 256;// 12M晶振,5ms定時
- TH0 = (65536 - 5000) / 256;
- display_function();
- time_counter++;
- time_counter8++;
- if(time_counter8 >= 1600)//大于8s沒切割,車子視為停下了,速度為:0,但里程還記著
- {
- time_counter8 = 0;
- speed = 0;//速度為 0
- point1 = 0;
- buf1[3] = speed%10; //顯示數(shù)組賦值
- buf1[2] = speed/10%10;
- buf1[1] = speed/100%10;
- buf1[0] = speed/1000%10;
- }
- }
- void time1() interrupt 3 //定時器1中斷函數(shù)
- {
- TH1=(65536-10)/256;
- TL1=(65536-10)%256;
- ++w;
- if(w>10)
- {
- w=0;
- };
- if(w<=zkb)
- {
- PWM=1;
- }
- else PWM=0;
- }
- //==================================外部中斷0中斷函數(shù)=========================
- void int0_interrupt()interrupt 0
- {
- external_counter++;
- if(external_counter ==1 )TR0 = ~TR0; //第一次切割打開定時器0
- if(external_counter == 65535)external_counter = 0;
- time_counter8 = 0; //只要8秒內(nèi)有切割,車子就一直在運行
- if(external_counter % 10 == 0)//切割10次 更新下速度
- { //*5是因為中斷一次是5MS
- if(flag1==0) //第一次切割更新速度
- {
- speed =((ulong)(36000)*zhouchang)/(time_counter * 5);
- flag1=1;
- }
- else if(flag1==1){speed =((ulong)(36000)*10*zhouchang)/(time_counter * 5);} //不是第一次切割
- if((speed >= 100)&&(speed < 1000)) //100 ---- 1000 3位整數(shù)
- {
- point1 = 1;
- buf1[3] = speed%10;
- buf1[2] = speed/10%10;
- buf1[1] = speed/100%10;
- buf1[0] = 0;
- }
- else if((speed >= 1000)&&(speed < 10000)) //1000 ---- 10000 4位整數(shù)
- {
- point1 = 1;
- speed = (uint)speed;
- buf1[3] = speed%10;
- buf1[2] = speed/10%10;
- buf1[1] = speed/100%10;
- buf1[0] = speed/1000%10;
- }
- else if((speed >= 10000)&&(speed < 100000)) //10000 ----- 100000 5位整數(shù)
- {
- point1 = 2;
- buf1[3] = speed/10%10;
- buf1[2] = speed/100%10;
- buf1[1] = speed/1000%10;
- buf1[0] = speed/10000%10;
- }
- else if((speed >= 100000)&&(speed < 1000000)) //100000 ------ 1000000 6位整數(shù)
- {
- point1 = 3;
- buf1[3] = speed/100%10;
- buf1[2] = speed/1000%10;
- buf1[1] = speed/10000%10;
- buf1[0] = speed/100000%10;
- }
- time_counter = 0;
- }
- if(external_counter % 10 == 0)//每切割10次 更新下里程
- {
- s = (ulong)external_counter * zhouchang; //里程:單位為 cm
- if((s >= 1000)&&(s < 10000))
- {
- point2 = 1; // 0.012 001212
- buf2[3] = s/100%10;
- buf2[2] = s/1000%10;
- buf2[1] = 0;
- buf2[0] = 0;
- }// 4位整數(shù)
- else if((s >= 10000)&&(s < 100000))
- {
- point2 = 1;
- buf2[3] = s/100%10;
- buf2[2] = s/1000%10;
- buf2[1] = s/10000%10;
- buf2[0] = 0;
- }// 5位整數(shù) 0.123 012345
- else if((s >= 100000)&&(s < 1000000))
- {
- point2 = 1;
- buf2[3] = s/100%10;
- buf2[2] = s/1000%10;
- buf2[1] = s/10000%10;
- buf2[0] = s/100000%10;
- } // 6位整數(shù) 1.234 1234 56
- else if((s >= 1000000)&&(s < 10000000))
- {
- point2 = 2;
- buf2[3] = s/1000%10;
- buf2[2] = s/10000%10;
- buf2[1] = s/100000%10;
- buf2[0] = s/1000000%10;
- }// 7位整數(shù) 1234 567
- else if((s >= 10000000)&&(s < 100000000))
- {
- point2 = 3;
- buf2[3] = s/10000%10;
- buf2[2] = s/100000%10;
- buf2[1] = s/1000000%10;
- buf2[0] = s/10000000%10;
- } // 8位整數(shù) 1234 5678
- }
- }
復(fù)制代碼
|
|