📄 lcd.c
字号:
// Copyright (c)2005 - 2006 by Laser Electronics, All Rights Reserved.
/*----------------------------------------------------------------------------+
| File Name: LCD.c, v1.0.1 |
| Author: 安徽雷森电子有限公司合肥研发中心 |
| Date: 2005年08月01日 |
+-----------------------------------------------------------------------------+
| Description: 联网型智能楼宇对讲系统 -- 管理中心机LCD显示屏驱动程序 |
| 器件选择 -- STC89C58RD+, PQFP-44 |
| 时钟频率 -- 24.000 MHz |
+-----------------------------------------------------------------------------+
/*----------------------------------------------------------------------------+
| Include files |
+----------------------------------------------------------------------------*/
#include "Main.h"
#include "LCD.h"
#include "Timer.h"
#include "KeyProcess.h"
#include <stdio.h>
/*----------------------------------------------------------------------------+
| Type Definition & Macro |
+----------------------------------------------------------------------------*/
#define LcdCLK P1_2
#define LcdSDI P1_3
#define LcdCS P1_4
/*----------------------------------------------------------------------------+
| Global Variables |
+----------------------------------------------------------------------------*/
// 显示缓冲,第一个字节最低位表示是否需要刷新显示,最高位表示是否反白显示
idata BYTE DispBuffer[2][DISP_BUF_LENGTH+1];
xdata BYTE MainLogo[DISP_BUF_LENGTH];
/*----------------------------------------------------------------------------+
| Internal Variables |
+----------------------------------------------------------------------------*/
bit FirstLineReverseDisp; // 第一行是否反白显示
bit SecondLineReverseDisp; // 第二行是否反白显示
code BYTE BlankLine[16] = " ";
// 设置菜单
code t_Menu SetupMenu[16] =
{
// Caption,NextMenu,Parent,Child,MenuFunction
// 通过父菜单来指示各个不级的菜单,使之能够在同一级菜单中上下翻页
// 数组的第一项菜单为总菜单,用来指示菜单项的第一行,实际上并不显示
/* 0 */ " ", 0, 0, 1, NULL,
/* 1 */ "1.设置系统时间 ", 2, 0, 0, EnterSetupSystemTime,
/* 2 */ "2.设置管理员密码", 3, 0, 0, EnterSetupSystemPassword,
/* 3 */ "3.增加刷卡用户 >", 4, 0, 7, NULL,
/* 4 */ "4.删除刷卡用户 >", 5, 0, 9, NULL,
/* 5 */ "5.系统参数设置 >", 6, 0,12, NULL,
/* 6 */ "6.返回 ", 1, 0, 0, ReturnIdle,
// 增加刷卡用户的子菜单
/* 7 */ "1.通过刷卡 ", 8, 3, 0, EnterAddTempCardByCard,
/* 8 */ "2.通过输入卡号 ", 7, 3, 0, EnterAddTempCardByNum,
// 删除刷卡用户的子菜单
/* 9 */ "1.通过刷卡 ", 10, 4, 0, EnterDelTempCardByCard,
/*10 */ "2.通过输入卡号 ", 11, 4, 0, EnterDelTempCardByNum,
/*11 */ "3.删除所有过期卡", 9, 4, 0, EnterDelTimeoutCard,
// 系统参数设置
/*12 */ "1.设置双击间隔 ", 13, 5, 0, EnterSetupDoubleClickTime,
/*13 */ "2.设置轮询时间 ", 14, 5, 0, EnterSetupCheckIntervalTime,
/*14 */ "3.与计算机同步 ", 12, 5, 0, NULL,
/*15 */ " ", 0, 0, 0, NULL,
};
/*----------------------------------------------------------------------------+
| General Subroutines |
+----------------------------------------------------------------------------*/
//
// 初始化LCD显示器,配置相应的寄存器
void InitLCD(void)
{
FirstLineReverseDisp = FALSE;
SecondLineReverseDisp = FALSE;
LcdWriteControlData(0x30); // 功能设定为扩充指令集 0x30
LcdWriteControlData(0x06); // 设定光标移动方向
LcdWriteControlData(0x0D); // 显示状态开关, 不显示光标
LcdWriteControlData(0x14); // 设定游标的移动与显示的移位控制位元,右移
LcdWriteControlData(0x01); // 清除显示
LcdWriteControlData(0x02); // 显示位置清零
}
//
// 初始化显示缓冲,根据当前不同的状态而显示不同的内容
// bForce: 是否需要更新第一行的内容
void InitDispBuffer(BOOL bForce)
{
BYTE i;
//*/
switch (SystemStatus.Status)
{
case Status_Init: // 系统正在初始化
{
memcpy(&DispBuffer[0][1], "正在启动 ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "请稍侯... ", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_Idle: // 平常情况
{
if (bForce)
{
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[0][1], MainLogo, DISP_BUF_LENGTH); // 显示公司标志
}
if (KeyBuffer[0] == 0x00) // 按键缓冲区为空,则显示当前时间
{
// 显示时间
UpdateTimeBuffer(&DispBuffer[1][1]);
DispBuffer[1][0] = 0x01;
}
else // 按键缓冲区非空,则显示按键缓冲区的内容
{
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);
// 更新显示缓冲
for (i=1; i<=KeyBuffer[0]; i++)
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = KeyBuffer[i]+0x30;
}
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_ViewBefore: // 按下监视键之后的界面
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请输入单元号码:", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], "监视:__栋__单元", DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将按键的值显示在屏幕上
{
DispBuffer[1][ViewBeforeDispOrder[i]] = KeyBuffer[i]+0x30;
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_ViewSendingRequest:
{
memcpy(&DispBuffer[0][1], &DispBuffer[1][1], DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "等待对方应答... ", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_Viewing:
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "正在监视: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], " __栋__单元", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_CallBefore: // 按下"呼叫"键之后的界面
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请输入房间号码:", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], "呼叫:__栋____房", DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将按键的值显示在屏幕上
{
DispBuffer[1][CallBeforeDispOrder[i]] = KeyBuffer[i]+0x30;
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_CallSendingRequest:
{
memcpy(&DispBuffer[0][1], &DispBuffer[1][1], DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "等待对方应答... ", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_Talking: // 正在通话
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "正在通话: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
if (ConnectingAddr[3] == 0x00) // 正在和门口机进行通话
{
memcpy(&DispBuffer[1][1], " __栋__单元", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
}
else // 正在和室内分机进行通话
{
memcpy(&DispBuffer[1][1], " __栋____房", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
}
break;
}
case Status_Calling: // 正在呼叫分机
{
memcpy(&DispBuffer[0][1], "正在呼叫: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], " __栋____房", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_bCallingIn_F: // 正在被室内机呼叫
{
memcpy(&DispBuffer[0][1], "用户呼叫: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "来自:__栋____房", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_bCallingIn_M: // 正在被门口机呼叫
{
memcpy(&DispBuffer[0][1], "单元门口呼叫: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "来自:__栋__单元", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupEnterPassword:
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请输入密码: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将之前输入的密码,用'*'表示具体的数字
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = '*';
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupMenu: // 设置菜单界面
{
if (SystemStatus.lParam == 0)
{
SystemStatus.lParam = SetupMenu[0].Child;
}
i = SystemStatus.lParam;
memcpy(&DispBuffer[0][1], SetupMenu[i].Caption, DISP_BUF_LENGTH);
i = SetupMenu[i].NextMenu;
memcpy(&DispBuffer[1][1], SetupMenu[i].Caption, DISP_BUF_LENGTH);
// 决定哪一行需要反白显示
if (SystemStatus.wParam == 0x01) // 选中第一行
{
DispBuffer[0][0] = 0x81;
DispBuffer[1][0] = 0x01;
}
else if (SystemStatus.wParam == 0x02) // 选中第二行
{
DispBuffer[0][0] = 0x01;
DispBuffer[1][0] = 0x81;
}
else // 都没有选中,意外情况
{
SystemStatus.wParam = 0x00;
DispBuffer[0][0] = 0x01;
DispBuffer[1][0] = 0x01;
}
break;
}
case Status_SetupTime: // 设置时间的界面
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "修改时间: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], "20__-__-__ __:__", DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将按键的值显示在屏幕上
{
DispBuffer[1][SetupTimeDispOrder[i]] = KeyBuffer[i]+0x30;
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupPasswordBefore: // 设置密码前面的输入管理员密码,正确之后才可以设置新的密码
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请输入当前密码: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将之前输入的密码,用'*'表示具体的数字
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = '*';
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupPasswordFirst: // 设置密码时第一次输入的界面
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请输入新密码: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将之前输入的密码,用'*'表示具体的数字
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = '*';
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupPasswordVerify: // 设置密码时第二次输入的界面
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请确认新密码: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);
for (i=1; i<=KeyBuffer[0]; i++) // 将之前输入的密码,用'*'表示具体的数字
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = '*';
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupAddTempCardByCard: // 通过刷卡增加刷卡用户
case Status_SetupDelTempCardByCard: // 通过刷卡删除用户/////////////////////////////////////////////////
{
if (bForce)
{
memcpy(&DispBuffer[0][1], "请刷卡: ", DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
}
memcpy(&DispBuffer[1][1], &BlankLine, DISP_BUF_LENGTH);//
for (i=1; i<=KeyBuffer[0]; i++)
{
DispBuffer[1][DISP_BUF_LENGTH-KeyBuffer[0]+i] = KeyBuffer[i]+0x30;
}
DispBuffer[1][0] = 0x01;
break;
}
case Status_SetupAddTempCardByNum: // 通过输入卡号增加刷卡用户///////////////////////////////////
case Status_SetupDelTempCardByNum: // 通过输入卡号删除刷卡用户
{
if (bForce)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -