📄 串口+8个键盘程序.c
字号:
#include<reg51.h>
#include<intrins.h>
#include<string.h>
#define comm 0
#define dat 1
#define uchar unsigned char
#define uint unsigned int
#define x1 0x80
#define x2 0x88
#define y 0x80
sbit Key_Hang0=P2^0;
sbit Key_Hang1=P2^1;
sbit Key_Lie0=P2^2;
sbit Key_Lie1=P2^3;
sbit Key_Lie2=P2^4;
sbit Key_Lie3=P2^5;
sbit Speaker=P2^7;
sbit cs = P1^0;
sbit std = P1^1;
sbit sclk = P1^2;
sbit psb = P1^3; //H=并口; L=串口;
sbit rst = P1^4; //Reset Signal 低电平有效
sbit led = P1^7; //Reset Signal 低电平有效
char send;
char tar[]={'D'};
#define MENULEVEL 7 //当前菜单表个数
#define OPTIONMETE 29 //当前选项个数,包括一个特别功能选项
//-------------------------------------
//
// 菜单结构定义
//
//-------------------------------------
struct Option{
unsigned char KeyLevel; //菜单选项所属菜单表号
unsigned char EnterIndex; //选项进入索引号
unsigned char CancelIndex; //选项退出索引号
unsigned char KeyWord[16]; //菜单选项文字描述数组
unsigned char WordMete; //菜单选项描述文字字节数
};
//-------------------------------------
//
// 具体菜单选项定义,定义一个结构数组
// 存储在编码区,节省内存RAM
//
//-------------------------------------
struct Option code sOption[OPTIONMETE] = {
// KeyLevel, EnterIndex, CancelIndex, KeyWord[16], WordMete//
//菜单选项所属菜单表号
//选项进入索引号
//选项退出索引号
//菜单选项文字描述数组
//菜单选项描述文字字节数
{0,9,0,"文本功能",8}, //0---------------------------9往下数9组数据就是"文本功能"
{0,16,1,"时间功能",8}, //1
{0,19,2,"温度功能",8}, //2
{0,OPTIONMETE-1,3,"系统检测",8}, //3
{0,OPTIONMETE-1,4,"修改密码",8}, //4
{0,OPTIONMETE-1,5,"帮助说明",8}, //5
{0,OPTIONMETE-1,6,"作者介绍",8}, //6
{0,OPTIONMETE-1,7,"系统版本",8}, //7
{0,OPTIONMETE-1,8,"退出系统",8}, //8
{1,OPTIONMETE-1,0,"输入显示向导",12}, //9------------------------------------"文本功能"
{1,OPTIONMETE-1,0,"新建显示文本",12}, //10
{1,OPTIONMETE-1,0,"文本发送显示",12}, //11
{1,OPTIONMETE-1,0,"删除已存文本",12}, //12
{1,14,0,"输入法设定",10}, //13
{2,OPTIONMETE-1,13,"输入法选择",10}, //14
{2,OPTIONMETE-1,13,"输入法排序",10}, //15
{3,OPTIONMETE-1,1,"设定本机时间",12}, //16-----------------------------------"时间功能"
{3,OPTIONMETE-1,1,"发送本机时间",12}, //17
{3,OPTIONMETE-1,1,"与计算机同步时间",16}, //18
{4,23,2,"显示当前温度",12}, //19-----------------------------------------"温度功能"
{4,OPTIONMETE-1,2,"存储当前温度",12}, //20
{4,OPTIONMETE-1,2,"显示已存温度",12}, //21
{4,OPTIONMETE-1,2,"删除已存温度",12}, //22
{5,25,19,"本机显示",8}, //23
{5,OPTIONMETE-1,19,"子机显示",8}, //24
{6,OPTIONMETE-1,23,"LED 显示",8}, //25
{6,OPTIONMETE-1,23,"数码管显示",10}, //26
{6,OPTIONMETE-1,23,"同时显示",8}, //27
{0,0,0,"",0} //28
};
//--------------------------------------
//
// 菜单表分类数组
//
//--------------------------------------
unsigned char code Level[MENULEVEL][3] = {
//每层表单对应 开始 结束 索引号 以及 选项数目
{0,8,9},
{9,13,5},
{14,15,2},
{16,18,3},
{19,22,4},
{23,24,2},
{25,27,3}
//SelectIndex
};
uchar ii,jj;
unsigned char FirstLineDisIndex = 0; //屏幕第一行显示的索引号
unsigned char SelectLine = 1; //当前选择的行
unsigned char SelectIndex = 0; //当前选定行对应的索引号
unsigned char LastIndex = 0; //进入功能函数前的索引号,判断具体功能使用
void send_sub(unsigned char send_data); //发送函数
void key_delay(int delay_time);
void GetKeyCode (void);
void start_init();
char KeyCodeConvert(char send);
void MenuReflash (void);
void MenuCancelOption (void);
void MenuEnterOption (void);
void FunctionAction (void);
void TemperatureShow(void);
void NoThisFunction (void);
void MenuCancelOption(void);
void ShutDown (void);
void MenuDownOneOption (void);
void MenuUpOneOption (void);
bit MenuLevelEnd (void);
bit MenuLevelStart (void); //判断当前索引是否为当前层第一个选项
void DIS12864M (void);
void wr_lcd (char dat_comm,char content);
void SentAIns(char LCD_Comand); //进入液晶普通指令模式
void SentAData(char LCD_Data);
void con_disp (uchar data1,uchar data2,uchar x0,uchar y0,uchar xl,uchar yl);
void SetALineReverse (char SelectLine); //填充所需反白
void delay (uint us); //delay time
void init_lcd ();
void Disp_String(uint a,uint b,uchar *dd);
void lat_disp (uchar data1,uchar data2);
//--------------------------------------------------------------------------------------
main()
{
start_init();
init_lcd ();
DIS12864M();
//lat_disp (0x00,0x00);
//con_disp(0xff,0xff,0x80,0x80,4,16);///反白
//SetALineReverse (SelectLine); //填充所需反白
while(1)
{ //key ();
MenuReflash (); //菜单更新函数
if(send)
{
send_sub( send);
send=0;
}
}
}
void send_sub(unsigned char send_data) //发送函数
{
TI=0;
EA=0;
ACC=send_data;
SBUF=ACC;
while(TI==0); //wait for sended
send_data=0x00; //clear send
TI=0;
EA=1;
}
void GetKeyCode()
{
Key_Hang0=0;
_nop_();
if(!Key_Lie0)
{
key_delay(5);
while(!Key_Lie0)
{Speaker=1;
send=0x08;
}
Speaker=0;
}
if(!Key_Lie1)
{
key_delay(5);
while(!Key_Lie1)
{ Speaker=1;
send=0x07;
}
Speaker=0;
}
//scan no2
if(!Key_Lie2)
{
key_delay(5);
while(!Key_Lie2)
{Speaker=1;
send=0x06;
}
Speaker=0;
}
if(!Key_Lie3)
{
key_delay(5);
while(!Key_Lie3)
{Speaker=1;
send=0x05;
}
Speaker=0;
}
Key_Hang0=1;
Key_Hang1=0;
_nop_();
if(!Key_Lie0)
{
key_delay(5);
while(!Key_Lie0)
{Speaker=1;
send=0x4;
}
Speaker=0;
}
if(!Key_Lie1)
{
key_delay(5);
while(!Key_Lie1)
{Speaker=1;
send=0x03;
}
Speaker=0;
}
//scan no2
if(!Key_Lie2)
{
key_delay(5);
while(!Key_Lie2)
{Speaker=1;
send=0x02;
}
Speaker=0;
}
if(!Key_Lie3)
{
key_delay(5);
while(!Key_Lie3)
{ Speaker=1;
send=0x01;
}
Speaker=0;
}
Key_Hang1=1;
}
//----------------------------------------
//
// 刷新菜单功能函数
// 函数原形:void DIS12864M (void);
// 没有参数,没有返回值
// 调用方式:void DIS12864M (void);
//
//----------------------------------------
void DIS12864M (void)
{
unsigned char i,LineMete = Level[sOption[SelectIndex].KeyLevel][2]; //循环量,显示行数
SentAIns(0x30); //进入液晶普通指令模式
SentAIns(0x01); //清屏
do //分别显示各行菜单项
{//必须先显示汉字再反显,否则屏幕上是乱码
SentAIns(0x80);//------------------------ 行1
for(i=0;i<sOption[FirstLineDisIndex].WordMete;i++)//传达多少个字符 每显示4行FirstLineDisIndex+1
SentAData(sOption[FirstLineDisIndex].KeyWord[i]);//字符串数组首地址
if(--LineMete == 0) break;//行--
SentAIns(0x90); //------------------------ 行2
for(i=0;i<sOption[FirstLineDisIndex+1].WordMete;i++)
SentAData(sOption[FirstLineDisIndex+1].KeyWord[i]);
if(--LineMete == 0) break;
SentAIns(0x88); //------------------------ 行3
for(i=0;i<sOption[FirstLineDisIndex+2].WordMete;i++)
SentAData(sOption[FirstLineDisIndex+2].KeyWord[i]);
if(--LineMete == 0) break;
SentAIns(0x98); //------------------------ 行4
for(i=0;i<sOption[FirstLineDisIndex+3].WordMete;i++)
SentAData(sOption[FirstLineDisIndex+3].KeyWord[i]);
}while(0);
lat_disp (0x00,0x00);
SetALineReverse (SelectLine); //填充所需反白
}
//----------------------------------------
//
// 判断当前索引是否是表单第一项功能函数
// 函数原形:bit MenuLevelStart (void);
// 没有参数,返回Bit标志,是第一项返回1,不是返回0
// 调用方式:bit MenuLevelStart (void);
//
//----------------------------------------
bit MenuLevelStart (void) //判断当前索引是否为当前层第一个选项
{
unsigned char i = MENULEVEL;// MENULEVEL存放的是当前菜单表个数=7;
do
{
i--;
if(SelectIndex == Level[i][0]) return 1;// SelectIndex存放的是当前选定行对应的索引号
}while(i); //为1说明是第一个菜单
return 0;
}
//----------------------------------------
//
// 判断当前索引是否是表单最后一项功能函数
// 函数原形:bit MenuLevelEnd (void);
// 没有参数,返回Bit标志,是最后一项返回1,不是返回0
// 调用方式:bit MenuLevelEnd (void);
//
//----------------------------------------
bit MenuLevelEnd (void)
{
unsigned char i = MENULEVEL; // MENULEVEL存放的是当前菜单表个数=7;
do
{
i--;
if(SelectIndex == Level[i][1]) return 1;
}while(i);
return 0;
}
//----------------------------------------
//
// 菜单上移一项函数
// 函数原形:void MenuUpOneOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuUpOneOption (void);
//
//----------------------------------------
void MenuUpOneOption (void)
{
if(MenuLevelStart ()) //如果当前为表单第一项MenuLevelStart ()==1是第一项
{//因为128X64最多显示4行,大于等于4个的要分两次以上显示
if(Level[sOption[SelectIndex].KeyLevel][2]>=4)//表单中选项数目大于等于4个,取Level[n][2]第n行的第三个数据
{
FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][1]-3; //第一行显示索引号为倒数第四项
SelectIndex = Level[sOption[SelectIndex].KeyLevel][1]; //选择索引为表单最后一项
SelectLine = 4; //标记选择行为第四行
DIS12864M (); //刷新屏幕显示
}
else //如果选项数目并不大于四个
{//因为128X64最多显示4行,小于等于4个的要一次显示
SelectIndex = Level[sOption[SelectIndex].KeyLevel][1]; //选择索引为当前表单最后一个
SelectLine = Level[sOption[SelectIndex].KeyLevel][2]; //显示行表单数目(最后一个)
DIS12864M (); //刷新屏幕显示
}
}
else //如果当前不是开始索引
{
if(SelectLine==1) //并且已经在屏幕最上边一行
{
FirstLineDisIndex--; //显示索引上移
SelectIndex--; //选择索引自减
SelectLine = 1; //选择行还是第一行
DIS12864M (); //刷新屏幕
}
else //如果不是第一行
{
SelectLine--; //选择行自减
SelectIndex--; //选择索引自减
DIS12864M (); //刷新屏幕显示
}
}
}
//----------------------------------------
//
// 菜单下移一项函数
// 函数原形:void MenuDownOneOption (void);
// 没有参数,没有返回值
// 调用方式:void MenuDownOneOption (void);
//
//----------------------------------------
void MenuDownOneOption (void)
{
if(MenuLevelEnd ()) //如果当前是表单最后一个索引
{
FirstLineDisIndex = Level[sOption[SelectIndex].KeyLevel][0]; //第一行显示索引为表单第一个选项9
SelectIndex = Level[sOption[SelectIndex].KeyLevel][0]; //选择索引为表单第一个选项索引
SelectLine = 1; //选择行为第一行
DIS12864M (); //刷新显示
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -