//PS2键盘测试程序,可换行,按shift不放接着输入
//可输出大写,按下CAPS输出大写,再次按下输出小写
//此程序只用来测试,代码冗余,仅供参考,可根据需要自行删减
//PA13->PS2.CLK PA15->PS2.DATA
#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "wdg.h"
#include "timer.h"
#include "lcd.h"
const u8 unshifted[][2]= //shift键没按下译码表
{
0x0e,'`',
0x15,'q',
0x16,'1',
0x1a,'z',
0x1b,'s',
0x1c,'a',
0x1d,'w',
0x1e,'2',
0x21,'c',
0x22,'x',
0x23,'d',
0x24,'e',
0x25,'4',
0x26,'3',
0x29,' ',
0x2a,'v',
0x2b,'f',
0x2c,'t',
0x2d,'r',
0x2e,'5',
0x31,'n',
0x32,'b',
0x33,'h',
0x34,'g',
0x35,'y',
0x36,'6',
0x39,',',
0x3a,'m',
0x3b,'j',
0x3c,'u',
0x3d,'7',
0x3e,'8',
0x41,',',
0x42,'k',
0x43,'i',
0x44,'o',
0x45,'0',
0x46,'9',
0x49,'.',
0x4a,'/',
0x4b,'l',
0x4c,';',
0x4d,'p',
0x4e,'-',
0x52,''',
0x54,'[',
0x55,'=',
0x5b,']',
0x5d,'\',
0x61,'<',
0x69,'1',
0x6b,'4',
0x6c,'7',
0x70,'0',
0x71,'.',
0x72,'2',
0x73,'5',
0x74,'6',
0x75,'8',
0x79,'+',
0x7a,'3',
0x7b,'-',
0x7c,'*',
0x7d,'9',
0,0
};
const u8 shifted[][2]= //shift键按下译码表
{
0x0e,'~',
0x15,'Q',
0x16,'!',
0x1a,'Z',
0x1b,'S',
0x1c,'A',
0x1d,'W',
0x1e,'@',
0x21,'C',
0x22,'X',
0x23,'D',
0x24,'E',
0x25,'$',
0x26,'#',
0x29,' ',
0x2a,'V',
0x2b,'F',
0x2c,'T',
0x2d,'R',
0x2e,'%',
0x31,'N',
0x32,'B',
0x33,'H',
0x34,'G',
0x35,'Y',
0x36,'^',
0x39,'L',
0x3a,'M',
0x3b,'J',
0x3c,'U',
0x3d,'&',
0x3e,'*',
0x41,'<',
0x42,'K',
0x43,'I',
0x44,'O',
0x45,')',
0x46,'(',
0x49,'>',
0x4a,'?',
0x4b,'L',
0x4c,':',
0x4d,'P',
0x4e,'_',
0x52,'"',
0x54,'{',
0x55,'+',
0x5b,'}',
0x5d,'|',
0x61,'>',
0x69,'1',
0x6b,'4',
0x6c,'7',
0x70,'0',
0x71,'.',
0x72,'2',
0x73,'5',
0x74,'6',
0x75,'8',
0x79,'+',
0x7a,'3',
0x7b,'-',
0x7c,'*',
0x7d,'9',
0,0
};
void Decode(u8 scancode);// 声明函数原型
u8 bitcount=11,ascii=' '; // bitcount为位计数值;ascii为翻译后的ASCII码,初值为空格
u8 hang=0,lie=0; //彩屏显示位置
int main(void)
{
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
EXTIX_Init();
LED_Init();
LCD_Init();
LCD_Clear(YELLOW);
POINT_COLOR=RED;
BACK_COLOR=YELLOW;
while(1)
{
if(hang>=240) //换行
{hang=0;lie+=16;if(lie>=320)lie=0;}
LCD_ShowChar(hang,lie,ascii,16,0); // 显示键盘字符
}
}
/*******************************************
函数名称: Decode
功 能:
参 数: scancode--需要翻译的扫描码
返回值 : 无
********************************************/
void Decode(u8 scancode)
{
static u8 up=0,shift=0; //up为通、断码标志,shift为shift键按下标志
u8 i;
if (!up) //已接收的11位数据是通码(up为0)
{
switch (scancode)//开始翻译扫描码
{
case 0xF0: //键盘释放标志(随后的一个字节是断码)
up=1; //设置up为断码标志
break;
case 0x12: //左shift键按下
shift=1; //设置shift为按下标志
break;
case 0x59: //右shift键按下
shift=1; //设置shift为按下标志
break;
case 0x58: //CAPS键按下处理
shift=(shift==0)?1:0;//shift取反
break;
case 0x66: // backspace键按下时处理
//backspace键按下时处理
break;
case 0x5a:// 回车键按下时处理:换行
ascii=' ';
hang=0;
lie=lie+16;
break;
default:
if(!shift) //如果shift键没有按下
{ //查找unshifted表,表中左列是扫描码,右列是对应的ASCII码
for(i=0;unshifted[i][0]!=scancode&&unshifted[i][0];i++);
if(unshifted[i][0]==scancode)
{
ascii=unshifted[i][1];
hang=hang+8;
}
}
else //如果shift键按下
{ //查找shifted表
for(i=0;shifted[i][0]!=scancode&&shifted[i][0];i++);
if(shifted[i][0]==scancode)
{
ascii=shifted[i][1];
hang=hang+8;
}
}
break;
}
}
else //已接收的11位数据是断码(up为1)
{
up = 0; //将断码标志复位
switch (scancode) //检测shift键释放
{
case 0x12 : //左shift键
shift = 0;
break;
case 0x59 : //右shift键
shift = 0;
break;
default:
break;
}
}
}
此外还需修改中断文件夹中的两个函数
[cpp] view plaincopy
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD
GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
GPIOA->CRL|=0X00000008;
GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入
GPIOA->CRH|=0X80800000;
GPIOA->ODR|=1<<13; //PA13上拉,PA0默认下拉
GPIOA->ODR|=1<<15; //PA15上拉
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
//Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发
Ex_NVIC_Config(GPIO_A,15,FTIR|RTIR);//下降、上升沿触发
MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2
MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2
}
//外部中断15~10服务程序
void EXTI15_10_IRQHandler(void)
{
static u8 data; // 声明局部静态变量来保存扫描码
if (!PAin(15)) // 如果是下降沿触发中断
{
if(bitcount < 11 && bitcount > 2) //3到10位是数据,起始位,校验位和停止位忽略
{
data = (data >> 1); //右移保存数据
if(PAin(13)&0x01)
{
data|=0x80; //存储一个'1'
}
}
}
else //如果是上升沿触发中断
{
if(--bitcount==0) //如果11位全部接收完毕
{
Decode(data); //将扫描码翻译成ASCII码
bitcount = 11; //重新设为11位数据
}
}
// delay_ms(10); //消抖
// if(KEY0==0) //按键0
// {
// LED0=!LED0;
// }else if(KEY1==0)//按键1
// {
// LED1=!LED1;
// }
// EXTI->PR=1<<13; //清除LINE13上的中断标志位
EXTI->PR=1<<15; //清除LINE15上的中断标志位
}