📄 12864与ps2.c
字号:
#include <at89x51.h>
#include "scancodes.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define Key_Data P3_4 //定义Keyboard引脚
#define Key_CLK P3_3
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define Disp_On 0x3f // 显示开指令 //
#define Disp_Off 0x3e // 显示关指令 //
#define Col_Add 0x40 // 定位到第0列指令 //
#define Page_Add 0xb8 // 定位到第0页指令 //
#define Start_Line 0xc0 // 定位从DDROM中的第0行开始往屏幕上显示 //
void Delay5Ms(void);
void Delay400Ms(void);
void Decode(unsigned char ScanCode);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
unsigned char code Cls[] = {" "};
static unsigned char IntNum = 0; //中断次数计数
static unsigned char KeyV; //键值
static unsigned char DisNum = 0; //显示用指针
static unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识
static unsigned char BF = 0; //标识是否有字符被收到
typedef bit BOOL ;
uchar aa=0x80;
uchar TempCyc;
/***************************-= 控 制 宏 =-**************************************************/
/** 根据你的控制线接法来修改 **/
sbit CS1 = P2^4; // 左屏使能 //
sbit CS2 = P2^6; // 右屏使能 //
sbit E = P2^7; // 使能端 //
sbit RS = P2^3; // 数据或指令寄存器选择端,又名DI //
sbit RW = P2^5; // 读写控制端 //
sbit RST = P2^1; // 复位端 //
sbit sdata = P0; // 数据口 //
unsigned char code a[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 你
宽×高(像素): 16×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/32字节
数据转换日期 : 2008-8-12 11:21:42
------------------------------------------------------------------------------*/
0x80,0x40,0xF0,0x2C,0x43,0x20,0x98,0x0F,0x0A,0xE8,0x08,0x88,0x28,0x1C,0x08,0x00,
0x00,0x00,0x7F,0x00,0x10,0x0C,0x03,0x21,0x40,0x3F,0x00,0x00,0x03,0x1C,0x08,0x00
};
/*==========================
函数名:延时子函数 ==
输 入:time延时长度 ==
输 出:无 ==
==========================*/
void Delay(unsigned int time)
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<10;j++)
;
}
/*===============================
// 函数名:写命令到LCD //
// 输 入:cmdcode待写入命令 //
// 输 出:无 //
===============================*/
void write_command(unsigned char cmdcode)
{
RS = 0;
RW = 0;
P0 = cmdcode;
Delay(1);
E = 1;
Delay(1);
E = 0;
}
/*================================
// 函数名:写数据到LCD //
// 输 入:Dispdata待写入数据 //
// 输 出:无 //
================================*/
void write_dat(unsigned char Dispdata)
{
RS = 1;
RW = 0;
P0 = Dispdata;
Delay(1);
E = 1;
Delay(1);
E = 0;
}
/*===================================================
// 函数名:任意位置写入一字节 //
// 输 入:Page行定位,Col列定位,Data待写入字节 //
// 输 出:无 //
===================================================*/
void write_data(unsigned char Page,unsigned char Col,unsigned char Data)//在屏幕的任意位置写待显示的数据
{
if ((Col&0x40)==0)
{
CS2=1;CS1=0;
write_command(Page_Add+Page);
write_command(Col_Add+Col);
write_dat(Data);
}
else
{
Col-=64;
CS2=0;CS1=1;
write_command(Page_Add+Page);
write_command(Col_Add+Col);
write_dat(Data);
}
}
/*======================
// 函数名:清显示屏 //
// 输 入:无 //
// 输 出:无 //
======================*/
void Clr_Scr(void)
{
unsigned char j,k;
CS2=1;CS1=0; // 清左半屏 //
{
for(k=0;k<8;k++)
{
write_command(Page_Add+k);
write_command(Col_Add);
for(j=0;j<64;j++)
write_dat(0x00);
}
}
CS2=0;CS1=1; // 清右半屏 //
{
for(k=0;k<8;k++)
{
write_command(Page_Add+k);
write_command(Col_Add);
for(j=0;j<64;j++)
write_dat(0x00);
}
}
}
////////////////////////////////////////////////////////////
// 函数名:指定位置显示16*16字母 //
// 输 入:pag行定位,col列定位,*zmk待显示数字数据指针 //
// 输 出:无 //
////////////////////////////////////////////////////////////
void Disp_Chr(unsigned char pag,unsigned char col, unsigned char code *zmk)
{
unsigned char j=0,i=0;
for(i=0;i<16;i++)
{
for(j=0;j<2;j++)
{
write_data(pag+j,col+i,zmk[16*j+i]);
}
}
}
////////////////////////////
// 函数名:初始化液晶屏 //
// 输 入:无 //
// 输 出:无 //
////////////////////////////
void Init_lcd(void)
{
RST=0;
Delay(10);
RST=1;
Delay(10);
CS2=1;
CS1=1;
Delay(100);
write_command(Disp_Off);
write_command(Page_Add+0);
write_command(Start_Line+0);
write_command(Col_Add+0);
write_command(Disp_On);
}
/********************************-= 用户操作在下面进行 =-**********************************************/
////////////////////////////
// 函数名:主函数(例子)//
// 输 入:无 //
// 输 出:无 //
////////////////////////////
void main(void)
{
Init_lcd(); // 初始化液晶屏
for (TempCyc=0; TempCyc<3; TempCyc++)
Delay400Ms(); //延时
Disp_Chr(0,0,a) ;
for (TempCyc=0; TempCyc<3; TempCyc++)
Delay400Ms(); //延时
Clr_Scr(); // 清屏
IT1 = 0; //设外部中断1为低电平触发
EA = 1;
EX1 = 1; //开中断
do
{
if (BF)
Decode(KeyV);
else
EA = 1; //开中断
}
while(1);
}
/**********************************************************************************************
函数名称:延时函数
函数功能:延时
说明:
**********************************************************************************************/
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
/**********************************************************************************************
函数名称:中断函数
函数功能:每十一次(IntNum)中断一次,读取键盘值
说明:
**********************************************************************************************/
void Keyboard_out(void) interrupt 2
{
if ((IntNum > 0) && (IntNum < 9))
{
KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
if (Key_Data) KeyV = KeyV | 0x80; //当键盘数据线为1时为1到最高位
}
IntNum++;
while (!Key_CLK); //等待PS/2CLK拉高
if (IntNum > 10)
{
IntNum = 0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
BF = 1; //标识有字符输入完了
EA = 0; //关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数要声明为再入函数)
}
}
/**********************************************************************************************
函数名称:读键盘函数
函数功能:将键盘通码读取,并显示
说明:
**********************************************************************************************/
void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码
{
unsigned char TempCyc;
if (!Key_UP) //当键盘松开时
{
switch (ScanCode)
{
case 0xF0 : // 当收到0xF0,Key_UP置1表示断码开始
Key_UP = 1;
break;
case 0x12 : // 左 SHIFT
Shift = 1;
break;
case 0x59 : // 右 SHIFT
Shift = 1;
break;
default:
if (DisNum > 15)
{
Disp_Chr(0,0,Cls);//清LCD第二行
DisNum = 0;
}
if(!Shift) //如果SHIFT没按下
{
for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示
if (UnShifted[TempCyc][0] == ScanCode) Disp_Chr(0,0,a);
DisNum++;
}
else //按下SHIFT
{
for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示
if (Shifted[TempCyc][0] == ScanCode) Disp_Chr(0,0,a);
DisNum++;
}
break;
}
}
else
{
Key_UP = 0;
switch (ScanCode) //当键松开时不处理判码,如G 34H F0H 34H 那么第二个34H不会被处理
{
case 0x12 : // 左 SHIFT
Shift = 0;
break;
case 0x59 : // 右 SHIFT
Shift = 0;
break;
}
}
BF = 0; //标识字符处理完了
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -