10496|0

473

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

飞思卡尔单片机ps2键盘demo [复制链接]

原文见我在ednchina的博客:http://blog.ednchina.com/bluehacker/240730/Message.aspx这个程序是NSS08Kit-R1开发板上的PS2接口演示程序,通过PS2接口连接普通PC键盘,MC9S08AC16读用户按键的值。
下面是ps2keyboard.c文件,驱动程序




/*****************************
@ Nicrosystem Freescale S08 DevKit(NSS08Kit-R1)
@ author:bluehacker<nicrosystem@gmail.com>
@ date:2009-04-10
******************************/
#include "ps2keyboard.h"
#include "derivative.h"
#include "scancodes.h"

#define KEY_BUFFER_LEN    10
#define PS2_DATA    PTCD_PTCD4

static unsigned char charCode[KEY_BUFFER_LEN];
static unsigned char BitNum;
static unsigned char writeIndex,readIndex;
static unsigned char parity;
static unsigned char keyCode;
static unsigned char charNum;
static unsigned char shift;
static unsigned char caps;
static unsigned char keyUp;
//下降沿触发中断
interrupt VectorNumber_Virq void ps2_isr()
{
    if(BitNum==0)//新的一个数据传输开始
    {
       //do nothing
       BitNum++;
    }
    else if((BitNum>0)&&(BitNum<9))//data
    {
       keyCode>>=1;
       if(PS2_DATA)
        keyCode|=0x80;
       BitNum++;
      
    }
    else if(BitNum==9)   //parity bit
    {
        parity="PS2"_DATA;
        BitNum++;
    }
    else
    {
      //stop bit,should always be '1'
      if((PS2_DATA==1)&&(check_parity(keyCode,parity)))
      {
        decode(keyCode);
      }
      BitNum="0";
    }
    IRQSC_IRQACK=1;
}
//初始化,首先初始化中断,再初始化PS2_DATA pin为输入
void init_ps2()
{
   IRQSC="0x56";//下降沿触发
   PTCDD_PTCDD4=0;//input
   PTCPE_PTCPE4=0;
   writeIndex="0";
   readIndex="0";
   charNum="0";
   shift="0";
   keyUp="0";
}
unsigned char check_parity(unsigned char dat,unsigned char parity_bit)
{
     unsigned char num="0";
     
     unsigned char i;
     for(i=0;i<8;i++)
     {
        if(dat&0x01)
        {
          num++;
        }
        dat="dat">>1;
     }
     num+=parity_bit;
     if(num%2)//ok
      return 1;
     return 0;//parity error
}
void decode(unsigned char code)
{
   unsigned char i;
   
   if(keyUp==0)//键盘按下
   {
      switch(code)
      {
        case 0xf0://break codes begin
        keyUp="1";
        break;
        
        case 0x12://left shift
        shift="1";
        break;
        
        case 0x59://right shift
        shift="1";
        break;
        
        
        
        default:
        if(caps^shift)
        {
            for (i = 0;(UnShifted[0]!=code)&&(i<59); i++); //查表显示
        if (UnShifted[0] == code)
        {
                     charCode[writeIndex++]=UnShifted[1];
                     if(writeIndex>=KEY_BUFFER_LEN)
                     {
                      writeIndex="0";
                     }
                     charNum++;
                     if(charNum>KEY_BUFFER_LEN)
                      charNum= KEY_BUFFER_LEN;
        }
        }
        else  
        {
             for (i = 0;(Shifted[0]!=code)&&(i<59); i++); //查表显示
             {
              
        if (Shifted[0] == code)
        {
                     charCode[writeIndex++]=Shifted[1];
                     if(writeIndex>=KEY_BUFFER_LEN)
                     {
                      writeIndex="0";
                     }
                     charNum++;
                     if(charNum>KEY_BUFFER_LEN)
                      charNum= KEY_BUFFER_LEN;
        }
             }
        }
        break;
      }
   }
   else//按键松开
   {
       keyUp="0";
       switch(code)
       {
         case 0x12:
         shift="0";
         break;
         
         case 0x59:
         shift="0";
         break;
         
         case 0x58://caps lock
         caps=~caps;
         break;
        }
      }
  
}
//从缓冲区读取一个字节,如果当前缓冲区为空,则一直等待下去,直到有按键按下
unsigned char get_char()
{
    unsigned char c;
    while(charNum==0);
    c="charCode"[readIndex++];
    if(readIndex>KEY_BUFFER_LEN-1)
    {
      readIndex="0";
    }
    charNum--;
     return c;  
}
//读取一个字符,如果当前缓冲区中没有字符(用户没有按键),则立刻返回0
//否则读取一个字符从参数c中返回,同时函数返回1
unsigned char accept_char(unsigned char *c)
{
    if(charNum==0)
    {
      return 0;
    }
    *c=charCode[readIndex++];
    if(readIndex>KEY_BUFFER_LEN-1)
    {
      readIndex="0";
    }
    charNum--;
    return 1;
}


