📄 ps2test.c
字号:
/*
Title: icc-avr ps2 test
Author: dushibiao
Date: 2007 10 25
Purpose: decode ps2 keyboard code
Frequency: internal 8M
Software: icc-avr
Hardware: AVR mega16 BOARD
Connect: dushibiao@126.com
*/
#include <iom16v.h>
#include "scancodes.h"
#include "shumaguan.h"
#define PORT_KB PORTD
#define PIN_KB PIND
#define PIN_DIR DDRD
#define CLOCK 3
#define DATAPIN 2
//管脚定义
#define PIN_RXD 0 //PD0 RXD
#define PIN_TXD 1 //PD1 TXD
//常量定义
#define BAUDRATE 9600 //baudrate
#define F_CPU 8000000 //the frequency of the global clock
unsigned char bitcount;
volatile unsigned char origialcode=0;
void intinitial(void);
void portinitial(void); //initialize ports
void init_USART(void);
unsigned char decode(unsigned char sc);
/*-----------------------------------------------------------------
function: send a char to the uart
para: the char to be send
-----------------------------------------------------------------*/
void put_c(unsigned char c) //发送采用查询方式
{
while( !(UCSRA & (1<<UDRE)) ); //wait until the uart is empty
UDR=c; //write data to uart
}
/*-----------------------------------------------------------------
function: send a string to the uart
para: ptr---the pointer point to the string
------------------------------------------------------------------*/
void put_s(unsigned char *ptr)
{
while (*ptr)
{
put_c(*ptr++);
}
put_c(0x0D);
put_c(0x0A); //结尾发送回车换行
}
void main(void)
{
portinitial();
intinitial();
init_USART();
put_s("PS2--KEYOARD test");
put_s("dushibiao");
put_s("dushibiao@126.com");
put_c(0x0a);
put_c(0x0d);//换行
SEI(); //enable interrupt ,this was predefined in MACROS.h
while(1)
{
display(origialcode);
}
}
/*********************************************************************
fuction: ports initialize
**********************************************************************/
void portinitial(void)
{
PORTA=0XFF;
DDRA=0XFF; //OUT
PORTB=0XFF;
DDRB=0X0F; //high fout bit in , low four bits out
PORTC=0XFF; //pull up
PORTD=0XFF; //pull up
}
/*********************************************************************
fuction: ext interrupt initialize
**********************************************************************/
void intinitial(void) //int1 ,int0下降沿中断
{
MCUCR=(1<<ISC10); //falling edge interrup
GICR |=(1<<INT1); //enable ext0,ext1 interrupt
bitcount = 11;
}
/*********************************************************************
fuction: ext1 interrupt service routine
**********************************************************************/
#pragma interrupt_handler int1pro: iv_INT1
void int1pro(void)
{
unsigned char i,code;
if ((PIN_KB&(1<<DATAPIN))==0)
{
while((PIN_KB&(1<<CLOCK))==0);
for(i=0;i<8;i++)
{
while(PIN_KB&(1<<CLOCK));
code>>=1;
if ((PIN_KB&(1<<DATAPIN))!=0)
code|=0x80;
while((PIN_KB&(1<<CLOCK))==0);
}
while(PIN_KB&(1<<CLOCK));
while((PIN_KB&(1<<CLOCK))==0);
while(PIN_KB&(1<<CLOCK));
if ((PIN_KB&(1<<DATAPIN))!=0)
{
origialcode=code;
code=decode(code);
if(code!=0)
put_c(code);
}
}
}
/*-------------------------------------------------------------------
function: initialize uart
--------------------------------------------------------------------*/
void init_USART(void)//USART 初始化
{
//USART 9600 8, n,1 PC上位机软件(超级终端等)也要设成同样的设置才能通讯
UCSRC = (1<<URSEL) | 0x06;
//异步,8位数据,无奇偶校验,一个停止位,无倍速
/*
UBRRH与UCSRC共用I/O 地址。因此访问该地址时需注意以下问题。
写访问
当在该地址执行写访问时, USART 寄存器选择位(URSEL)控制被写入的寄存器。
若URSEL为0,对UBRRH值更新;若URSEL为1,对UCSRC设置更新
读访问
对UBRRH 或UCSRC 寄存器的读访问则较为复杂。但在大多数应用中,基本不需要读这些寄存器
没有UBRR这个16位寄存器,因为UBRRL(0x09)/UBRRH(0x20)的地址不连续,而且UBRRH跟UCSRC共用地址
*/
//U2X=0时的公式计算
UBRRL= (F_CPU/BAUDRATE/16-1)%256;
UBRRH= (F_CPU/BAUDRATE/16-1)/256;
//U2X=1时的公式计算
//UBRRL= (F_CPU/BAUDRATE/8-1)%256;
//UBRRH= (F_CPU/BAUDRATE/8-1)/256;
//也可根据数据手册的[波特率设置的例子]查得
//UBRRL = 0x2F; //set baud rate lo
//UBRRH = 0x00; //set baud rate hi
UCSRA = 0x00; //无倍速
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
//使能接收中断,使能接收,使能发送
}
/*--------------------------------------------------------------------------
function: decode the ps2 code to ASCII
para: sr----ps2 code
return ASCII code
--------------------------------------------------------------------------*/
unsigned char decode(unsigned char sc)
{
static unsigned char shift=0,up=0,shiftup=0;
unsigned char i;
if (sc==0xf0)
{
up=1;
return 0;
}
if (up==1)
{
up=0;
if ((sc==0x12)|(sc==0x59)) shift=0;
return 0;
}
switch (sc)
{
case 0x12:{
shift=1;
shiftup=1;
}
case 0x59:{
shift=1;
shiftup=1;
}
default:{
if (shift==0)
{
for(i = 0;unshifted[i][0]!=sc && unshifted[i][0]; i++);
if (unshifted[i][0] == sc)
return unshifted[i][1];
}
else
{
for(i = 0;shifted[i][0]!=sc && shifted[i][0]; i++);
if (shifted[i][0] == sc)
{
return shifted[i][1];
}
}
}
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -