lkc8210 发表于 2022-3-21 15:44 我用的proteus 7.8版本。仿真的。直接程序导入的 |
zhangdingjun 发表于 2022-3-19 23:27 不会吧~? ![]() 把下面那位置截出来看看 ![]() |
lkc8210 发表于 2022-3-19 22:49 这就是我的全部程序了 |
把Lcd.h和Lcd.c(如果有的话)也贴出来呀~! |
lkc8210 发表于 2022-3-18 19:18 #define uchar unsigned char #define uint unsigned int //宏定义 //头函数声明 #include <reg52.h> //包含头文件 #include "Lcd.h" //液晶函数 #include "Data.h" //计算每个月最多多少天的函数 #include "DS1302.h" //时钟芯片程序 #include "AT24C02.h" //AT24C02函数 //键盘定义 sbit K1=P3^4; //模式切换 sbit K2=P3^6; //减速键 sbit K3=P3^5; //加速键 sbit K4=P3^7; //万年历模式时;设置时间信息。计价器模式时:设置单价 //模式0时钟 1时钟调整 uchar Mode=0; //时钟屏幕调整 uchar Wei=0; uchar SS=0; //价格调整 uchar JGWei=0; //计价器参数 uint Day=0; //白天起步价 uint Night=0; //夜间起步价 uint DanJia=0; //单价 uint DJ_min=0; //每分钟单价 uint ZJ=0; //总价 unsigned long GL=0; //公里 uint Time=0; //时间变量 uint count=0; //计数变量 uchar m=0; //定时器计时变量 //白天/晚上 uchar DN=0; //白天还是晚上切换变量 //公里/时间 uchar GT=0; //走公里还是时间的切换变量 //初始化函数 void InitTimer0(); //写初值 void SETS(); //读初值 void READS(); //主函数 void main() { //初始化 Ds1302_Init(); //时钟芯片 Init_LCD(); //液晶的初始化 initeeprom(); //EEPROM初始化 //SETS(); //读取初始参数 READS(); //定时器初始化 InitTimer0(); //循环 while(1) //进入循环 { //时钟模式 if(Mode==0) { if(Wei==0) { Ds1302_Read_Time(); //读时间 display_NYR(time_buf1,Wei,0); //显示时间 } } else if(Mode==1) //计价器模式 { if(time_buf1[4]>=23||time_buf1[4]<7) //时间23点到7点之前是夜间模式 DN=1; else //其余时间是白天模式 DN=0; display_S(Day,Night,DanJia,ZJ,GL/10,Time,GT,DN); //显示计价器 } if(K4==0) //设置按键按下 { delay(100); //延时去抖 if(K4==0) //再次判断按键是否按下 { if(Mode==0) //调时模式 { Wei++; //设置时间的位置加一,也就是依次调节年月日时分秒等数据 if(Wei==1) //进入设置时间数据后 { SS=1; //闪烁变量置1,闪烁对应位置 } display_NYR(time_buf1,Wei,SS); //显示时间、设置的位和闪烁的状态 if(Wei==7) //当设置最后一位后 { Wei=0; //位数据清零,退出设置时间状态 Ds1302_Write_Time(); //保存时间 Init_LCD(); //初始化液晶屏 } } else if(Mode==1) //调计价器价格 { JGWei++; //价格的位加 if(JGWei==1) //进入价格位设置状态后 { Mode=2; //模式等于2,进入计价器单价设置状态 Init_LCD_JGTZ(); //初始化价格设置界面 display_D(Day,Night,DanJia,JGWei,DJ_min); //显示计价器价格 } } else if(Mode==2) //模式等于2时,也就是进入单价设置状态 { JGWei++; //价格位加 display_D(Day,Night,DanJia,JGWei,DJ_min); //显示白天夜晚、单价、价格位、分钟等价等数据 if(JGWei==5) //价格位加到5时 { Mode=1; //退出价格位设置,到计价器模式 JGWei=0; //设置的价格位置清零 SETS(); //保存 READS(); //读初值 ZJ=0; //总价清零 GL=0; //公里数清零 Time=0; //低速时间清零 TR0=1; //开启定时器 Init_LCD_JJQ(); //显示计价器 } } while(K4==0); //按键释放 } } //+ if(K3==0) //加按键按下 { delay(100); //延时去抖 if(K3==0) //再次判断按键按下 { if(Mode==0) //调时 { //年位置 if(Wei==1) { time_buf1[1]++; //年数据加 if(time_buf1[1]>=100) //加到100 time_buf1[1]=0; //清零 } //月 else if(Wei==2) { time_buf1[2]++; //月数据加 if(time_buf1[2]>=13) //加到13月 time_buf1[2]=1; //变成1月份 } //日 else if(Wei==3) //日数据 { time_buf1[3]++; //日数据加 if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1) //输入年月日数据,返回每个月的最大天数 time_buf1[3]=1; //达到最大天数,日期清零 } //时 else if(Wei==4) { time_buf1[4]++; //小时加 if(time_buf1[4]>=24) //加到24 time_buf1[4]=0; //小时等于0 } //分 else if(Wei==5) //以下注释略 { time_buf1[5]++; if(time_buf1[5]>=60) time_buf1[5]=0; } //秒 else if(Wei==6) { time_buf1[6]++; if(time_buf1[6]>=60) time_buf1[6]=0; } //显示 if(Wei!=0) display_NYR(time_buf1,Wei,SS); //显示所有数据 } //单价 else if(Mode==2) //调节计价器单价 { //单价 if(JGWei==1) { DanJia++; //单价加 if(DanJia>999) //加到999 { DanJia=1; //置1 } } //± else if(JGWei==2) { DJ_min++; if(DJ_min>999) { DJ_min=1; } } // else if(JGWei==3) { Night++; if(Night>999) { Night=1; } } //°×ì else if(JGWei==4) { Day++; if(Day>999) { Day=1; } } display_D(Day,Night,DanJia,JGWei,DJ_min); //显示计价器各参数 } while(K3==0); //按键释放 } } //- if(K2==0) //减按键,注释略,基本同上 { delay(100); if(K2==0) { //调时 if(Mode==0) { //年 if(Wei==1) { time_buf1[1]--; if(time_buf1[1]<0) time_buf1[1]=99; } //月 else if(Wei==2) { time_buf1[2]--; if(time_buf1[2]<=0) time_buf1[2]=12; } //日 else if(Wei==3) { time_buf1[3]--; if(time_buf1[3]<=0) time_buf1[3]=YDay(time_buf1[1],time_buf1[2]); } //时 else if(Wei==4) { time_buf1[4]--; if(time_buf1[4]<0) time_buf1[4]=23; } //分 else if(Wei==5) { time_buf1[5]--; if(time_buf1[5]<0) time_buf1[5]=59; } //秒 else if(Wei==6) { time_buf1[6]--; if(time_buf1[6]<0) time_buf1[6]=59; } //显示 if(Wei!=0) display_NYR(time_buf1,Wei,SS); } //调价 else if(Mode==2) { //单价 if(JGWei==1) { DanJia--; if(DanJia==0) { DanJia=999; } } //等待时间单价 else if(JGWei==2) { DJ_min--; if(DJ_min==0) { DJ_min=999; } } //夜间 else if(JGWei==3) { Night--; if(Night==0) { Night=999; } } //白天 else if(JGWei==4) { Day--; if(Day==0) { Day=999; } } display_D(Day,Night,DanJia,JGWei,DJ_min); } while(K2==0); } } //切换 if(K1==0) //切换时钟模式和计价器模式 { delay(100); if(K1==0) { if(Mode==1) //当前是计价器模式 { Mode=0; //切换到时钟模式 ZJ=0; GL=0; //总价和公里数清零 Time=0; //等待时间清零 //关闭定时器 TR0=0; EX0=0; //显示计价器 Init_LCD(); } else if(Mode==0) //当前是时钟模式 { Mode=1; //切换到计价器模式 //参数初始化 //读数据 READS(); //读取保存在EEPROM内的单价数据 ZJ=0; GL=0; //总价、公里数和等待时间变量清零 Time=0; //开启定时器 m=0; TR0=1; EX0=1; //显示计价器 Init_LCD_JJQ(); } while(K1==0); } } } } //初始化函数 void InitTimer0(void) { TMOD = 0x01; //定时器0打开 TH0 = 0x3C; TL0 = 0xB0; //50ms EA = 1; //打开中断总开关 ET0 = 1; //打开中断允许开关 TR0 = 1; //打开定时器定时开关 IT0=1; //INT0负跳变触发 EX0=0;//开外部INTO中断 } //定时器0中断50ms void Timer0Interrupt(void) interrupt 1 { TH0 = 0x3C; TL0 = 0xB0; //赋初值 m++; //每过50ms m变量加1 if(m>=20) //加20次就是1000ms,就是1s { m=0; //清零 if(count>=100) //检测电机的脉冲,一秒钟超过100转就是高速模式,计公里数 { GT=0; //记公里模式 GL=GL+count/10; //公里数累加,没有公式,就是把旋转的圈数除以10得到接近真实大小的数据 count=0; //转数清零 } else //检测电机的脉冲,一秒钟小于100转就是低速模式,计时间计费 { count=0; //转数清零 GT=1; //等待时间计时模式 Time++; //时间++ } } //计算钱数 //公里数小于3 if(GL<=300) { if(DN==0) //白天 { if(Time>60) //低速的时间超过1分钟(60s) ZJ=Day+Time/60*DJ_min; //总价就是白天的起步价+时间乘以等待单价 else //高速 ZJ=Day; //总价就是起步价 } else //夜间 { if(Time>60) //低速的时间超过一分钟(60s) ZJ=Night+Time/60*DJ_min;//总价就是夜间的起步价+时间乘以等待的单价 else //高速 ZJ=Night; //总价就是夜间的起步价 } } else //公里数大于3公里 { if(DN==0) //白天 { /* GL计到200就是2km,因为是超过3km开始按照单价收费那么在3.1km时就要显示4km的价格,所以就要在超过300时加一个单价的价格。 超过3km要收费,显示3.1km时就应该显示起步价+第一个单价了,但是 3.1km如果减去3km的话,剩下的0.1不到1,所以就计算总价时,少减一个,就是减2。 所以计算下面的价格时要GL/10-20 */ if(Time>60) //低速的时间超过一分钟(60s) ZJ=Day+(GL/10-20)/10*DanJia+Time/60*DJ_min; //总价=白天起步价+(公里/10-20)/10*单价+时间+等待时间单价 else //高速 ZJ=Day+(GL/10-20)/10*DanJia; //总价=白天起步价+(公里/10-20)/10*单价+单价 } else //注释同上 { if(Time>60) ZJ=Night+(GL/10-20)/10*DanJia+Time/60*DJ_min; else ZJ=Night+(GL/10-20)/10*DanJia; } } } void EXINT0() interrupt 0 //外部中断,检测电机的转速 { count++; //电机转一圈,此变量加1 } //读数值 void READS() //读取EEPROM初值 { uchar SH=0,SL=0; uint temp=0; //定义变量 delay(10); //延时 SL=read_add(0x01); //读取白天起步价的低八位 delay(10); SH=read_add(0x02); //读取白天起步价的高八位 temp=SH; //高八位先暂存 temp=temp<<8; //高八位暂存数据左移8位 temp=temp+SL; //左移后的数据加上低八位的数据组成一个16位的数据 Day=temp; //将这个16位数据转移到白天起步价的变量内 delay(10); //一下注释略 SL=read_add(0x03); delay(10); SH=read_add(0x04); temp=SH; temp=temp<<8; temp=temp+SL; Night=temp; //夜间起步价 delay(10); SL=read_add(0x05); delay(10); SH=read_add(0x06); temp=SH; temp=temp<<8; temp=temp+SL; DanJia=temp; //单价 delay(10); SL=read_add(0x07); delay(10); SH=read_add(0x08); temp=SH; temp=temp<<8; temp=temp+SL; DJ_min=temp; //等待时间单价 } // void SETS() { uchar SH=0,SL=0; uint temp=0; //注释变量 temp=Day; //白天起步价变量赋值到temp准备存储 SL=temp&0x00ff; //temp按位与上0x00ff,将高八位数据去掉,得到低八位赋值给SL SH=temp>>8; //将temp右移八位,将高八位数据赋值给SH delay(10); write_add(0x01,SL); //存储低八位 delay(10); write_add(0x02,SH); //存储高八位 temp=Night; //一下注释略 SL=temp&0x00ff; SH=temp>>8; delay(10); write_add(0x03,SL); delay(10); write_add(0x04,SH); temp=DanJia; SL=temp&0x00ff; SH=temp>>8; delay(10); write_add(0x05,SL); delay(10); write_add(0x06,SH); temp=DJ_min; SL=temp&0x00ff; SH=temp>>8; delay(10); write_add(0x07,SL); delay(10); write_add(0x08,SH); } |
代码呢? |