|
lkc8210 發(fā)表于 2022-3-18 19:18
代碼呢?
#define uchar unsigned char
#define uint unsigned int //宏定義
//頭函數(shù)聲明
#include <reg52.h> //包含頭文件
#include "Lcd.h" //液晶函數(shù)
#include "Data.h" //計算每個月最多多少天的函數(shù)
#include "DS1302.h" //時鐘芯片程序
#include "AT24C02.h" //AT24C02函數(shù)
//鍵盤定義
sbit K1=P3^4; //模式切換
sbit K2=P3^6; //減速鍵
sbit K3=P3^5; //加速鍵
sbit K4=P3^7; //萬年歷模式時;設(shè)置時間信息。計價器模式時:設(shè)置單價
//模式0時鐘 1時鐘調(diào)整
uchar Mode=0;
//時鐘屏幕調(diào)整
uchar Wei=0;
uchar SS=0;
//價格調(diào)整
uchar JGWei=0;
//計價器參數(shù)
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; //計數(shù)變量
uchar m=0; //定時器計時變量
//白天/晚上
uchar DN=0; //白天還是晚上切換變量
//公里/時間
uchar GT=0; //走公里還是時間的切換變量
//初始化函數(shù)
void InitTimer0();
//寫初值
void SETS();
//讀初值
void READS();
//主函數(shù)
void main()
{
//初始化 Ds1302_Init(); //時鐘芯片
Init_LCD(); //液晶的初始化
initeeprom(); //EEPROM初始化
//SETS();
//讀取初始參數(shù)
READS();
//定時器初始化
InitTimer0();
//循環(huán)
while(1) //進入循環(huán)
{
//時鐘模式
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) //設(shè)置按鍵按下
{
delay(100); //延時去抖
if(K4==0) //再次判斷按鍵是否按下
{
if(Mode==0) //調(diào)時模式
{
Wei++; //設(shè)置時間的位置加一,也就是依次調(diào)節(jié)年月日時分秒等數(shù)據(jù)
if(Wei==1) //進入設(shè)置時間數(shù)據(jù)后
{
SS=1; //閃爍變量置1,閃爍對應(yīng)位置
}
display_NYR(time_buf1,Wei,SS); //顯示時間、設(shè)置的位和閃爍的狀態(tài)
if(Wei==7) //當(dāng)設(shè)置最后一位后
{
Wei=0; //位數(shù)據(jù)清零,退出設(shè)置時間狀態(tài)
Ds1302_Write_Time(); //保存時間
Init_LCD(); //初始化液晶屏
}
}
else if(Mode==1) //調(diào)計價器價格
{
JGWei++; //價格的位加
if(JGWei==1) //進入價格位設(shè)置狀態(tài)后
{
Mode=2; //模式等于2,進入計價器單價設(shè)置狀態(tài)
Init_LCD_JGTZ(); //初始化價格設(shè)置界面
display_D(Day,Night,DanJia,JGWei,DJ_min); //顯示計價器價格
}
}
else if(Mode==2) //模式等于2時,也就是進入單價設(shè)置狀態(tài)
{
JGWei++; //價格位加
display_D(Day,Night,DanJia,JGWei,DJ_min); //顯示白天夜晚、單價、價格位、分鐘等價等數(shù)據(jù)
if(JGWei==5) //價格位加到5時
{
Mode=1; //退出價格位設(shè)置,到計價器模式
JGWei=0; //設(shè)置的價格位置清零
SETS(); //保存
READS(); //讀初值
ZJ=0; //總價清零
GL=0; //公里數(shù)清零
Time=0; //低速時間清零
TR0=1; //開啟定時器 Init_LCD_JJQ(); //顯示計價器 }
}
while(K4==0); //按鍵釋放
}
}
//+
if(K3==0) //加按鍵按下
{
delay(100); //延時去抖 if(K3==0) //再次判斷按鍵按下
{
if(Mode==0) //調(diào)時
{
//年位置
if(Wei==1)
{
time_buf1[1]++; //年數(shù)據(jù)加
if(time_buf1[1]>=100) //加到100
time_buf1[1]=0; //清零
}
//月
else if(Wei==2)
{
time_buf1[2]++; //月數(shù)據(jù)加
if(time_buf1[2]>=13) //加到13月
time_buf1[2]=1; //變成1月份
}
//日
else if(Wei==3) //日數(shù)據(jù)
{
time_buf1[3]++; //日數(shù)據(jù)加
if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1) //輸入年月日數(shù)據(jù),返回每個月的最大天數(shù)
time_buf1[3]=1; //達到最大天數(shù),日期清零
}
//時
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); //顯示所有數(shù)據(jù)
}
//單價
else if(Mode==2) //調(diào)節(jié)計價器單價
{
//單價
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); //顯示計價器各參數(shù)
}
while(K3==0); //按鍵釋放
}
}
//-
if(K2==0) //減按鍵,注釋略,基本同上
{
delay(100);
if(K2==0)
{
//調(diào)時 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);
}
//調(diào)價
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) //當(dāng)前是計價器模式
{
Mode=0; //切換到時鐘模式
ZJ=0;
GL=0; //總價和公里數(shù)清零
Time=0; //等待時間清零
//關(guān)閉定時器
TR0=0;
EX0=0;
//顯示計價器
Init_LCD();
}
else if(Mode==0) //當(dāng)前是時鐘模式
{
Mode=1; //切換到計價器模式
//參數(shù)初始化
//讀數(shù)據(jù)
READS(); //讀取保存在EEPROM內(nèi)的單價數(shù)據(jù)
ZJ=0;
GL=0; //總價、公里數(shù)和等待時間變量清零
Time=0;
//開啟定時器
m=0;
TR0=1;
EX0=1;
//顯示計價器
Init_LCD_JJQ();
}
while(K1==0);
}
}
}
}
//初始化函數(shù)
void InitTimer0(void)
{
TMOD = 0x01; //定時器0打開
TH0 = 0x3C;
TL0 = 0xB0; //50ms
EA = 1; //打開中斷總開關(guān)
ET0 = 1; //打開中斷允許開關(guān)
TR0 = 1; //打開定時器定時開關(guān)
IT0=1; //INT0負跳變觸發(fā)
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轉(zhuǎn)就是高速模式,計公里數(shù)
{
GT=0; //記公里模式
GL=GL+count/10; //公里數(shù)累加,沒有公式,就是把旋轉(zhuǎn)的圈數(shù)除以10得到接近真實大小的數(shù)據(jù)
count=0; //轉(zhuǎn)數(shù)清零
}
else //檢測電機的脈沖,一秒鐘小于100轉(zhuǎn)就是低速模式,計時間計費
{
count=0; //轉(zhuǎn)數(shù)清零
GT=1; //等待時間計時模式
Time++; //時間++
}
}
//計算錢數(shù)
//公里數(shù)小于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 //公里數(shù)大于3公里
{
if(DN==0) //白天
{
/*
GL計到200就是2km,因為是超過3km開始按照單價收費那么在3.1km時就要顯示4km的價格,所以就要在超過300時加一個單價的價格。
超過3km要收費,顯示3.1km時就應(yīng)該顯示起步價+第一個單價了,但是 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 //外部中斷,檢測電機的轉(zhuǎn)速
{
count++; //電機轉(zhuǎn)一圈,此變量加1
}
//讀數(shù)值
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; //高八位暫存數(shù)據(jù)左移8位
temp=temp+SL; //左移后的數(shù)據(jù)加上低八位的數(shù)據(jù)組成一個16位的數(shù)據(jù)
Day=temp; //將這個16位數(shù)據(jù)轉(zhuǎn)移到白天起步價的變量內(nèi)
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,將高八位數(shù)據(jù)去掉,得到低八位賦值給SL
SH=temp>>8; //將temp右移八位,將高八位數(shù)據(jù)賦值給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);
} |
|