单片机里程和速度表仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51单片机里程和速度显示源程序如下:
- #define cystal4MHz
- #include <reg51.h>
- #include <string.h>
- #include "systimer.h"
- #include "lcd.h"
- #include "math.h"
- #include "keytask.h"
- uchar first_start=0;
- uchar timer1=0;//用于进度的显示效果
- uchar timer_100ms=0;
- uchar LCDBacklightOff_delay=11;
- uchar LCDBacklightOff_timer=0;
- unsigned char IsSet=0; /*设置模式标志位 0:正常走时 1:设置模式*/
- unsigned char SetSelect=0; /*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/
-
- /**************************************/
- uchar time,timer_10ms;
- uchar months,monthend,days=1,months=1,seconds,minutes,hours,year=10,second;
- uchar menu=0,menu_flag;//界面
- /**************************************/
- uchar seconds_bike,minutes_bike,hours_bike;
- uchar temp_work;//运动标志
- uchar kilometer,kilometer_oneway;//运动千里、运动(米)
- float total_distance;//总里程
- unsigned long total_time;//总时间
- float meter,meter_oneway;//单程距离
- uchar temp_work_over;//单程结束标志
- uchar timer_10ms_1=0;//运动时间计数单位
- uint timer_10ms_2=0;//外部运行时间计数单位
- uchar timer_work_1,timer_work;//
- float speed_max=60,speed,speed_ave=0;// 最大速度、瞬时速度、平均速度
- float k,l;
- uchar r=26;//轮胎的半径
- uchar speed_max_int, speed_max_dec ;//最大速度的整数部分和小数部分
- uchar speed_int,speed_dec; //瞬时速度的整数部分和小数部分
- uchar speed_ave_int,speed_ave_dec; //平均速度的整数部分和小数部分
- uint meter_int,meter_dec; //里程的整数部分和小数部分
- uchar meter_oneway_int,meter_oneway_dec;//里程的整数部分和小数部分
- uchar timer_work_2;//外部输入标志
- float work_time_t1;//外界输入时间(轮胎运行一圈的时间)
- uchar temp3,temp4;
- uchar NewKey1,NewKey2,NewKey3;
- uchar shuru_flag;
- unsigned data Temp1 = 0;
- unsigned char c = 0;
- unsigned char d = 0;
- unsigned a[4]; //温度数值存放
- uchar code ditab[16]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
- //uchar work_time_t1_int,work_time_t1_dec;//运动时间的整数部分和小数部分
- /**************************************/
- void Init_date(void) //日期算法
- {
- switch(months)
- {
- case 1: monthend = 31;break;
- case 2: if(year % 4 == 0)
- monthend = 29;
- else monthend = 28; break;
- case 3: monthend = 31; break;
- case 4: monthend = 30; break;
- case 5: monthend = 31; break;
- case 6: monthend = 30; break;
- case 7: monthend = 31; break;
- case 8: monthend = 31; break;
- case 9: monthend = 30; break;
- case 10: monthend = 31;break;
- case 11: monthend = 30; break;
- case 12: monthend = 31; break;
- }
- if(days == monthend)
- {
- days = 1;
- months++;
- if(months > 12)
- {
- months = 1;
- year++;
- }
- }
- }
- void Init_Clock_bike(void) //时间算法
- {
- if(timer_10ms_1>=100)
- {
- timer_10ms_1=0;
- seconds_bike++;
- if(seconds_bike == 60)
- {
- seconds_bike = 0;
- minutes_bike++;
- if(minutes_bike ==60)
- {
- minutes_bike=0;
- hours_bike++;
- }
- }
- }
- }
-
- void set_date(void) //日期设置
- {
- switch(months)
- {
- case 1: monthend = 31;break;
- case 2: if(year % 4 == 0)
- monthend = 29;
- else monthend = 28;break;
- case 3: monthend = 31; break;
- case 4: monthend = 30; break;
- case 5: monthend = 31; break;
- case 6: monthend = 30; break;
- case 7: monthend = 31; break;
- case 8: monthend = 31; break;
- case 9: monthend = 30; break;
- case 10: monthend = 31; break;
- case 11: monthend = 30; break;
- case 12: monthend = 31; break;
- }
- if(days == monthend+1)
- {
- days = 1;
- }
- if(days<1)
- {
- days=monthend;
- }
- if(months>12)
- {
- months=1;
- }
- if(months<1)
- {
- months=12;
- }
- if(year>99)
- {
- year=0;
- }
- if(year<0)
- {
- year=99;
- }
- }
- void Set_time(void) //时间设置
- {
- if(hours==24)
- {
- hours=0;
- }
- if(hours<0)
- {
- hours=23;
- }
- if(minutes==60)
- {
- minutes=0;
- }
- if(minutes<0)
- {
- minutes=59;
- }
- if(seconds==60)
- {
- seconds=0;
- }
- if(seconds<0)
- {
- seconds=59;
- }
- }
- void Init_Clock(void) //时间算法
- {
- if(seconds == 60)
- {
- seconds = 0;
- minutes++;
- if(minutes == 60)
- {
- minutes = 0;
- hours++;
- if(hours == 24)
- {
- hours = 0;
- days++;
- Init_date();//日期算法嵌套
- }
- }
- }
- }
- void task_shuru(void)
- {
- if(shuru==0)
- {
- shuru_flag = 1;
- }
- }
- void display_one(void)//第一个界面
- {
- DisplaySinglByte(1,0,2+0x30);
- DisplaySinglByte(1,1,0+0x30);
- DisplaySinglByte(1,2,year/10+0x30);
- DisplaySinglByte(1,3,year%10+0x30);
- DisplaySinglByte(1,4,' ');
- DisplaySinglByte(1,5,months / 10+0x30);
- DisplaySinglByte(1,6,months % 10+0x30);
- DisplaySinglByte(1,7,' ');
- DisplaySinglByte(1,8,days / 10+0x30);
- DisplaySinglByte(1,9,days % 10+0x30);
- DisplaySinglByte(1,10,' ');
- DisplaySinglByte(1,11,hours / 10+0x30);
- DisplaySinglByte(1,12,hours%10+0x30);
- if(timer_10ms>=50)
- {
- DisplaySinglByte(1,13,':');
- }
- if(timer_10ms<50)
- {
- DisplaySinglByte(1,13,' ');
- }
- DisplaySinglByte(1,14,minutes / 10+0x30);
- DisplaySinglByte(1,15,minutes % 10+0x30);
-
- /************************显示速度**************/
-
- speed_int = (int)speed;
- speed_dec = (int)((speed -(float)speed_int)*100);
-
- if(speed_int/100>0)
- {
- DisplaySinglByte(2,0,speed_int/100+0x30);
- }
- else
- {
- DisplaySinglByte(2,0,' ');
- }
- if(speed_int/10>0)
- {
- DisplaySinglByte(2,1,speed_int/10%10+0x30);
- }
- else
- {
- DisplaySinglByte(2,1,' ');
- }
- DisplaySinglByte(2,2,speed_int%10+0x30);
- DisplaySinglByte(2,3,'.');
- DisplaySinglByte(2,4,speed_dec/10+0x30);
- // DisplaySinglByte(2,5,speed_dec%10+0x30);
- DisplaySinglByte(2,5,' ');
- DisplaySinglByte(2,6,a[1]+0x30);
- DisplaySinglByte(2,7,a[2]+0x30);
- DisplaySinglByte(2,8,'.');
- DisplaySinglByte(2,9,a[3]+0x30);
- /************************显示里程**************/
- meter_int = (int)meter;
- meter_dec = (int)((meter -(float)meter_int)*100);
- //DisplaySinglByte(2,10,kilometer/100+0x30);
- if(kilometer==0)
- {
- // DisplaySinglByte(2,10,kilometer%100/10+0x30);
- DisplaySinglByte(2,11,kilometer%10+0x30);
- DisplaySinglByte(2,12,'.');
- DisplaySinglByte(2,13,meter_int/100+0x30);
- DisplaySinglByte(2,14,meter_int%100/10+0x30);
- DisplaySinglByte(2,15,meter_int%10+0x30);
- }
- if(kilometer>0)
- {
- if(kilometer/100>0)
- {
- DisplaySinglByte(2,10,kilometer/100+0x30);
- }
- else
- {
- DisplaySinglByte(2,10,' ');
- }
- if(kilometer/10>0)
- {
- DisplaySinglByte(2,11,kilometer%100/10+0x30);
- }
- else
- {
- DisplaySinglByte(2,11,' ');
- }
- DisplaySinglByte(2,12,kilometer%10+0x30);
- DisplaySinglByte(2,13,'.');
- DisplaySinglByte(2,14,meter_int/100+0x30);
- DisplaySinglByte(2,15,meter_int%100/10+0x30);
- //DisplaySinglByte(2,15,meter_int%10+0x30);
- }
- /***********************************************/
- }
- void display_two()//第二个界面显示
- {
- /************************显示最大速度**************/
- speed_max_int = (int)speed_max;
- speed_max_dec = (int)((speed_max -(float)speed_max_int)*100);
- if(speed_max_int/100>0)
- {
- DisplaySinglByte(1,0,speed_max_int/100+0x30);
- }
- else
- {
- DisplaySinglByte(1,0,' ');
- }
- if(speed_max_int%100/10>0)
- {
- DisplaySinglByte(1,1,speed_max_int%100/10+0x30);
- }
- else
- {
- DisplaySinglByte(1,1,' ');
- }
- DisplaySinglByte(1,2,speed_max_int%10+0x30);
- DisplaySinglByte(1,3,'.');
- DisplaySinglByte(1,4,speed_max_dec/10+0x30);
- DisplaySinglByte(1,5,'k');
- DisplaySinglByte(1,6,'m');
- DisplaySinglByte(1,7,'/');
- DisplaySinglByte(1,8,'h');
- DisplaySinglByte(1,9,' ');
- DisplaySinglByte(1,10,' ');
- DisplaySinglByte(1,11,'R');
- DisplaySinglByte(1,12,'=');
- DisplaySinglByte(1,13,r/10+0x30);
- DisplaySinglByte(1,14,r%10+0x30);
- DisplaySinglByte(1,15,' ');
- DisplaySinglByte(2,0,' ');
- DisplaySinglByte(2,1,' ');
- DisplaySinglByte(2,2,' ');
- DisplaySinglByte(2,3,' ');
- DisplaySinglByte(2,4,' ');
- DisplaySinglByte(2,5,' ');
- DisplaySinglByte(2,6,' ');
- DisplaySinglByte(2,7,' ');
- DisplaySinglByte(2,8,' ');
- DisplaySinglByte(2,9,' ');
- DisplaySinglByte(2,10,' ');
- DisplaySinglByte(2,11,' ');
- DisplaySinglByte(2,12,' ');
- DisplaySinglByte(2,13,' ');
- DisplaySinglByte(2,14,' ');
- DisplaySinglByte(2,15,' ');
-
- }
- /*******************************/
- /**************************************/
- void main(void)
- {
- TMOD = 0x21;
- SCON = 0x50;
- set_bps
- //
- TH0 = 0x70;
- TL0 = 0x00;
- TR0 = 1;
- P2 = 0xff;
- //
- // WDI = ~WDI;
- // WDI = ~WDI;
- // WDI = ~WDI;
- HaveKey=0xff;
- //sheld init
- InitLCD();
- // LCDBacklightDelay=back_light_delay;
- // LCDBacklightOn;
- // LCDBacklightOn;
- //BuzzerOn;
- //BzrDelay = 5;
- //打开中断
- IP=0x10; //中断优先级// PT0 = 0; PS = 1;
- TR1 = 1;
- ES = 1;
- ET0 = 1;
- EA = 1;
- //
- while(1)
- {
- //计时器
-
- WDI = 0;//便于观察
- KeyProcessTask();
- task_shuru();
- ReadTemperature();
- ChangeTemp();
- if(HaveKey==1)
- {
- if( menu== 0)
- {
- switch (SetSelect)
- {
- case SECOND:
- seconds++;
- if(hours==60)
- {
- hours=0;
- }
- timer_10ms=0;
- HaveKey=0;
- break;
- case MINUTE:
- minutes++;
- timer_10ms=0;
- HaveKey=0;
- break;
- case HOUR:
- hours++;
- timer_10ms=0;
- HaveKey=0;
- break;
- case DAY: set_date();
- days++;
- timer_10ms=0;
- set_date();
- HaveKey=0;
- break;
- case MONTH:
- months++;
- timer_10ms=0;
- HaveKey=0;
- break;
- case YEAR:
- year++;
- timer_10ms=0;
- HaveKey=0;
- break;
- }
- }
- if( menu== 1)
- {
- switch (IsSet)
- {
- case MAX:
- if(speed_max<200)
- {
- speed_max++;
- }
- HaveKey=0;
- break;
- case R:
- if(r<50)
- {
- r++;
- }
- timer_10ms=0;
- HaveKey=0;
- break;
- }
- }
- }
- if(HaveKey==2)
- {
- if(menu==0)
- {
- switch (SetSelect)
- {
- case SECOND:
- seconds--;
- if(seconds==-1)
- {
- seconds=59;
- }
- Set_time();
- timer_10ms=0;
- HaveKey=0;
- break;
- case MINUTE:
- minutes--;
- if(minutes==-1)
- {
- minutes=59;
- }
- Set_time();
- timer_10ms=0;
- HaveKey=0;
- break;
- case HOUR:
- hours--;
- if(hours==-1)
- {
- hours=23;
- }
- Set_time();
- timer_10ms=0;
- HaveKey=0;
- break;
- case DAY: set_date();
- days--;
- timer_10ms=0;
- set_date();
- HaveKey=0;
- break;
- case MONTH:
- months--;
- timer_10ms=0;
- set_date();
- HaveKey=0;
- break;
- case YEAR:
- year--;
- timer_10ms=0;
- set_date();
- HaveKey=0;
- break;
- }
- }
- if( menu== 1)
- {
- switch (IsSet)
- {
- case MAX:
- if(speed_max>0)
- {
- speed_max--;
- }
- HaveKey=0;
- break;
- case R:
- if(r>0)
- {
- r--;
- }
- timer_10ms=0;
- HaveKey=0;
- break;
- }
- }
- }
-
- if(HaveKey==3)
- {
- timer_10ms=0;
- if(menu== 1)
- {
- if(IsSet>0)
- {
- IsSet--; /*设置位的标志变量SetSelect=0:时位 1:分位 2:秒位*/
- }
- if(IsSet==0) /*按到第四次,即设置完秒位后,将标志位IsSet置0,完成设置*/
- {
- IsSet=R;
- }
- }
- if(SetSelect>0)
- {
- SetSelect--; /*设置位的标志变量SetSelect=0:时位 1:分位 2:秒位*/
- }
- if(SetSelect==0) /*按到第四次,即设置完秒位后,将标志位IsSet置0,完成设置*/
- {
- SetSelect=YEAR;
- }
- HaveKey=0;
- }
- if(HaveKey==4)//界面切换
- {
- menu_flag++;
- if(menu==0)
- {
- menu = 1;
- HaveKey=0;
- }
- if(menu==1&&menu_flag==2)
- {
- menu = 0;
- menu_flag=0;
- HaveKey=0;
- }
-
- }
- if(HaveKey==5)
- {
- if(temp_work_over ==0)
- {
- temp_work=1;
- kilometer_oneway=0;
- meter_oneway = 0;
- }
- temp_work_over=1;
- HaveKey=0;
- }
- if(HaveKey==6)
- {
- temp_work=0;
- temp_work_over =0;
- HaveKey=0;
- }
- if(shuru_flag==1)
- {
- if(shuru==1)
- {
- work_time_t1 = (float)timer_10ms_2*10;
- if(work_time_t1>0)
- {
- speed = 3.14*(float)r*2.54/work_time_t1*36;
- }
- timer_10ms_2 = 0;
- work_time_t1 = 0;
- timer_work_2 = 1;//计两个外部输入的时间差
- timer_work_1 = 1;//开始计运动时间
- meter = meter+3.14*2.54*r/100;
- if(temp_work==1)
- {
- meter_oneway = meter_oneway+3.14*2.54*r/100;
- }
- shuru_flag=0;
- }
- }
-
- /*第二次按C键设置分位,第三次按键设置秒位,第四次按键完成退出设置*/
- if(menu == 0)
- {
- display_one();//显示第一个界面
- }
- if(menu == 1)
- {
- display_two();//显示第二个界面
- }
- if(meter >=1000)//里程进位
- {
- kilometer++;
- meter = meter -1000;
- }
-
- if(speed > speed_max)//判断是否为最大速度
- {
- alarmon;
- }
- if(speed < speed_max)//判断是否为最大速度
- {
- alarmoff;
- }
- total_distance=(float)kilometer*1000+meter;
- total_time= seconds_bike +minutes_bike*60+hours_bike*3600;
- if(total_time>0)
- {
- speed_ave = ((float)total_distance/(float)total_time)*3.6;
- }
- if(timer_10ms>=100)
- {
- seconds++;
- timer_10ms=0;
- }
- Init_Clock();
- Init_Clock_bike();
- if(timer_10ms_2 >=300) //3秒没有第二次信号输入当超时,速度为0
- {
- timer_work_2 = 0;
- timer_work_1 = 0;
- timer_10ms_2 = 0;
- speed=0;
- }
- // WDI = 1;
- //休眠
- //休眠
- PCON|=0x01;
- }
- }
-
- /* ------------------------------------------------------------------------------
- [ interrupt [0x0B] void T0_int (void) ]
- [ comment: 定时器TO中断服务程序,定时给主循环发送20ms间隔消息 ]
- ------------------------------------------------------------------------------ */
- void T0_int (void) interrupt 1//[0x0B] //定时器T0 20ms 定时
- {
- TR0 = 0;
- set_timer
- TR0 = 1;
- timer_10ms++;
- if(timer_work_1==1)//运动时间标志
- {
- timer_10ms_1++;
- }
- if(timer_work_2==1)//外部输入计时标志
- {
- timer_10ms_2++;
- }
- }
- //双变量延时
- /*void Delay(unsigned x,unsigned y)
- {
- int i,j;
-
- for(i=0;i<x;i++)
- for(j=0;j<y;j++);
- }*/
-
-
-
- //温度数值的转换
- void ChangeTemp()
- {
- if(d==15)
- {
- a[0] = 10;
- }
- else
- {
- a[0] = 11;
- }
-
- a[1] = Temp1 / 10;
- a[2] = Temp1 % 10;
- a[3] = ditab[c];
- }
-
-
- //显示函数
- /*void DisPlay()
- {
- ChangeTemp();
- P1 = tab[HaveKey];
- P0 = tab[dis_buff[1]];
-
- }*/
-
- //显示定时器
- /*void INT_T0() interrupt 1 using 0
- {
- TH0 = 0xDC;
- TL0 = 0xB0;
- // ReadTemperature();
- //DisPlay();
- }*/
-
-
- /*------------------------------温度传感器子程序--------------------------*/
-
- void Delay1(unsigned int i)
- {
- while(i--);
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
姚伟业余爱好.zip
(131.86 KB, 下载次数: 39)
|