这个程序是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 <hidef.h> /* 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 */
}
文章评论(0条评论)
登录后参与讨论