功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示有四个状态
a) 时间显示
b) 时间设置
c) 计价器显示
d) 计价器设置
2.按键切换四个不同显示状态
3.默认为时间显示状态,长按’切换‘键切换至计价器模式
4.在时间显示状态下按‘设置’键可设置时间
5.在计价器显示状态下按’设置‘键可进入收费标准设置
6.设定值支持掉电保护
7.上电过程中按下“设置”键可重置参数
8.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:

PCB :

主程序:
//头函数声明
#include
#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; //50msTL0 = 0x00; //(65536 - 46080) % 256; //50msInit_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/
上一篇:JUC学习笔记——共享模型之无锁
下一篇:问题很多。用什么成语来形容