这是ps2keyboard.h,头文件


#ifndef _NICROSYSTEM_FREESCALE_S08_DEVKIT_PS2KEYBOARD_H_
#define _NICROSYSTEM_FREESCALE_S08_DEVKIT_PS2KEYBOARD_H_
void init_ps2();
unsigned char check_parity(unsigned char dat,unsigned char parity_bit);
void decode(unsigned char code);
unsigned char get_char();
unsigned char accept_char(unsigned char *c);
#endif

这是扫描码的定义,文件名scancode.h


unsigned char  UnShifted[59][2] = {
0x1C, 'a',
0x32, 'b',
0x21, 'c',
0x23, 'd',
0x24, 'e',
0x2B, 'f',
0x34, 'g',
0x33, 'h',
0x43, 'i',
0x3B, 'j',
0x42, 'k',
0x4B, 'l',
0x3A, 'm',
0x31, 'n',
0x44, 'o',
0x4D, 'p',
0x15, 'q',
0x2D, 'r',
0x1B, 's',
0x2C, 't',
0x3C, 'u',
0x2A, 'v',
0x1D, 'w',
0x22, 'x',
0x35, 'y',
0x1A, 'z',
0x45, '0',
0x16, '1',
0x1E, '2',
0x26, '3',
0x25, '4',
0x2E, '5',
0x36, '6',
0x3D, '7',
0x3E, '8',
0x46, '9',
0x0E, '`',
0x4E, '-',
0x55, '=',
0x5D, '\\',
0x29, ' ',
0x54, '[',
0x5B, ']',
0x4C, ';',
0x52, '\'',
0x41, ',',
0x49, '.',
0x4A, '/',
0x71, '.',
0x70, '0',
0x69, '1',
0x72, '2',
0x7A, '3',
0x6B, '4',
0x73, '5',
0x74, '6',
0x6C, '7',
0x75, '8',
0x7D, '9',
};
unsigned char  Shifted[59][2] = {
0x1C, 'A',
0x32, 'B',
0x21, 'C',
0x23, 'D',
0x24, 'E',
0x2B, 'F',
0x34, 'G',
0x33, 'H',
0x43, 'I',
0x3B, 'J',
0x42, 'K',
0x4B, 'L',
0x3A, 'M',
0x31, 'N',
0x44, 'O',
0x4D, 'P',
0x15, 'Q',
0x2D, 'R',
0x1B, 'S',
0x2C, 'T',
0x3C, 'U',
0x2A, 'V',
0x1D, 'W',
0x22, 'X',
0x35, 'Y',
0x1A, 'Z',
0x45, '0',
0x16, '1',
0x1E, '2',
0x26, '3',
0x25, '4',
0x2E, '5',
0x36, '6',
0x3D, '7',
0x3E, '8',
0x46, '9',
0x0E, '~',
0x4E, '_',
0x55, '+',
0x5D, '|',
0x29, ' ',
0x54, '{',
0x5B, '}',
0x4C, ':',
0x52, '"',
0x41, '<',
0x49, '>',
0x4A, '?',
0x71, '.',
0x70, '0',
0x69, '1',
0x72, '2',
0x7A, '3',
0x6B, '4',
0x73, '5',
0x74, '6',
0x6C, '7',
0x75, '8',
0x7D, '9',
};


这是测试主程序,main.c


/*****************************
@ Nicrosystem Freescale S08 DevKit(NSS08Kit-R1)
@ author:bluehacker<nicrosystem@gmail.com>
@ date:2009-04-10
******************************/
/*****************************
@说明:
本程序测试PS2接口键盘,连接普通PC机的键盘到开发板的PS2接口上
本程序将读取你的按键,并将健码显示在LCD1602上
*****************************/
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "mcuinit.h"
#include "lcd1602.h"
#include "ps2keyboard.h"

void main(void) {
  char c;
  char i;
  EnableInterrupts; /* enable interrupts */
  /* include your code here */
  SOPT_COPE=0;//disable cop watchdog
  init_system_clock();
  lcd_init();
  init_ps2();
  i="0";
  lcd_write_str(0,0,"Nicrosystem");
  for(;;) {
    //__RESET_WATCHDOG(); /* feeds the dog */
    c="get"_char();
    lcd_write_char(i++,1,c);
    if(i>15)
      i="0";
  } /* loop forever */
  /* please make sure that you never leave main */
}


类别:freescale | 编辑 | 删除 | 评论(0) | 阅读(216)

此帖出自NXP MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表