自行车速度里程测量,使用的是外部中断0计数里程脉冲,定时器0计算时间
PWM调速,使用定时器1产生PWM波形
两个程序单独使用都没问题,
但是合在一起,两个定时器一起用就出现问题,错误首先在数码管位选端出现流水灯效果,第一次切割后恢复正常,没有了流水灯效果,速度测量失效。里程测量还能用
附程序代码:
- //速度:单位为 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}; //数码管驱动信号0---9,共阳
- uchar code bitcode[]={0x7f,0xbf,0xdf,0xef}; //数码管位选扫描信号 0111 1111
- sbit change = P3^4; //切换按键
- bit flag = 1; //切换标记
- bit flag1=0; //第一次切割
- uchar point1 = 0; //小数点标记,速度
- uchar buf1[]={0,0,0,0}; //数码管该显示的数字,高-----低,速度
- uchar point2 = 0; //小数点标记,里程
- uchar buf2[]={0,0,0,0}; //数码管该显示的数字,高------低,里程
- uchar num = 4; //数码管第num位
- uint time_counter = 0; //每10次切割时差,定时计数
- uint time_counter8 = 0; //8s定时计数
- uint external_counter = 0; //外部中断计数
- 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级延时函数
- {
- uchar i,j;
- for(i = 0;i < x;i++) //连续x次,约 x ms
- for(j=0;j<120;j++); //数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的初始化函数
- {
- TMOD |= 0x11;
- TH1=(65536-10)/256;
- TL1=(65536-10)%256;
- TL0 = (65536 - 5000) % 256;//12M晶振,5ms定时
- TH0 = (65536 - 5000) / 256;
- IT0 = 1;//外部中断0,负跳变触发方式
- TR0 = 0;
- ET0 = 1;
- EX0 = 1;
- EA = 1;
- ET1=1;
- TR1=1;
- }
- void display_function() //显示函数
- {
- 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;//最高位小数点亮
- 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;//第二高位小数点亮
- 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;//第三高位小数点亮
- 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;//最高位小数点亮
- 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;//第二高位小数点亮
- 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;//第三高位小数点亮
- default:break;
- }
- if(num == 0)num = 4;
- }
- }
- //====================================主函数=========================================================
- 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中断函数================================
- 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; //显示数组赋值
- buf1[2] = speed/10%10;
- buf1[1] = speed/100%10;
- buf1[0] = speed/1000%10;
- }
- }
- void time1() interrupt 3 //定时器1中断函数
- {
- TH1=(65536-10)/256;
- TL1=(65536-10)%256;
- ++w;
- if(w>10)
- {
- w=0;
- };
- if(w<=zkb)
- {
- PWM=1;
- }
- else PWM=0;
- }
- //==================================外部中断0中断函数=========================
- 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秒内有切割,车子就一直在运行
- 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位整数
- {
- 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位整数
- {
- 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位整数
- {
- 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位整数
- {
- 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位整数
- 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位整数 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位整数 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位整数 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位整数 1234 5678
- }
- }
复制代码
|