功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示有四个状态
a) 时间显示
b) 时间设置
c) 计价器显示
d) 计价器设置
2.按键切换四个不同显示状态
3.默认为时间显示状态,长按’切换‘键切换至计价器模式
4.在时间显示状态下按‘设置’键可设置时间
5.在计价器显示状态下按’设置‘键可进入收费标准设置
6.设定值支持掉电保护
7.上电过程中按下“设置”键可重置参数
8.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
//头函数声明
#include <reg52.h>
#include "lcd.h"
#include "date.h"
#include "ds1302.h"
#include "at24c02.h"
#define DISP_TIME 0
#define DISP_PRICE 1
#define DISP_AJUST_PRICE 2
//键盘定义
sbit KEY_MODE = P3^5; //模式切换
sbit KEY_SUB = P3^6; //减按键
sbit KEY_ADD = P3^4; //加按键
sbit KEY_SET = P3^3; //万年历模式时:设置时间信息。计价器模式时:设置单价
unsigned char mode = DISP_TIME;
//时钟屏幕调整
unsigned char setTimeLocation = 0; //设定时间位置
unsigned char setFlag = 0; //设置标志
//价格调整
unsigned char setPriceLocation = 0; //设定价格位置
//计价器参数
unsigned int dayFlagfallPrice = 2; //白天起步价
unsigned int nightFlagfallPrice = 10; //夜晚起步价
unsigned int distUnitPrice = 3; //公里价格
unsigned int timeUnitPrice = 1; //时间价格
unsigned int totalPrice = 0; //总价
unsigned long dist = 0; //单位:0.01公里
unsigned long distkm = 0; //单位:公里
long timeOneSecond = 0; //单位:秒
long timeOneMinute = 0; //单位:分
unsigned int exintCnt = 0; //计数
unsigned char time50ms = 0; //50ms计数
unsigned int g_cnt = 0; //计数
bit isNightFlag = 0; //是否为夜晚
bit isTimeFlag = 1; //时间显示标志
bit isStartFlag = 0; //启动标志
//初始化定时器0
void InitTimer0();
//初始化定时器1
void InitTimer1();
//写初值到EEPROM
void Sets();
//从EEPROM读初值
void Reads();
//按键扫描
void KeyScan();
//价钱计算
void PriceCalc();
//初始化参数
void InitParam();
//主函数
void main()
{
//初始化
DS1302_Init();
InitEEPROM();
//Sets();
//定时器初始化
InitTimer0();
InitTimer1();
if (KEY_SET == 0) //初始化参数
{
DelayMs(20);
if (KEY_SET == 0)
{
Sets();
DS1302_Write_Time();
}
while(KEY_SET == 0);
}
else
{
Reads(); //读取初始参数
}
Init_LCD();
IT0 = 1; //INT0负跳变触发
EX0 = 0; //关闭外部中断
EA = 1; //打开总中断
//循环
while(1)
{
//时钟模式
if (mode == DISP_TIME)
{
TR1 = 0;
//读时间
if (setTimeLocation == 0)
{
//显示时间
DS1302_Read_Time();
Display_NYR(timeBufDec, setTimeLocation, 0);
}
}
else if (mode == DISP_PRICE)
{
TR1 = 1;
if (isStartFlag == 1)
{
TR0 = 1;
EX0 = 1;
}
else
{
TR0 = 0;
EX0 = 0;
}
if (timeBufDec[4] >= 23 || timeBufDec[4] < 7) //夜晚时间:23:00~7:00
{
isNightFlag = 1; //夜晚
}
else
{
isNightFlag = 0;
}
if (g_cnt % 10 == 0) //500ms更新一次数据
{
PriceCalc();
Display_S(distUnitPrice, timeUnitPrice, totalPrice, dist / 10, timeOneSecond, isTimeFlag); //显示计价器信息
}
}
KeyScan();
}
}
//按键扫描处理
void KeyScan()
{
unsigned int keyCnt = 0;
if (KEY_SET == 0) //设置键按下
{
DelayMs(100);
//调时
if (KEY_SET == 0)
{
if (mode == DISP_TIME)
{
setTimeLocation++;
if (setTimeLocation == 1)
{
setFlag = 1;
}
// 闪烁
Display_NYR(timeBufDec, setTimeLocation, setFlag);
if (setTimeLocation == 7)
{
setTimeLocation = 0;
// 保存时间
DS1302_Write_Time();
Init_LCD();
}
}
else if (mode == DISP_PRICE)
{
setPriceLocation++;
if (setPriceLocation == 1)
{
mode = DISP_AJUST_PRICE;
// 显示计价器价格
Init_LCD_JGTZ();
Display_D(dayFlagfallPrice, nightFlagfallPrice, distUnitPrice, setPriceLocation, timeUnitPrice);
}
}
// 调价格
else if (mode == DISP_AJUST_PRICE)
{
setPriceLocation++;
Display_D(dayFlagfallPrice, nightFlagfallPrice, distUnitPrice, setPriceLocation, timeUnitPrice);
if (setPriceLocation == 5)
{
mode = DISP_PRICE;
isStartFlag = 0;
InitParam();
setPriceLocation = 0;
// 参数初始化
Sets(); // 保存
Reads(); // 读初值
TH0 = 0x4C; //(65536 - 46080) / 256; //50ms
TL0 = 0x00; //(65536 - 46080) % 256; //50ms
Init_LCD_JJQ(); // 显示计价器
}
}
}
while (KEY_SET == 0);
}
if (KEY_ADD == 0) //加键按下
{
DelayMs(180);
//调时
if (mode == DISP_TIME)
{
//年
if (setTimeLocation == 1)
{
timeBufDec[1]++;
if (timeBufDec[1] >= 100)
timeBufDec[1] = 0;
}
//月
else if (setTimeLocation == 2)
{
timeBufDec[2]++;
if (timeBufDec[2] >= 13)
timeBufDec[2] = 1;
}
//日
else if (setTimeLocation == 3)
{
timeBufDec[3]++;
if (timeBufDec[3] >= YDay(timeBufDec[1], timeBufDec[2]) + 1)
timeBufDec[3] = 1;
}
//时
else if (setTimeLocation == 4)
{
timeBufDec[4]++;
if (timeBufDec[4] >= 24)
timeBufDec[4] = 0;
}
//分
else if (setTimeLocation == 5)
{
timeBufDec[5]++;
if (timeBufDec[5] >= 60)
timeBufDec[5] = 0;
}
//秒
else if (setTimeLocation == 6)
{
timeBufDec[6]++;
if (timeBufDec[6] >= 60)
timeBufDec[6] = 0;
}
//显示
if (setTimeLocation != 0)
Display_NYR(timeBufDec, setTimeLocation, setFlag);
}
//调价
else if (mode == DISP_AJUST_PRICE)
{
//单价
if (setPriceLocation == 1)
{
distUnitPrice++;
if (distUnitPrice > 999)
{
distUnitPrice = 1;
}
}
//等待时间单价
else if (setPriceLocation == 2)
{
timeUnitPrice++;
if (timeUnitPrice > 999)
{
timeUnitPrice = 1;
}
}
//夜间
else if (setPriceLocation == 3)
{
nightFlagfallPrice++;
if (nightFlagfallPrice > 999)
{
nightFlagfallPrice = 1;
}
}
//白天
else if (setPriceLocation == 4)
{
dayFlagfallPrice++;
if (dayFlagfallPrice > 999)
{
dayFlagfallPrice = 1;
}
}
Display_D(dayFlagfallPrice, nightFlagfallPrice, distUnitPrice, setPriceLocation, timeUnitPrice);
}
else if (mode == DISP_PRICE)
{
if (isStartFlag == 0)
{
InitParam();
}
}
// while (KEY_ADD == 0);
}
if (KEY_SUB == 0) //减键按下
{
DelayMs(180);
//调时
if (mode == DISP_TIME)
{
//年
if (setTimeLocation == 1)
{
if (timeBufDec[1] == 0)
timeBufDec[1] = 100;
timeBufDec[1]--;
}
//月
else if (setTimeLocation == 2)
{
timeBufDec[2]--;
if (timeBufDec[2] <= 0)
timeBufDec[2] = 12;
}
//日
else if (setTimeLocation == 3)
{
timeBufDec[3]--;
if (timeBufDec[3] <= 0)
timeBufDec[3] = YDay(timeBufDec[1], timeBufDec[2]);
}
//时
else if (setTimeLocation == 4)
{
if (timeBufDec[4] == 0)
timeBufDec[4] = 24;
timeBufDec[4]--;
}
//分
else if (setTimeLocation == 5)
{
if (timeBufDec[5] == 0)
timeBufDec[5] = 60;
timeBufDec[5]--;
}
//秒
else if (setTimeLocation == 6)
{
if (timeBufDec[6] == 0)
timeBufDec[6] = 60;
timeBufDec[6]--;
}
//显示
if (setTimeLocation != 0)
Display_NYR(timeBufDec, setTimeLocation, setFlag);
}
//调价
else if (mode == DISP_AJUST_PRICE)
{
//单价
if (setPriceLocation == 1)
{
distUnitPrice--;
if (distUnitPrice == 0)
{
distUnitPrice = 999;
}
}
//等待时间单价
else if (setPriceLocation == 2)
{
timeUnitPrice--;
if (timeUnitPrice == 0)
{
timeUnitPrice = 999;
}
}
//夜间
else if (setPriceLocation == 3)
{
nightFlagfallPrice--;
if (nightFlagfallPrice == 0)
{
nightFlagfallPrice = 999;
}
}
//白天
else if (setPriceLocation == 4)
{
dayFlagfallPrice--;
if (dayFlagfallPrice == 0)
{
dayFlagfallPrice = 999;
}
}
Display_D(dayFlagfallPrice, nightFlagfallPrice, distUnitPrice, setPriceLocation, timeUnitPrice);
}
else if (mode == DISP_PRICE)
{
if (isStartFlag == 0)
{
InitParam();
}
}
// while (KEY_SUB == 0);
}
仿真演示视频:
https://www.bilibili.com/video/BV1FP411c7oA/
实物演示视频:
https://www.bilibili.com/video/BV13G411w7LK/