📄 source4.c
字号:
/*在以前的程序上吸取成功大侠的营养,终于完成7290键盘,红外,和PS2键盘的键值显示
/*在这个程序里设了一个软件复位键,即7290键盘的F3和PS2的ENTER长按.
/*PS2的键值未加处理,可根据需要对健值进行处理,如设第二功能键之类
/*使用了奇偶校验,数据一般比较正确
/*由于用中断没有实现,所以是用的捕获1,需用跳线把PS2的中断接到P1.3
/*左边两位数码管用来读取原始键值,可把获得的值填入键值表中获得新键值
****************************************************************************/
#include <c8051f020.h> // SFR 声明
#include <intrins.h>
/*------------------------------------------------------------------------------*/
#define CHIP_24C02 0xA0 //AT24C02从器件自身寻址地址.
#define CHIP_7290 0x70 //ZLG7290从器件自身寻址地址.
#define CHIP_8563 0xA2 //PCF8563从器件自身寻址地址.
#define KEY 0x01 //普通键键值寄存器器件子地址
#define RCNT 0x02 //普通键连击计数器器件子地址
#define FKEY 0x03 //功能键键值寄存器器件子地址
#define CBUF0 0x07 //命令缓冲区0
#define CBUF1 0x08 //命令缓冲区1
#define FLASH 0x0C //闪烁控制寄存器
#define SCANNUM 0x0D //显示位数控制寄存器
#define F0 0xfe //功能键键值定义
#define F1 0xfd
#define F2 0xfb
#define F3 0xf7
#define DEFPS2PUSHCOUNT 0x0A //长按时间
unsigned char xdata Ir_Data[]={0};
unsigned char code S[8]={0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10};
//各位数码管对应器件子地址,0x17对应最右边一位,
//0x10对应最左边一位。
unsigned char code SMGNUM[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,//**********/
0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,//**********/
0x02,0x0a,0x2a,0x3a,0x6e,0x00};//*******************/
//共阴数码管各显示数字对应代码0--F,-,n,r,o,,H**/
sbit ZLG7290RES = P3^2;
sbit Reset7290 = P2^7;
sbit PS2DATA = P3^1;
sbit PS2CLOCK = P1^3;
unsigned char xdata key,j =0;
bit key_sign; //按键标志
/*-------------------------------------------------------------------------------*/
unsigned char Bit_Cnt;
unsigned char temp;
unsigned char Irdata;
unsigned char WORD; //保存被收/发的数据字节
unsigned char WORDADR; //保存被传送的数据在器件中的地址
unsigned char SMBMODE; //SENDMODE作读/写控制字
unsigned char SMB_num; //SMB0一次读写字节数控制变量
bit SM_BUSY; //忙碌标志位
/*-------------------------------------------------------------------------------*/
void delay_ms( unsigned int count); //延时
void Init_Device(void); //系统初始化
void SMBUS_ISR (void); //中断服务程序
char SLA_READ(char chip,char wordadr);
void SLA_WRITE(char chip,char wordadr, char word);
/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
struct Keyboard_Information
{
unsigned char PS2KeyCount;//脉冲计数
unsigned char PS2KeyExtFlage;
unsigned char PS2KeyTemp;
unsigned char PS2KeyPopError;//出错类别
unsigned char PS2KeyPushCount;
unsigned char PS2KeyMessage;
unsigned char PS2KeyVal;
}PS2Buffers;
/*---------------------------------------------------------------------------------*/
void main (void)
{
unsigned char check; // 测试用变量
WDTCN = 0xde; // 关闭看们狗
WDTCN = 0xad;
Init_Device(); //系统初始化
SM_BUSY = 0; // SM_BUSY是忙碌标志位
SI = 0; //SM_BUSY中断标志位
ZLG7290RES =0;
Reset7290 =0;
delay_ms(20);
Reset7290 =1;
ZLG7290RES =1;
delay_ms(2);
SLA_WRITE(CHIP_7290,SCANNUM,0x07);
delay_ms(2);
SLA_WRITE(CHIP_7290,CBUF0,0X70);
SLA_WRITE(CHIP_7290,CBUF1,0X00);
delay_ms(2);
SLA_WRITE(CHIP_7290,FLASH,0X00);
CR =1;
while(1)
{ Reset7290 =1;
if(key_sign ==1) //键值显示
{ CR =0;
key_sign =0;
check =Ir_Data[3];
switch (check)
{
case F0:
Ir_Data[3] =0xF0;
break;
case F1:
Ir_Data[3] =0xF1;
break;
case F2:
Ir_Data[3] =0xF2;
break;
case F3:
Ir_Data[3] =0xF3;
RSTSRC |= 0x02;//软件复位
break;
default:
break;
}
if(check !=0xFF)
{ ZLG7290RES =1;
P5 =Ir_Data[2]; //**红外校验不外乎字节取反或重发
temp =check;//**通过观察这四组数据即可得到检验的方法.
SLA_WRITE(CHIP_7290,S[0],SMGNUM[Ir_Data[0]/16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[1],SMGNUM[Ir_Data[0]%16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[2],SMGNUM[Ir_Data[1]/16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[3],SMGNUM[Ir_Data[1]%16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[4],SMGNUM[Ir_Data[2]/16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[5],SMGNUM[Ir_Data[2]%16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[6],SMGNUM[Ir_Data[3]/16]);
delay_ms(1);
SLA_WRITE(CHIP_7290,S[7],SMGNUM[Ir_Data[3]%16]);
delay_ms(1);
}CR =1;
}
}
}
void PCA0_INT (void) interrupt 9
{
unsigned char i, key;
unsigned char code PS2TAB[] =
{ //20键PS2小键盘键码表
0x70, //0
0x69, //1
0x72, //2
0x7A, //3
0x6B, //4
0x73, //5
0x74, //6
0x6C, //7
0x75, //8
0x7D, //9
0x0B, //F6
0x77, //NumberLock
0x79, //加
0x7B, //减
0x7C, //乘
0x4A, //除
0x66, //Bksp
0x76, //Esc
0x71, //Del.
0x5A, //Enter
};
static unsigned char oldFall;
unsigned char temp,newFall;
EA =0; //**关总中断,清中断标志位,此步骤不可少
ZLG7290RES =0; //置指示
if(CCF0 ==1) //红外解码处理
{
CCF0 =0;
newFall =PCA0CPH0; //读取捕获寄存器的高八位数
temp =newFall-oldFall; //计算脉冲加间隔的时间
oldFall =newFall;
if(temp>=6 && temp<11) // "0"码
{temp=0;}
else if(temp>10 && temp<=0x15) //“1”码
{temp=1;}
else if(temp>=0x59 && temp<=0x65) //引导码信号
{
Bit_Cnt =0;
Ir_Data[0] =0;
Ir_Data[1] =0;
Ir_Data[2] =0;
Ir_Data[3] =0;
EA =1;ZLG7290RES =1;return; //返回,等待下次开始接收
}
else { Bit_Cnt =0;EA =1;ZLG7290RES =1;return; } //干扰信号
Bit_Cnt++;
switch(Bit_Cnt)
{ case 8: //第一字节数据
Ir_Data[0] =Irdata;
Ir_Data[0] =Ir_Data[0]|(unsigned char)temp;
Ir_Data[0] =_crol_(Ir_Data[0],8);//红外编码低位在前
Irdata=0;
break;
case 16: //第二字节数据
Ir_Data[1] =Irdata;
Ir_Data[1] =Ir_Data[1]|(unsigned char)temp;
Ir_Data[1] =_crol_(Ir_Data[1],8);
Irdata=0;
break;
case 24: //第三字节数据
Ir_Data[2] =Irdata;
Ir_Data[2] =Ir_Data[2]|(unsigned char)temp;
Ir_Data[2] =_crol_(Ir_Data[2],8);
Irdata=0;
break;
case 32: //第四字节数据
Ir_Data[3] =Irdata;
Ir_Data[3] =Ir_Data[3]|(unsigned char)temp;
Ir_Data[3] =_crol_(Ir_Data[3],8);
Bit_Cnt =0;key_sign =1;
break;
default:
break;
}
Irdata =Irdata|(unsigned char)temp;
Irdata =Irdata<<1;
}
if(CCF1 ==1)//PS2键盘处理
{
CCF1 =0;
if (PS2Buffers.PS2KeyCount ==0)
{ //PS2起始位测试
if (!PS2CLOCK && !PS2DATA)
{ //低电平是起始位
if (PS2Buffers.PS2KeyExtFlage !=0xF0)
{
PS2Buffers.PS2KeyTemp =0;
PS2Buffers.PS2KeyExtFlage =0;
PS2Buffers.PS2KeyPopError =0;
}
PS2Buffers.PS2KeyCount++; //脉冲计数
}
else PS2Buffers.PS2KeyPopError =0xEB; //置键起始位错误号0xeb
}
else if (PS2Buffers.PS2KeyCount <9)
{ //PS2数据位
key =PS2Buffers.PS2KeyTemp; //取键盘缓冲区移位数据
key >>=1;
if (PS2DATA) key |=0x80;
PS2Buffers.PS2KeyTemp =key;
PS2Buffers.PS2KeyCount++; //脉冲计数
}
else if (PS2Buffers.PS2KeyCount ==9)
{ //PS2数据奇校验
ACC = PS2Buffers.PS2KeyTemp; //取键盘缓冲区移位数据(C51取偶校验位)
if (P != PS2DATA) PS2Buffers.PS2KeyCount++; //奇校验正确,脉冲计数
else
{//PSW.0为奇偶标志位,当ACC中个位和为奇数时该位为1
PS2Buffers.PS2KeyPopError =0xEC; //置键奇校验位错误号0xec
PS2Buffers.PS2KeyCount =0; //脉冲计数归零
}
}
else if (PS2Buffers.PS2KeyCount ==10)
{ //停止位
key = PS2Buffers.PS2KeyTemp; //取键盘缓冲区移位数据
Ir_Data[0]=key;
PS2Buffers.PS2KeyCount =0; //脉冲计数归零
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -