📄 rt1602c+ps2_key二号.c
字号:
//单片机RT1602_C语言程序__RT1602C+PS2_KEY二号
//2006年4月8951_LCD_1602_Q_D_MCU适用
//AT89C54_Ver1.00
//KS0070(44780) 16x2 字符液晶屏驱动演示程序总线方式
//DB0=P1.0 DB1=P1.1 DB2=P1.2 DB3=P1.3 DB4=P1.4 DB5=P1.5
//DB6=P1.6 DB7=P1.7 R/W=P2.0 RS=P2.1 E=P2.7
//[注]:AT89C51的晶振频率为12MHz或11MHz
//PS/2_Keyboard接线
//1=DATA=P3.7 2=NC 3=GND 4=VCC
//5=CLK=P3.2 外部中断触发方式为低电平
#include <REGX51.H>
#include <stdio.h>
#include <absacc.h>
#include <inTRins.h>
#include <SS89BIN.h>
#define LCM_RW P3_5 //H读数据,L写数据
#define LCM_RS P3_4 //H数据寄存器,L指令寄存器
#define LCM_E P3_3 //片选,下降沿触发
#define LCM_Data P1 //数据总线接P1口
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define sda P3_7 //定义Keyboard数据端口引脚
sbit Key_Data=P3^7; //定义Keyboard数据端口引脚
sbit Key_CLK =P3^2; //中断端口,时钟线
unsigned char code cdle_net[]={"--www.cdle.net--"};
unsigned char code email[]={"pnzwzw@cdle.net"};
unsigned char code Cls[]={" "}; //清屏或者显示空白
static unsigned char KeyV=0X00; //键值
static unsigned char IntNum=0; //中断次数计数
unsigned char lie,hang; //lie为列值, hang为行值
bit dx=0; //大小写标志 dx==1时大写状态
void Delay5Ms(void) //5ms延时
{unsigned int TempCyc=5552;
while(TempCyc--);
}
unsigned char ReadDataLCM(void) //读数据
{LCM_RS=1;
LCM_RW=1;
LCM_E =0;
LCM_E =0;
LCM_E =1;
return(LCM_Data);
}
unsigned char ReadStatusLCM(void) //读状态
{LCM_Data=0xFF;
LCM_RS=0;
LCM_RW=1;
LCM_E =0;
LCM_E =0;
LCM_E =1;
while(LCM_Data&Busy); //检测忙信号
return(LCM_Data);
}
void WriteDataLCM(unsigned char WDLCM) //写数据
{ReadStatusLCM(); //检测忙
LCM_Data=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E =0; //若晶振速度太高可以在这后加小的延时
LCM_E =0; //延时
LCM_E =1;
}
void WriteCommandLCM(unsigned char WCLCM,BuysC) //写指令,BuysC为0时忽略忙检测
{if(BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E =0;
LCM_E =0;
LCM_E =1;
}
void LCMInit(void) //LCM初始化
{LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); //显示光标移动设置
WriteCommandLCM(0x0F,1); //显示开及光标设置
}
void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData)
{Y&=0x1; //按指定位置显示一个字符
X&=0xF; //限制X不能大于15,Y不能大于1
if(Y)X|=0x40; //当要显示第二行时地址码+0x40;
X|=0x80; //算出指令码
WriteCommandLCM(X,1); //发命令字
WriteDataLCM(DData); //发数据
}
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{unsigned char ListLength; //按指定位置显示一串字符
ListLength=0;
Y&=0x1;
X&=0xF; //限制X不能大于15,Y不能大于1
while(DData[ListLength]>0x19) //若到达字串尾则退出
{if(X<=0xF) //X坐标应小于0xF
{DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符
ListLength++;
X++;
}
}
}
void delay(int x) //PS2_延时程序
{int i,j;
for(i=0;i<600;i++)
for(j=0;j<x;j++);
}
void Decode()
{unsigned char data TempCyc;
signed char data k;
TempCyc=KeyV;
switch(TempCyc) //键值与显示字符的对应关系
{case 0x8A: k=0; break; //0
case 0x2C: k=1; break; //1
case 0x3C: k=2; break; //2
case 0x4C: k=3; break; //3
case 0x4A: k=4; break; //4
case 0x5C: k=5; break; //5
case 0x6C: k=6; break; //6
case 0x7A: k=7; break; //7
case 0x7C: k=8; break; //8
case 0x8C: k=9; break; //9
case 0x38: k=10; break; //a
case 0x64: k=11; break; //b
case 0x42: k=12; break; //c
case 0x46: k=13; break; //d
case 0x48: k=14; break; //e
case 0x56: k=15; break; //f
case 0x68: k=16; break; //g
case 0x66: k=17; break; //h
case 0x86: k=18; break; //i
case 0x76: k=19; break; //j
case 0x84: k=20; break; //k
case 0x96: k=21; break; //l
case 0x74: k=22; break; //m
case 0x62: k=23; break; //n
case 0x88: k=24; break; //o
case 0x9A: k=25; break; //p
case 0x2A: k=26; break; //q
case 0x5A: k=27; break; //r
case 0x36: k=28; break; //s
case 0x58: k=29; break; //t
case 0x78: k=30; break; //u
case 0x54: k=31; break; //v
case 0x3A: k=32; break; //w
case 0x44: k=33; break; //x
case 0x6A: k=34; break; //y
case 0x34: k=35; break; //z
case 0x98: k=63; break; //;
case 0xAA: k=65; break; //=
case 0xF2: k=68; break; //+
case 0x52: k=-16;break; //空格键
case 0xB0: k=101;break; //大小写控制键Caps lock
}
if(k==101) {dx=!dx;} //按下大小写控制键时 大小写标志取反
DisplayOneChar(2,0,KeyV/16+0x30);
DisplayOneChar(3,0,KeyV%16+0x30);
/* if(k==-16) //空格键按下时
{DisplayOneChar(lie,hang,-16+'0'); //清除光标
DisplayOneChar(lie+1,hang,79+'0'); //光标移一位
}
if(dx==0) //小写状态时显示
{DisplayOneChar(lie,hang,k+'0'); //小写字符
DisplayOneChar(lie+1,hang,79+'0'); //光标
}
if(dx==1) //大写状态时显示
{if(k>9&&k<=35)
{DisplayOneChar(lie,hang,(k+26)+'0');//大写字符
DisplayOneChar(lie+1,hang,79+'0');//光标
}
if(k>=0&&k<=9)
{DisplayOneChar(lie,hang,(k-10)+'0');//数字键对应的符号
DisplayOneChar(lie+1,hang,79+'0');//光标
}
}
if(lie==16) //写满一行
{lie=0;hang=hang+1; //换行
DisplayOneChar(lie,hang,79+'0'); //光标下移
}
else {lie=lie+2;}*/
EA=1;
delay(20);
}
void Keyboard_out(void) interrupt 0
{if((IntNum>0)&&(IntNum<9))
{KeyV=KeyV>>1; //因键盘数据是低>>高,结合上一句所以右移一位
if(Key_Data==1) //当键盘数据线为1时
{KeyV=KeyV|0x80;} //存储一位
}
IntNum++; //中断次数加一(中断一次接收一位数据)
if(IntNum>10) //中断11次后数据发送完毕
{IntNum=0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
EA=0; //关中断等显示完后再开中
Decode();
}
}
void TIME(int nt) //延时函数
{long int it=0;
for(it=0;it<nt*1000;it++);
return;
}
void main(void)
{ P3_1=0;P3_2=1;TIME(3); //指示灯闪烁
P3_1=1;P3_2=0;TIME(3);
P3_1=0;P3_2=1;TIME(3);
TIME(1); //启动时延时,等待LCM进入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻(可不要)
DisplayListChar(1,0,"Liao Quan Xin!"); //第一排1位显示的字符,14字
DisplayListChar(0,1,cdle_net); //第二排0位显示的字符,16字
// DisplayListChar(0,1,email); //第二排0位显示的字符,16字
ReadDataLCM(); //测试用句无意义
TIME(20); //延时
DisplayListChar(0,0,Cls); //清屏
DisplayListChar(0,1,Cls);
IT0=0; //设外部中断0为低电平触发
EA=1;
EX0=1; //开中断
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -