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

📄 key_b.c

📁 本程序主要通过外部中断INT0及3.3端口读取PS2键盘值并通过LCD1602显示
💻 C
字号:
/****************************************************************************
*函数功能:本程序主要通过外部中断INT0及3.3端口读取PS2键盘值并通过LCD1602显示,		 
*键扫描码的解码通过数组方式解码,程序的解码功能主要针对数字及大小写字母和常用			  
*标点符号 
*创建者:  曹兴
*创建日期:2008-10-11
*版本号:  2008101101
*****************************************************************************/
#include"reg51.h"
#include"stdio.h"
/*****************************端口定义***************************************/
#define   DATA	  P0					 //LCD数据传输端口
sbit RS = P2^7;				             //LCD控制端口定义
sbit RW = P2^6;
sbit EP = P2^5;
sbit k_data =  P3^3;    				 //PS/2数据线端口
sbit k_clk  =  P3^2;    	 			 //PS/2时钟线端口
unsigned char bitcount = 11;			 //PC键盘数据长度计数
unsigned char input = 0;				 //缓冲区读指针
unsigned char k_buf[32];				 //键盘缓冲区
//没有按下shift键的PC键盘扫描码
unsigned char code unshifted[][2]=
{28,'a',50,'b',33,'c',35,'d',36,'e',43,'f',52,'g',51,'h',67,'i',59,'j',
 66,'k',75,'l',58,'m',49,'n',68,'o',77,'p',21,'q',45,'r',27,'s',44,'t',
 60,'u',42,'v',29,'w',34,'x',53,'y',26,'z',69,'0',22,'1',30,'2',38,'3',
 37,'4',46,'5',54,'6',61,'7',62,'8',70,'9',14,'`',78,'-',85,'=',
 84,'[',91,']',76,';',65,',',73,'.',74,'/'};
//按下shift键的PC键盘扫描码
unsigned char code shifted[][2]=
{28,'A',50,'B',33,'C',35,'D',36,'E',43,'F',52,'G',51,'H',67,'I',59,'J',
 66,'K',75,'L',58,'M',49,'N',68,'O',77,'P',21,'Q',45,'R',27,'S',44,'T',
 60,'U',42,'V',29,'W',34,'X',53,'Y',26,'Z',69,')',22,'!',30,'@',38,'#',
 37,'$',46,'%',54,'^',61,'&',62,'*',70,'(',14,'~',78,'_',85,'+',93,'|',
 84,'{',91,'}',76,':',82,'"',65,'<',73,'>',74,'?'};
/*****************************************************************************
*函数名称:put_k_buf
*函数功能:将解码后的字符放入键盘缓冲区内
*入口参数:k_char
*出口参数:无
*****************************************************************************/
void put_k_buf(unsigned char k_char)
{
 k_buf[input] = k_char;					 //送键盘值ASCII码到键盘缓冲区
 if(input<31)
    input++;
 else
    input = 0;
	return;
} 
/*****************************************************************************
*函数名称:decode
*函数功能:解码函数,将接收到的数据转化为其对应的字符
*入口参数:k_code
*出口参数:无
*****************************************************************************/
void decode(unsigned char k_code) 
{
 static unsigned char shift,up,shiftup;
 unsigned i;
 if(k_code==0xf0)						 //按键释放
 {
  up = 1;
  return;
 }
 if(up==1)								 //shift键开关
 {
 up = 0;
 if((k_code==0x12)|(k_code==0x59))
    shift = 0;
 return;
 }
 switch(k_code)
        {
		case 0x12:						 //检测左shift键
		     {
			 shift = 1;
			 shiftup = 1;
			 } 
		 case 0x59:						 //检测右shift键
		     {
			  shift = 1;
			  shiftup = 1;
			 }
		  default:						 
		     { 
			  if(shift==0)				 //找出没有按下shift键的字符码将其存日键盘缓冲区中
			   {
			    for(i=0;unshifted[i][0]!=k_code&&unshifted[i][0];i++);
			    if(unshifted[i][0]==k_code)
			    put_k_buf(unshifted[i][1]);
			   }						 
			  else						 //找出按下shift键的字符码将其存日键盘缓冲区中
			   {
				for(i=0;shifted[i][0]!=k_code&&shifted[i][0];i++);		
			    if(shifted[i][0]==k_code)
				put_k_buf(shifted[i][1]);	
			   }
			 }
		} 
}
/*****************************************************************************
*函数名称:Keyboard_out
*函数功能:中断函数接受键盘发来的数据
*入口参数:无
*出口参数:无
*****************************************************************************/
void Keyboard_out(void) interrupt 0	using 0
{
 static unsigned char dat;
 switch(bitcount)
 {
  case 11:								//接收起始位 
      {
	   if(k_data )						//若数据线为高则返回
	        return ;					
	   else							    //若数据线为低则bitcount减1准备接收数据 
	        bitcount--; 
	   break;		 
	  }
  case 2:								//奇校验位
	  {
 	   bitcount--;
	   break;
	  }									
   case 1:							  	//停止位
       {
	   bitcount--;					    
	   if(!k_data )						//若数据线为0,则主机禁止接收放弃数据
	   {
	    bitcount = 11;
		return;
	   }
	   else								//若数据线为1,则接受停止位
	   {
	    bitcount = 11;
	    decode(dat);				    //将数据进行解码
	   }
	   break;
	   }
  
   default:						    //通过移位保存接收的8位数据
       {
	    dat = (dat>>1);
		if(k_data )
		dat|=0x80;
		bitcount--;
	   }
 }
}
/*****************************************************************************
*函数名称:delayns
*函数功能:LCD延时子程序
*入口参数:time
*出口参数:无
*****************************************************************************/
void delayns(unsigned char time)
{
 unsigned char i;
 for(;time>0;time--)
 for(i = 0; i< 250; i++)	;
}
/*****************************************************************************
*函数名称:lcd_buzy
*函数功能:测试LCD忙碌状态		
*入口参数:无
*出口参数:result
*****************************************************************************/
bit lcd_buzy()
{
 bit result;
 RS = 0;
 RW = 1;
 EP = 1;
 delayns(1);                          //此处延时特别重要 (必不可少)
 result = (bit)(DATA & 0x80);
 delayns(1);
 EP = 0;
 return result;
}
/*****************************************************************************
*函数名称:lcd_w_order
*函数功能:写指令数据到LCD子程序
*入口参数:cmd
*出口参数:无
*****************************************************************************/
void lcd_w_order(unsigned char cmd)
{
 while(lcd_buzy());                  //判断LCD是否忙碌
 RS = 0;
 RW = 0;
 EP = 1;
 DATA = cmd;
 delayns(1);
 EP = 0;
}
/*****************************************************************************
*函数名称:lcd_w_data
*函数功能:写入显示数据到LCD子程序
*入口参数:dat
*出口参数:五
*****************************************************************************/
void lcd_w_data(unsigned char dat)
{
 while(lcd_buzy());                  //判断LCD是否忙碌
 RS = 1;
 RW = 0;
 EP = 1;
 DATA = dat;
 delayns(1);
 EP = 0;
}
/*****************************************************************************
*函数名称:lcd_post
*函数功能:设定显示位置子程序
*入口参数:pos
*出口参数:无 
*****************************************************************************/
void lcd_post(unsigned char pos)

{
 lcd_w_order(pos | 0x80);
}
/*****************************************************************************
*函数名称:lcd_init
*函数功能:LCD初始化子程序
*入口参数:无
*出口参数:无
*****************************************************************************/
void lcd_init()
{
 lcd_w_order(0x38);	               //显示模式设置
 delayns(1);
 lcd_w_order(0x0c);	               //显示光标设置,开显示
 delayns(1);
 lcd_w_order(0x06);	               //显示光标移动(右移) 
 delayns(1);
 lcd_w_order(0x01);	               //清屏
 delayns(1);
}
/*****************************************************************************
*函数名称:main
*函数功能:本程序主要通过外部中断INT0及3.3端口读取PS2键盘值并通过LCD1602显示,键
*扫描码的解码通过数组方式解码,程序的解码功能主要针对数字及大小写字母和常用标点
*符号
*入口参数:无
*出口参数:无 
*****************************************************************************/
void main()
{
 unsigned char j,i=0;
 EA = 1;
 IT0 = 1;
 EX0 = 1;
 
 while(1)
 {
 i=0;
 lcd_init();                       // 初始化LCD
 delayns(10);
 lcd_post(0x00);                   //设置显示位置
 while(i<input)			   
 {
  lcd_w_data(k_buf[i]);            //显示字符
  i++;
 if(i==16)
  {
   lcd_post(0x40);                 // 设置显示位置
  }	  
 }
 for (j=0;j<20;j++)
 delayns(200);
 }
}

⌨️ 快捷键说明

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