⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 source4.c

📁 PS2键盘的使用,7290键盘的使用,怎么用红外来解码哟,大家不妨看看嘛,说不定有所帮助哟?
💻 C
📖 第 1 页 / 共 2 页
字号:
    	if (PS2DATA)
		{						//高电平是停止位
      		if (key ==0xe0)	//本次是扩展键
			{PS2Buffers.PS2KeyExtFlage =0xe0;}//置扩展键标志(小键盘只有回车键)
      		
      		else if (key ==0xf0)//本次是键断码,键释放
			{PS2Buffers.PS2KeyExtFlage =0xf0;}//置键释放标志
        
      		else
			{					//本次必为键值
        	if ((key ==0xAA) || (key ==0xFA)) PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零
																					
        	else
			{
            	PS2CLOCK =0;//阻止PS2键盘立即回送数据
          		PS2Buffers.PS2KeyPopError =0xAA;//出错码
          		for (i =0; i <20; i++)
			{
            	if (key ==(PS2TAB[i]))
				{			//搜索匹配按键
              		key =i ;
              		if (PS2Buffers.PS2KeyExtFlage ==0xF0)
					{
               		 	key |=0x80;//键释放
                		PS2Buffers.PS2KeyPushCount =0;//长压键计数器清零
                		PS2Buffers.PS2KeyMessage =key;//存入当前键值并执行命令
              			Ir_Data[1] =key;
					}
              		else
					{
                	if (key !=PS2Buffers.PS2KeyVal)
						{	//换了一个键
                  		PS2Buffers.PS2KeyPushCount =0;//长压键计数器清零
                  		PS2Buffers.PS2KeyMessage =key;//存入当前键值并执行命令
                		Ir_Data[2] =key;
						}
                	else
						{	//未换键
                  		PS2Buffers.PS2KeyPushCount++;		//长压键计数器计数
                  		if (PS2Buffers.PS2KeyPushCount >DEFPS2PUSHCOUNT)
							{								//长压时间到
                    PS2Buffers.PS2KeyMessage =key | 0x40;	//存入当前键值并执行命令
                    PS2Buffers.PS2KeyPushCount =0;		//长压键计数器清零
                  	Ir_Data[3] =key | 0x40;		
							}
                		}
              		}
              		PS2Buffers.PS2KeyVal =key;	//存入当前键值值1~20或0x80+(1~20)
					key_sign =1;
					if(Ir_Data[3] ==0x53)Ir_Data[3] =F3;
              		PS2Buffers.PS2KeyTemp =0;	//键码移位记录器
              		PS2Buffers.PS2KeyExtFlage =0;	//扩展键标志
              		PS2Buffers.PS2KeyPopError =0;	//键释放标志或出错码
              		break;
            	}
          	}//for循环出口
          		if (PS2Buffers.PS2KeyPopError) PS2Buffers.PS2KeyPushCount =0;
												//长压键计数器清零
          		PS2CLOCK =1;					//释放PS2时钟总线
        	}
      		}
    	}//得到停止位,完成键值处理
    	else PS2Buffers.PS2KeyPopError =0xed;//置停止位错误号0xed
  	}
  	else PS2Buffers.PS2KeyCount =0;//PS2键盘出错
	}
	ZLG7290RES =1;EA =1;//	对于不知道键值的键盘可在此处加key_sign=1,但会影响红外

}






void ZLG7290KEY_ISR (void) interrupt 0     //7290中断处理
{
    unsigned char m;
	Ir_Data[0] =0x72;
	Ir_Data[1] =0x90;
	Ir_Data[2] =0;
    if(j!=1)
      {
	     Ir_Data[3] =SLA_READ(CHIP_7290,KEY);
   	     if(Ir_Data[3] ==0)
	     {
	         Ir_Data[3] =SLA_READ(CHIP_7290,FKEY);
	         j =1;
	      } 
         key_sign =1;
       }
     else
	   j =0;
	   m =SLA_READ(CHIP_7290,KEY);
	   if(m !=0)
	   {
	      Ir_Data[3] =m;
		  key_sign =1;
        }
       else
	   {
		   j =0;
        }
}

