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);
} |