/*********************************************************************************/
//函数名称:SLA_WRITE
//函数功能:在指定从器件指定的字节地址中写入一个字节数据
//输入参数:从器件寻址地址chip,写入数据在器件中的字节地址wordadr
//          待写入的数据word;
//输出参数:无
/*********************************************************************************/
void SLA_WRITE(char chip, char wordadr, char word)
{
   SMBMODE=chip & 0xfe;             //SENDMODE作读/写控制字  
   while(SM_BUSY);                  // 若SMBUS忙碌就等待
   SM_BUSY = 1;                     // 置SM_BUSY位(忙碌标志位)为1                
   WORD = word;                     // WORD中存放要送到24C02中去的数据(8位)
   WORDADR = wordadr;               // OP_CODE 中存放被传送数据送入24C02的首地址.
   SMB_num=1;
   STO = 0;
   STA = 1;                         // 启动数据传输
   while(SM_BUSY);                  // 等待传输完成
}
/*********************************************************************************/
//函数名称:SLA_READ
//函数功能:在指定从器件指定的字节地址中读出一个字节数据
//输入参数:从器件寻址地址chip,读出数据在器件中的字节地址wordadr
//输出参数:读出的一个字节数据WORD
/*********************************************************************************/
char SLA_READ(char chip, char wordadr)
{
   SMBMODE=chip | 0x01;
   while(SM_BUSY);                   // 若SMBUS忙碌就等待
   SM_BUSY = 1;                      // 置SM_BUSY位(忙碌标志位)为1 
   WORDADR = wordadr;                // OP_CODE 中存放从24C02读出数据的的首地址.
   SMB_num=1;
   STO = 0;
   STA = 1;                          // 启动传输
   while(SM_BUSY);                   // 等待传输完成 
   return WORD;                      //返回读出来的数据(一个字节)
}
void SMBUS_ISR (void) interrupt 7    //SMB0中断服务程序
{
   switch (SMB0STA)                  // 根据中断状态码跳转
   {                                 //(SMB0STA 是中断状态寄存器)
      case  0x08:	                 //0x08, (MT & MR) 发送起始位
         SMB0DAT = SMBMODE & 0xfe;   // 装入被访问的从芯片的读/写地址
         STA = 0;                    // 人工清除 STA 位
         break;
      case  0x10:	                 //0x10,(MT & MR) 重复发送起始位
         SMB0DAT = SMBMODE | 0x01;   // 装入被访问的从芯片的读地址
         STA = 0;                    // 人工清除 STA 位
         break;
      case  0x18:                    //0x18 ,(MT) 发送从地址 + W 后收到ACK
         SMB0DAT = WORDADR;
         break;
      case  0x20:     	             //0x20,(MT) 发送从地址 + W 后收到NACK
         STO = 1;
         STA = 1;
         break;
      case  0x28:		             //0x28,(MT) 发送数据后收到ACK
		 if(SMB_num)
		 {							    
             if (SMBMODE & 0x01)     // 如果为读操作则重新启动总线.
			 {     
                 STO = 0;
                 STA = 1;
           	  } 
			 else 
			 { 
                 SMB0DAT = WORD; //如果为写操作则将数据写入SMB0DAT.
				 SMB_num--;
              }
          }
		 else      //如果数据写入完毕则发送停止信号.
		 { 
             STO = 1;
             SM_BUSY = 0; 
          }
         break;
      case  0x30:           //0x30,(MT) 发送数据后收到NACK
         STO = 1;
         STA = 1;
         break;
      case  0x40:           //0x40,(MR) 发送从地址 + R 后收到 ACK
         AA = 0;                        
         break;
   	  case  0x48:	        //0x48,(MR) 发送从地址 + R 后收到 NACK
         STO = 0;
         STA = 1;
         break;
      case  0x58:	        //0x58,(MR) 收到数据字节 后已发送NACK
         WORD = SMB0DAT; 
         STO = 1;
         SM_BUSY = 0;
         AA = 1;                          
         break;
      default:
         STO = 1;
         SM_BUSY = 0;
         break;
    }
     SI = 0;
}
/*********************************************************************************/
// 初始化函数
/*********************************************************************************/
/*延时子程序*/
void delay_ms(unsigned int count)
{
   unsigned int ii,jj;
   for(ii=0;ii<count;ii++)
   {
      for(jj=0;jj<250;jj++)
	  _nop_();	
	  _nop_();	
	  _nop_();	
	  _nop_();			
    }	
}
void Port_IO_Init()
{
    EMI0CF    = 0x2C; //选择高端口模式,只用外部存储器,EMIF工作在
	                  //地址/数据复用方式,/WR和/RD占用12个SYSCLK周期 
    EMI0TC    = 0x3C; //地址建立/保持时间为0,ALE高/低脉宽占1个SYSCLK周期    
    P3MDOUT   = 0x2D; //P3.5--> LCD_RES,P3.3--> LCD_REQ,P3.2--> 7290_/RES,
	                  //P3.0--> OE574 四位设置为推拉输出方式;
	                  //P3.4--> LCD_BUSY,P3.1-->PS2_DATA两位设置为开漏输出方式。
    P74OUT    = 0xFF; //将P4,P6,P5,P7口配置为推拉输出方式
	P0MDOUT   = 0x01; //将TX0,TX1设置为推拉输出方式
    P1MDOUT   = 0x01;
    XBR0      = 0xDF; //按照配置表进行各个外设的配置
    XBR1      = 0x1C;
    XBR2      = 0x44;
   /*额外的配置请在本行文字以下进行配置并请加详细注释*/
    
   /*------------------------------------------------*/
}
void Oscillator_Init()  //系统时钟初始化
{
    int i = 0;
    OSCXCN    = 0x67;
    for (i = 0; i < 3000; i++);  // Wait 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    OSCICN    = 0x88;  //使用外部22.1184M晶振,使能时钟丢失检测
}
void SMBus_Init()
{
    SMB0CN    = 0x44;  //允许SMBUS, 应答返回AA(低电平
    SMB0CR    = 0x00;  //配置传送速度为40K
}
void Interrupts_Init()
{
    EIE1     |= 0x02;//使能SMB0中断
    IE       |= 0x05;//使能中断0
	TCON	 |= 0x04;
	IP		 |= 0x00;
	EIP1     |= 0x02;//设置SMBUS中断为高优先级
	IE       |= 0x80;//使能全局中断
}
void PCA0_Init (void)//PCA0初始化
{
	PCA0MD	  =	0x00;//PCA0采用系统时钟12分频,禁止PCA0溢出中断
	EIE1	 |=	0x08;//允许PCA0中断
	PCA0CPM0  =	0x11;//模块0下降沿中断允许
	PCA0CPM1  =0x11;
	CR		  =	0;   //关PCA0
}
void Init_Device(void) //初始化主函数
{
    Oscillator_Init();
	Port_IO_Init();
	SMBus_Init();
	Interrupts_Init();
	PCA0_Init();
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -