PS2接口键盘显示实验
键盘显示程序设计实验

实验四键盘显示程序设计实验目的1、理解串行接口键盘单片机汇编语言程序的基本结构2、了解单片机汇编语言程序的设计和调试方法3、掌握几个的基本的传送类、控制类指令的使用方法实验仪器单片机开发板、万利仿真机、稳压电源、计算机实验原理1、键盘接口电路工作原理串行接口键盘盘电路如图4-15所示。
键盘扫描线与显示位选扫描信号共用。
键盘输入只需要一根线,电路简单。
键盘扫描信号从74LS164输出,低电平有效。
当扫描到某个键时,若按键按下,在KEY端得到低电平,否则得到高电平。
通过判断KEY的电平就可以知道相应键盘是否按下。
图4-15 键盘接口电路图2、读键盘程序设计从上面工作原理分析可知,读键程序可以和显示程序结合在一起,也可以单独设计。
这种结构的键盘同样存在抖动问题。
为了减少程序误动作,程序设计时也要考虑去抖动问题。
这里设计一个把键值显示在LED上的程序。
为了简化问题,把读键程序与显示结合起来。
程序流程图如图4-16所示。
图4-16 键盘扫描程序流程图实验内容1、设计程序把键值显示在数码管。
#include<reg52.h>#include"display.h"extern uchar point;extern uchar table[8];uchar t,temp,time;char num;bit flag1;/*void main(){uchar i;table[0]=0x0;for(i=1;i<8;i++)table[i]=0x11;while(1){num=dispkey();if(flag==1)table[0]=num;delay_1ms(2);}}*//************************************************************2、设计程序按不同键时实现不同功能。
功能:按向上键:最右边一位数码管数值加1(0-9),到9时加1回到0 按向下键:最右边一位数码管数值减加1(9-0),到0时减1回到9按向左键:显示数字左移一位按向右键:显示数字右移一位keypointr:短按小数点右移,长按显示学号;接口:上下左右keypointrkeypointl**************************************************************/ void main(){uchar i,j=7,k=0;for(i=0;i<8;i++)table[i]=0x11;TMOD=0x01;EA=1;TH0=(65536-20000)/256;TL0=(65536-20000)%256;ET0=1;TR0=1;table[7]=0x1;while(1){delay_1ms(5);temp=dispkey();switch(temp){case 5: if ( flag==0){num=++table[j];//加1if(num==10)num=0;table[j]=num;delay_1ms(1);}; flag=1; break;case 4:if ( flag==0){num=--table[j];//减1if(num==-1)num=9;table[j]=num;delay_1ms(1);};flag=1;break;case 2: if ( flag==0) //右移{if(j==7){table[0]=table[7];table[7]=0x11;j=0;continue;}table[j+1]=table[j];//左边赋给右边j++;table[j-1]=0x11;delay_1ms(1);//关闭左一位};flag=1;break;case 8:if ( flag==0){ //左移if(j==0){table[7]=table[0];table[0]=0x11;j=7;continue;}table[j-1]=table[j];//右边赋给左边j--;table[j+1]=0x11;delay_1ms(1);//关闭右一位};flag=1;break;case 1:if ( flag==0) //小数点右移{if(flag1==1){table[0]=0x9;table[1]=0x4;table[2]=0x0;table[3]=0x8;table[4]=0x1;table[5]=0x0;table[6]=0x3;table[7]=0x1;}else{if(k==7){ point=tablepoint[7];k=0;continue;}point=tablepoint[k];k++;delay_1ms(1);}};flag=1;break;default:flag=0; break;}}}void timer0() interrupt 1{TH0=(65536-20000)/256;TL0=(65536-20000)%256;t++;time++;if(temp==1){if(time==50){if(temp==1)flag1=1;time=0;}}}/*******************************************************显示函数*******************************************************///#define __DISPLAY_H__#include"display.h"uchar code disptable[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0x11,0xC1,0x63,0x85,0x61,0x71,0xfe,0xff};//0~F数码代码uchar code tablepoint[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; uchar point;uchar table[8];void delay_1ms(uchar z){uint x,y;for(x=z;x>0;x--)for(y=123;y>0;y--);}uchar dispkey(void){uchar i,keynum=0;i=8;DA T=disptable[table[i-1]];if(point&tablepoint[i-1])DA T=DA T&0xfe; //加入小数点DISPDIN =0;DISPCLK =0;DISPCLK =1;DISPDIN =1;delay_1ms(1);if(!key){delay_1ms(5);if(!key) keynum=i;}for (i=7;i>0;i--){DA T =0xff;DA T =disptable[table[i-1]];if(point&tablepoint[i-1])DA T=DA T&0xfe; //加入小数点DISPCLK =0;DISPCLK =1;delay_1ms(1);if(!key){delay_1ms(5);if(!key) keynum=i;}}DA T=0xff;return keynum;}思考题1、当按加1键时,每按一次数码管值变化可能超过1,是什么原因?答:原因是机械按键会有抖动现象,所以每按一次数码管值变化可能超过1。
实验(二十一)PS2键盘控制LCD12864显示

华南理工大学无线电爱好者协会F D R 工作室实验二十一:PS2键盘控制LCD12864实验一. 实验目的:1. 认识ps2键盘协议2. 掌握12864液晶模块的使用方法。
3. 学会利用12864实现小型可视化图形界面 二. 实验原理:12864与单片机连接原理图12864跟ps2键盘的底层通讯较为复杂,我们在文件夹里提供了相应的资料给读者。
在此不再累述。
提醒读者一下:12864 驱动电流加大,使用时请先调lcd 座旁的蓝色可调电阻,使lcd 上能显示一个一个的小方格。
然后才能正常显示。
12864有并行跟串行两种通讯方式。
当psb 脚为高平时是并行,反之为串行。
华南理工大学F D R 工作室华南理工大学无线电爱好者协会F D R 工作室键盘要注意通码(按下键盘时发出)跟断码(松开键盘时发出)之间的联系。
三.硬件链接图:12864连线:如图所示的红线排针连到单片机各IO口,12864的几个控制脚都是连接在P0口上,从右到左依次是RS、RW、E、PSB、NC(我们提供的12864用不到该引脚)、RST,依次连接到P0^0,P0^1,P0^2,P0^3,P0^4,P0^5; 而数据线则直接接到P1口。
键盘连线:键盘的两条控制线在排针P7靠近红外接收头的两根上,最后一根是时钟线sclk,上边一根是数据线dat,将数据线接到单片机P3^2上靠近单片机一侧的排针上,将时钟线接到单片机INT1上。
12864连线图四.实验程序:#include<AT89X52.h>#include"led.h" //该头文件包含数码管显示数字驱动 #include"tg12864p.h"//该头文件包含lcd12864驱动sbit dat =P3^2;//DATA IN华南理工大学F D R 工作室华南理工大学无线电爱好者协会F D R 工作室#define uchar unsigned char // 即 uchar 等同与unsigned char #define uint unsigned int uchar sp2key_scan();/*****************常量声明区******************************************/ uchar code key_table[47]={'0','1','2','3','4','5','6','7','8','9', 'a','b','c','d','e','f','g','h','i','j', 'k','l','m','n','o','p','q','r','s','t', //说明:存放键盘上按键的as2码值 'u','v','w','x','y','z',' ','-','=',']', ';','"',',','.','/','[',' ' //作用:方便日后传值到液晶上 };/****************全局变量声明区************************************/ uchar key=0; //用于存放键盘解码函数的解码结果 uchar key_temp=0; bit BF=0; //接收到通码的标志位uchar key_count=0; //记录键盘传任一个数据时传来时钟脉冲个数 uchar key_buffer[5]={0,0,0,0,0};//接收键盘传来数据的缓冲区uchar key_num=0;//一个按键动作,键盘会发出通码,段吗,这用于记录收到编码个数。
FPGA实验十一 PS2键盘控制LCD显示实验

高性能软件无线电平台X6-面向高性能SoC验证和科学仿真主要特性支持PCI Express® Gen2 ×8 (但IP另配)搭载DDR3 SDRAM SO-DIMM系统搭载FMC连接器,可使用大部分RocketI/O(GTX)利用FMC可选基板能够对应各种接口提供PCI Express和DMA等参考设计无限扩展行业应用下一代软件无线电平台微软研究院软件无线电(Sora)是一种新型基于PC 的可编程无线电平台架构。
Sora 结合了可编程性和通用处理器(GPP )平台的性能和灵活性,同时使用的硬件和软件技术,以满足高性能的无线通信算法的计算挑战。
Sora 平台提供 Soft WiFi 开源代码。
SoftWiFi 目前支持率的802.11a/b/g 全部协议,无缝地与商业802.11网卡实现互操作,并达到商业网卡相当的性能。
Sora 是第一平台真正的软件无线电平台,支持用户开发的802.11a/b/g ,如物理层和MAC ,软件完全是标准PC 架构。
典型应用: White Spaces Mobile Phones Public Safety Radio Land MobileBroadcast TV and FM Radio Satellite navigationCovers 6 Amateur Radio Bands 射频部分主要特性: Dull-duplex Transceiver50 MHz to 5.8 GHz coverage50-100mW (17-20dBm) from 50 MHz to 1.2 GHz 30-70mW (15-18dBm) from 1.2 GHz to 2.2 GHz25+ dB Output power control range under software control Receive Specs:Noise figure of 5-7 dBIIP3 of 5-10 dBm;IIP2 of 40-55 dBm全频带射频收发模块实验十一 PS/2键盘显示LCD 实验一 实验目的1掌握PS/2键盘控制端口协议;2通过编写程序实现PS/2键盘控制LCD 的显示。
9_PS2键盘实验

广州致远电子有限公司
MagicARM270教学实验开发平台
3.实验内容
按照PS/2时序协议,不断地读取PS/2输出的键值,然 后通过串口发送到PC机显示。
广州致远电子有限公司
MagicARM270教学实验开发平台
4.实验预习要求
仔细阅读参考文献 [2] 第 24 节的 PXA27x 的 GPIO 模块说 明; 仔仔细阅读 <<MagicARM270 实验理论指导书 >> 第 2 章的 内容,了解MagicARM270实验箱的硬件结构,注意PS/2接 口电路。
MagicARM270教学实验开发平台
PS/2键盘实验
1.实验目的
掌掌握PS/2键盘接口时序协议,并读取键盘键值。
广州致远电子有限公司
MagicARM270教学实验开发平台
2.实验设备
硬件: PC机 1台 MagicARM270教学实验开发平台 1套 软件: Windows 98/2000/XP操作系统 ADS 1.2集成开发环境 超级终端程序(Windows系统自带)
广州致远电子有限公司
MagicARLeabharlann 270教学实验开发平台6.实验步骤
(10) 按MagicARM270实验箱的RST键复位系统,运行程 序,按 PS/2 键盘上的按键,观察 PC 机上的“超级终端” 主窗口是否显示出按键的键值 。
广州致远电子有限公司
MagicARM270教学实验开发平台
7.思考题
广州致远电子有限公司
MagicARM270教学实验开发平台
6.实验步骤
(6) 使 用 JFlashMM 软 件 将 flash.bin 烧 写 到 片 外 NOR FLASH ,操作方法请参考 <<MagicARM270 实验理论指导 书 >> 第 5 章“ ADS 集成开发环境应用及 JTAG 烧写方法” 的说明。 (7) 使用 PS/2 键盘插入 MagicARM270 实验箱的 CZ4 接口, 使用串口延长线把实验箱上的CZ1与PC机的COM1连接。 (8) 将 MagicARM270 实验箱上 SW1 的开关 1 拔到“ PS2” 端(即开关断开)。 (9) PC机上运行“超级终端”程序 ,设置串口波持率 为115200, 8位数据位,无奇偶校验位,1位停止位。
51单片机 PS2口电脑键盘输入液晶显示

#include <reg52.h>sbit LCM_RS= P2^0;//定义LCD引脚sbit LCM_RW= P2^1;sbit LCM_E= P2^2;sbit Key_Data = P3^4; //定义Keyboard引脚sbit Key_CLK = P3^3;#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识unsigned char code 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',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 code 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',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',};/*void Delay5Ms(void);void LCMInit(void);void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData);void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData);void Decode(unsigned char ScanCode);void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);unsigned char ReadDataLCM(void);unsigned char ReadStatusLCM(void);*/unsigned char code cdle_net[] = {"1602LCD PS2 TEST"};unsigned char code email[] = {"fjbysj@"};unsigned char code Cls[] = {" "};static unsigned char IntNum = 0; //中断次数计数static unsigned char KeyV; //键值static unsigned char DisNum = 0; //显示用指针static unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识static unsigned char BF = 0; //标识是否有字符被收到//5ms延时void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}//400ms延时void Delay400Ms(void){unsigned char TempCycA = 5;unsigned int TempCycB;while(TempCycA--) {TempCycB=7269;while(TempCycB--); }}//读状态unsigned char ReadStatusLCM(void){ LCM_Data = 0xFF;LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 1;while(LCM_Data & Busy); //检测忙信号return(LCM_Data);}//写数据{ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}//写指令void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{ if(BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*//读数据unsigned char ReadDataLCM(void){ LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 1;return(LCM_Data);}*/void LCMInit(void) //LCM初始化{ LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();Delay5Ms();WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0F,1); // 显示开及光标设置}//按指定位置显示一个字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if(Y)X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCM(X, 1); //发命令字WriteDataLCM(DData); //发数据}//按指定位置显示一串字符void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>0x19) {//若到达字串尾则退出if(X <= 0xF) {//X坐标应小于0xFDisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void Keyboard_out(void) interrupt 2{if((IntNum > 0) && (IntNum < 9)) {KeyV >>= 1; //因键盘数据是低>>高,结合上一句所以右移一位if(Key_Data) {KeyV |= 0x80; //当键盘数据线为1时为1到最高位}}IntNum++;while(!Key_CLK); //等待PS/2CLK拉高if(IntNum > 10) {IntNum = 0; //当中断10次后表示一帧数据收完,清变量准备下一次接收BF = 1; //标识有字符输入完了EA = 0; //关中断等显示完后再开中断(注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数要声明为再入函数)}}void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码{unsigned char TempCyc;if(!Key_UP) { //当键盘松开时switch(ScanCode) {case 0xF0 : //当收到0xF0,Key_UP置1表示断码开始Key_UP = 1;break;case 0x12: // 左SHIFTShift = 1;break;case 0x59: // 右SHIFTShift = 1;break;default:if(DisNum > 15) {DisplayListChar(0,1,Cls); //清LCD第二行DisNum = 0;}if(Shift == 1) { //如果按下SHIFTfor(TempCyc = 0;(Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示if(Shifted[TempCyc][0] == ScanCode) {DisplayOneChar(DisNum,1,Shifted[TempCyc][1]);}DisNum++;}else { //没有按下SHIFTfor(TempCyc = 0; (UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59);TempCyc++); //查表显示if(UnShifted[TempCyc][0] == ScanCode) {DisplayOneChar(DisNum,1,UnShifted[TempCyc][1]);}DisNum++;}break;}}Key_UP = 0;switch(ScanCode) { //当键松开时不处理判码,如G 34H F0H 34H 那么第二个34H不会被处理case 0x12: // 左SHIFTShift = 0;break;case 0x59: // 右SHIFTShift = 0;break;default:break;}}BF = 0; //标识字符处理完了}void KeyScan(void)/* 键盘扫描*/{unsigned char i,j,kv0,kv1,kv2,kv3,kv4,kvn,kvc,kvo,CLEAR;i = 0;j = 0;P1 = 0xEF;kv0=P1; /* 读入键值*/P1 = 0xDF;kv1=P1;P1 = 0xBF;kv2=P1;P1 = 0x7F;kv3=P1;P1 = 0xFF;kv4=P1;kvn = 0;for(i=0; i<4; i++) { /* 键值分析*/if((kv0&0x01)==0) {kvn = i*4 + 1;j++;}if((kv1&0x01)==0) {kvn = i*4 + 2;j++;}if((kv2&0x01)==0) {kvn = i*4 + 3;}if((kv3&0x01)==0) {kvn = i*4 + 4;j++;}if((kv4&0x01)==0) {kvn = 17 + i;j++;}kv0 /= 2;kv1 /= 2;kv2 /= 2;kv3 /= 2;kv4 /= 2;}if(j>1) {kvn = 0; /* 同时按下多键则键值无效*/}if(kvn==0) {kvc = 0;kvo = 0;}else { /* 若键值有效*/if(kvn==kvo) { /* 若键值与上次键值相同*/if(kvc<253)kvc++; /* 同键值计数延时*/if(kvc>2)kvn=0; /* 以前键值已有效,则本次无效*/ if(kvo == CLEAR) {if(kvc==20)kvn = 0x55; /* 连按清零键达120*10ms 则置全清*/ }}else { /* 若键值与上次键值不同*/ kvo = kvn; /* 记下键值*/kvc = 1;kvn = 0; /* 本次键值无效*/}}if(kvc==0) {kvn=0;}}void main(void){ unsigned char TempCyc;Delay400Ms(); //启动等待,等LCM讲入工作状态LCMInit(); //LCM初始化//Delay5Ms(); //延时片刻(可不要)DisplayListChar(0, 0, cdle_net);DisplayListChar(0, 1, email);//ReadDataLCM();//测试用句无意义for(TempCyc=0; TempCyc<10; TempCyc++) {Delay400Ms(); //延时}DisplayListChar(0, 1, Cls);IT1 = 0; //设外部中断1为低电平触发EX1 = 1; //开中断EA = 1;while(1) { KeyScan();if(BF)Decode(KeyV);else {EA = 1; //开中断}}}。
PS2键盘接口设计

研究生课程设计报告课程名称:基于FPGA的现代数字系统设计设计名称: PS/2键盘接口设计姓名:学号:课程教师:起止日期: 2016,西南科技大学信息工程学院制设计任务书学生班级:学生姓名:学号:设计名称:PS/2键盘接口设计起止日期: 2016,12,21至2016,12,28 课程教师:设计题目一、设计目的和意义键盘是嵌入式系统的最重要的输入设备之一,是实现人机交互的重要途径。
除了可以自行设计扫描式矩阵键盘之外,还可以选择标准 PS/2键盘实现人机交互。
扫描式矩阵键盘虽然电路简单,但不具有通用性,当需要使用较多的按键输入时,则会占用较多的I/O 端口,在软件上则要进行上电复位、按键扫描及通信的处理,而且还要加上按键的去抖动处理,增大了系统软、硬件的开销,开发周期较长。
标准PS/2 键盘由于接口通信协议简单,在系统中占用软硬件资源少,高可靠性,表达信息量大而得到了越来越广泛的应用本设计根据PS/2键盘的通信时序,利用Verilog HDL硬件描述语言来设计PS/2接口键盘的输入识别电路,并在CPLD/FPGA上实现,避免了硬件电路的焊接与测试。
Verilog HDL语言满足数字系统设计和综合的所有要求,设计中充分运用Verilog HDL层次化与模块化的思想,使整个设计过程简单、灵活。
同时运用EDA工具ISE Design Suite10.1验证设计。
经过对系统进行编译、仿真、测试,完成把键盘按键扫描码转的通码的显示,成功实现PS/2接口键盘的输入识别及显示的功能。
本设计具有较好的通用性和可移植性,可取代自行设计扫描式矩阵键盘而用于许多嵌入式系统设计中。
二、设计原理1 PS/2模块1.1、SP/2键盘接口PS/2通信协议是一种双向同步串行通迅协议。
通迅的两端通过CLOCK(时钟信号端)同步,并通过DATA(数据端口)交换数据。
任何一方如果想要抑制另外一方的通迅时,只需要把CLOCK 拉到低电平。
实验25 PS2键盘实验

实验 25 PS2 键盘实验在单片机系统中,经常使用的键盘都是专用键盘.此类键盘为单独设计制 作的,成本高、使用硬件连接线多,且可靠性不高,这一状况在那些要求键盘按键 较多的应用系统中更为突出.与此相比,在 PC 系统中广泛使用 PS/2 键盘具有价格 低、 通用可靠,且使用连接线少(仅使用 2 根信号线)的特点,并可满足多种系统的 要求.因此在单片机系统中应用 PS/2 键盘是一种很好的选择. 下面给出了一个在单片机上实现对 PS/2 键盘支持的硬件连接与驱动程序设计实 现.该设计实现了在单片机系统中对 PS/2 标准 104 键盘按键输入的支持.使用 Keil C51 开发的驱动程序接口和库函数可以方便地移植到其他单片机或嵌入式 系统中.所有程序在 Keil uVision2 上编译通过,在单片机 AT89s52 上测试通过. 协议: PS/2 协议: 目前,PC 机广泛采用的 PS/2 接口为 mini-DIN 6pin 的连接器,如图 1 所示:PS/2 设备有主从之分,主设备采用 Female 插座,从设备采用 Male 插头. 现在广泛使用的 PS/2 键盘鼠标均在从设备方式下工作.PS/2 接口的时钟与数据 线都是集电极开路结构,必须外接上拉电阻(一般上拉电阻设置在主设备中).主 从设备之间数据通信采用双向同步串行方式传输,时钟信号由从设备产生。
1.1 从设备到主设备的通信当从设备向主设备发送数据时,首先检查时钟线,以确认时钟线是否为高电 平.如果是高电平,从设备就可以开始传输数据;反之,从设备要等待获得总线的 控制权,才能开始传输数据.传输的每一帧由 11 位组成,发送时序及每一位的含 义如图 2 所示:每一帧数据中开始位总是为 0,数据校验采用奇校验方式,停止位始终为 1. 从设备到主设备通信时,从设备总是在时钟线为高时改变数据线状态,主设备在 时钟下降沿读人数据线状态。
1.2 主设备到从设备的通信 主设备与从设备进行通信时,主设备首先将时钟线和数据线设置为“请求 发送”状态,具体方式为:首先下拉时钟线至少 100us 抑制通信,然后下拉数据线 “请求发送”,最后释放时钟线.在此过程中,从设备在不超过 10us 的间隔内必 须检查这个状态,当设备检测到这个状态时,它将开始产生时钟信号.此时数据传 输的每一帧由 12 位构成,其时序和每一位含义如图 3 所示:与从设备到主设备通信相比,其每帧数据多了一个 ACK 位.这是从设备应答接收到字节的应答位,由从 设备通过拉低数据线产生,应答位 ACK 总是为 0.主设备到从设备通信过程中,主设备总是在时钟线为低电平时改变数据线的状态,从设备在时钟上升沿读人数据线状态. 2、PS/2 键盘的编码与命令集 2.1 PS/2 键盘的编码 目前,PC 机使用的 PS/2 键盘都默认采用第 2 套扫描码集.扫描码有两种不同的类型:“通码(make code)”和“断码(break code)”.当一个键被按下或持续按住时,键盘会将该键的通码发送给主机;而当一 个键被释放时,键盘会将该键的断码发送给主机.根据键盘按键扫描码的不同,可将按键分为 3 类: 第 1 类按键 第 2 类按键 通码为一个字节,断码为 0xF0+通码形式.如 A 键,其通码为 0x1C;断码为 0xF0 0x1C. 通码为两字节 0xE0+0xXX 形式,断码为 0xE0+0xF0+0xXX 形式.如 Right Ctrl 键,其通码为0xE0 0x14;断码为 0xE0 0xF0 0x14. 第 3 类特殊按键 有两个,Print Screen 键,其通码为 0xE0 0x12 0xE0 0x7C;断码为 0xE0 0xF0 0x7C 0xE00xF0 0x12.Pause 键,其通码为 0xE1 0x14 0x77 0xE1 0xF0 0xl4 0xF0 0x77;断码为空. 组合按键扫描码的发送是按照按键发生的次序,如按下面顺序按左 Shift 十 A 键:① 按下左 Shift 键;② 按下 A 键;③ 释放 A 键;④ 释放左 Shift 键,那么计算机上接收到的一串数据为 0x12 0x1C 0xF0 0x1C 0xF0 0x12.PS2 键盘的硬件原理图,3 脚,5 脚已经连 接到 单片机的 P3.4,P3.3PS2 实验照片,把程序烧写后, 把计算机的键盘插 入 XL2000 的 JP81,液晶屏的 JP41 所有跳线帽全部插入,按电脑键盘 则有相应的显示。
PS2接口键盘显示实验

PS2接口键盘显示实验一、实验目的1、学习用FPGA设计简单通信协议的方法。
2、学习PS2的工作原理,扫描码的ASCII码的转换。
3、掌握VHDL编写中的一些小技巧。
二、实验原理PS2通信协议是一种双向同步串行通迅协议。
通迅的两端通过CLOCK(时钟信号端)同步,并通过DATA(数据端口)交换数据。
任何一方如果想要抑制另外一方的通迅时,只需要把CLOCK拉到低电平。
PS2标准,规范每笔数据传输包含起始位(start bit)、扫描码(scan code)、奇同位检查(odd parity)、以及终止位(stop bit)共计11位,并以双向串行数据传输的方式,达到通信的目的。
且当主机端(host)或从机端(slave)并无传送或接收数据时,数据传输端口及频率均将升为高电位。
图21-1所示为每一笔数据传输所包含之内容如下:1.起始位(“0”)2.8位数据宽度的扫描码( scan code )。
3.奇同位检查,使扫描码与奇同位加起来1的数字为奇数个。
4.终止位(“1”)图21-1 PS2 串行传输标准Male(Plug)Female(Socket)6-pin Mini-DIN (PS2):1 - Data2 - Not Implemented3 - Ground4 - Vcc (+5V)5 - Clock6 - Not Implemented 图21-2 PS2 端口脚位定义PS2控制接口仅使用到两条传输端口,一为频率端口,另一则为数据端口如图21-2所示,且此传输埠必为三态(Tri-State)并具有双向(bidirectional)特性。
PS2 传输产品上,常见为鼠标与键盘,两者的驱动原理均相同,仅扫描码(scan code)不同。
因此我们以PS2键盘为例进行说明。
键盘其实就是一个大型的按键矩阵,它们由安装在电路板上的处理器(叫做“键盘编码器”)来监视着。
虽然不同的键盘可能采用不同的处理器,但是它们完成的任务都是一样的,即监视哪些按键被按下,哪些按键被释放了,并将这些信息传送到主机。
HDL-PS2接口键盘课程设计

课程设计报告题目HDL项目设计摘要:键盘是最常用人机接口设备之一,在嵌入式系统中有着相当广泛的应用。
一般自行设计的简易矩阵键盘仅仅是按行、列排列起来的矩阵开关。
当需要较多的按键时,则会占用较多的I/O 端口,在软件上则要进行上电复位按键扫描及通信处理,而且还要加上按键的去抖动处理,增大了软硬件开销。
而PS/2 键盘,内嵌自动去除按键抖动设计,自动地识别键的按下与释放,软硬件开发简便,价格便宜,稳定可靠,将PS/2 键盘作为嵌入式系统的输入设备已经成为可行的方案。
本设计是以现场可编程逻辑器件(FPGA)为核心的PS/2接口键盘的输入识别电路。
利用QuartusⅡ软件编写verilog HDL硬件描述语言程序以实现键盘部分简单键值的识别与输出。
本设计主要以程序为核心,硬件电路的搭建使用FPGA实验箱,将程序顶层文件里定义的输入输出端口与实验箱管脚进行相应的配置,除实验箱上的reset键以外,外设是一个与实验箱通过PS/2接口相连的键盘。
当系统上电后,实验箱上的数码管可以依次显示从键盘上输入的键值,并具有数码管清零功能。
关键词:Ps/2接口键盘、输入识别、FPGA 、Quartus Ⅱ、Verilog HDLAbstractThe keyboard, as one of the most commonly used man-machine interface equipment, has a wide application in embedded systems. General to design simple matrix keyboard is only per row, column arrangement up matrix switch. When need more button, will occupy more I/O port, in software, must carry on the power on the reset button scanning and communication processing, but also add buttons to jitter processing, increases the software and hardware cost. And PS / 2 keyboard, inline automatic remove key jitter design, automatically identify key press and release, software and hardware development is simple, cheap, stable and reliable, the PS / 2 keyboard as embedded system input device has become feasible scheme.This design based on field programmable logic devices (FPGA) is the core of the PS / 2 interface keyboard input identification circuit. Use verilog HDL Quartus Ⅱwriting software hardware description language program to realize the keyboard part simple key value of the recognition and output. This design mainly program as the core, the construction of the hardware circuit using FPGA experimental box, will be the top procedure defined in the file input/output port and experimental XiangGuan foot carries on the corresponding configuration, in addition to the experiment box on the reset button beyond, peripheral is a and experimental box through the PS / 2 interface connected keyboard. When the system is powered on, experiment box on the digital tube display can in turn from the keyboard input key value, and has the digital tube reset function.Keywords: Ps / 2 interface keyboard input identification FPGA,QuartusⅡVerilog HDL目录摘要2一.系统设计 51.1设计目标 51.2方案对比与确定 51.3总体设计框图及说明 61.3.1 总体设计框图 61.3.2总体设计端口说明 6 1.4模块电路设计及说明 7 1.4.1键盘数据接收部分 71.4.2数码管显示部分 8二.结果与讨论92.1调试步骤 9 2.2调试现象 92.3问题与分析 9三.软件设计103.1程序流程图 103.2程序设计 11四.心得体会17五.参考文献17六.附录18第一章系统设计1.1系统设计目标(1)以通用的PS2键盘为输入,设计一个能够识别PS2键盘输入编码的电路,并把键值通过数码管显示;(2)至少能够识别0~9的数字键。
实验四 键盘及显示实验

实验四键盘及显示实验一、实验目的1、学习自制键盘与单片机的接口及程序处理方法;2、掌握数码管显示电路的构成及程序编制方法。
二、实验仪器设备THGZ—1型单片机·CPLD/FPGA开发综合实验装置1台。
三、实验内容与要求通过键盘输入数据和操作指令,并由LED显示器显示相关数据。
1、独立式键盘与动态LED显示起初显示器全黑,当按KEY1~KEY8任意键后,显示器显示与键号对应的字符(“1”~“8”),每次按键对应字符显示在最右边,前一次的左移一位。
图2-4.1 独立式键盘与动态LED显示实验电路2、矩阵式键盘与动态LED显示①单字符的循环显示起初显示器显示“In ”,按键盘上的“0”~“9”任意键后再按“开始”键,6位LED 显示器马上左循环显示(左移速度0.5s/字符)键入的字符,按“停止”键可以重复以上过程。
图2-4.2 单字符的循环显示实验电路②延时函数的时间测量用定时器/计数器0测量如下延时函数的延时时间。
delaytest(unsigned int time){ unsigned int i,j;for (i=0;i<time;i++)for (j=0;j<65535;j++);}开机显示“good”;按“测量”键后显示“InPArA”表明要通过键盘输入延时函数的实参值,输入实参值并显示该值;按“测量”键后以ms为单位显示测量结果;再按“测量”键将重复以上过程。
图2-4.3 延时函数的时间测量实验电路四、思考题1、比较独立式键盘与矩阵式键盘的异同。
2、键盘处理程序包括哪些过程?2、如何识别键盘上的各键?键值有何意义?3、何为消抖?有何意义?如何实现?实验四源程序清单TEST4-1.C#include <reg51.h>#define KeyISegCodeO P1 /*定义键盘输入口/动态LED显示器段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/unsigned char DispBuf[6]={10,10,10,10,10,10}; /*显示数组,初始化为不显示*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char KeyV alue=0; /*键值,无键按下为0*/BitCtrO=0; /*关闭显示*/KeyISegCodeO=0xff; /*由输出转为输入*/if (KeyISegCodeO!=0xff){ delay(12); /*消抖延时约10ms(fosc=12MHz)*/if (KeyISegCodeO!=0xff){ switch (KeyISegCodeO){ case 0xfe: KeyV alue=1;break; /*KEY1按下,键值为1*/case 0xfd: KeyV alue=2;break; /*KEY2按下,键值为2*/case 0xfb: KeyV alue=3;break; /*KEY3按下,键值为3*/case 0xf7: KeyV alue=4;break; /*KEY4按下,键值为4*/case 0xef: KeyV alue=5;break; /*KEY5按下,键值为5*/case 0xdf: KeyV alue=6;break; /*KEY6按下,键值为6*/case 0xbf: KeyV alue=7;break; /*KEY7按下,键值为7*/case 0x7f: KeyV alue=8;break; /*KEY8按下,键值为8*/}while (KeyISegCodeO!=0xff); /*等待键释放*/}}return(KeyV alue); /*返回键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[16]={63,6,91,79,102,109,125,7,127,111,0}; /*0~9、显黑共阴极段码*/ unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(5); /*延时约4ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/}}main(){ unsigned char KeyV alue,i;while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/if (KeyV alue!=0){ /*显示缓冲区刷新*/for (i=5;i>0;i--)DispBuf[i]=DispBuf[i-1];DispBuf[0]=KeyV alue;}display(6); /*显示(6位)*/}}TEST4-2.1.C#include <reg51.h>#include <intrins.h>#define KeyROCISegCodeO P1 /*定义键盘行输出列输入/段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/#define NumRow 3 /*定义键盘行数为3*/#define NumColumn 4 /*定义键盘列数为4*/unsigned char DispBuf[6]={10,10,10,10,11,1}; /*显示数组,初始化为显示"In "*/unsigned char c_50ms=1; /*50毫秒计数*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char row=NumRow,RowCode,column=NumColumn,ColumnState; /*行循环、行码、列循环、列状态*/BitCtrO=0; /*关闭显示*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*有键按下*/delay(12); /*消抖延时约10ms(fosc=12MHz)*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*确实有键按下,寻找是哪个键*/RowCode=0xfe; /*指向第1行*/for(row=0;row<NumRow;row++) /*扫描共NumRow行*/{ KeyROCISegCodeO=RowCode; /*当前行*/ColumnState=KeyROCISegCodeO|0x0f; /*获取列状态*/for(column=0;column<NumColumn;column++) /*查询共NumColumn列的状态*/if ((ColumnState|0x7f)==0x7f){ while ((KeyROCISegCodeO|0x0f)!=0xff); /*等待键释放*/return(row*NumColumn+column); /*返回键值*/}elseColumnState=_crol_(ColumnState,1); /*指向下一列*/RowCode=_crol_(RowCode,1); /*指向下一行*/}}}return(NumRow*NumColumn); /*返回无键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[12]={63,6,91,79,102,109,125,7,127,111,0,84}; /*0~9、黑、n共阴极段码*/ unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyROCISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(6); /*延时约5ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/}}main(){ unsigned char i,KeyV alue,lock=0; /*循环,键值,键联锁:0:"停止"键有效、1:数字键有效、2:"开始"键有效*/TMOD=1; /*定时计数器0定时、方式1*/TH0=(65536-50000)/256; /*定时计数器0定时50ms*/TL0=(65536-50000)%256;ET0=1; /*开定时计数器0中断*/EA=1; /*开总中断*/while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/switch (KeyV alue) /*键处理*/{ case 12: break; /*无键按下不处理*/case 11: { if (lock==0){ /*"停止键"有效及处理*/TR0=0; /*关闭T0*/DispBuf[5]=1; /*左边第1个数码管显"I"*/DispBuf[4]=11; /*左边第2个数码管显"n"*/for (i=0;i<4;i++) DispBuf[i]=10; /*后面4个数码管显黑*/lock=1; /*数字键有效*/}} break;case 10: { if (lock==2){ /*"开始"键有效及处理*/TR0=1; /*启动T0*/lock=0; /*"停止"键有效*/}} break;default: { if (lock==1){ /*数字键有效及处理*/DispBuf[0]=KeyV alue; /*右边第1个数码管显键入的字符*/for (i=5;i>0;i--) DispBuf[i]=10; /*其余5个显黑*/lock=2; /*"开始"键有效*/}}}display(6); /*数码管(6个)显示*/}}/**********定时计数器0中断处理程序*********/TC0() interrupt 1 using 1{ unsigned char temp,i;TH0=(65536-50000)/256; /*定时计数器0重新定时50ms*/TL0=(65536-50000)%256;if (c_50ms++>10){ /*0.5s后使键入字符左环移1位*/c_50ms=1;temp=DispBuf[5];for (i=5;i>0;i--) DispBuf[i]=DispBuf[i-1];DispBuf[0]=temp;}}TEST4-2.2.C#include <reg51.h>#include <intrins.h>#define KeyROCISegCodeO P1 /*定义键盘行输出列输入/段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/#define NumRow 3 /*定义键盘行数为3*/#define NumColumn 4 /*定义键盘列数为4*/unsigned char DispBuf[6]={10,10,13,12,12,9}; /*显示数组,初始化为显示"good "*/unsigned long total; /*T0溢出计数*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}void delaytest(unsigned int time) /*延时函数*/{ unsigned int i,j;for (i=0;i<time;i++)for (j=0;j<65535;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char row=NumRow,RowCode,column=NumColumn,ColumnState; /*行循环、行码、列循环、列状态*/BitCtrO=0; /*关闭显示*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*有键按下*/delay(12); /*消抖延时约10ms(fosc=12MHz)*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*确实有键按下,寻找是哪个键*/RowCode=0xfe; /*指向第1行*/for(row=0;row<NumRow;row++) /*扫描共NumRow行*/{ KeyROCISegCodeO=RowCode; /*当前行*/ColumnState=KeyROCISegCodeO|0x0f; /*获取列状态*/for(column=0;column<NumColumn;column++) /*查询共NumColumn列的状态*/if ((ColumnState|0x7f)==0x7f){ while ((KeyROCISegCodeO|0x0f)!=0xff); /*等待键释放*/return(row*NumColumn+column); /*返回键值*/ }elseColumnState=_crol_(ColumnState,1); /*指向下一列*/RowCode=_crol_(RowCode,1); /*指向下一行*/ }}}return(NumRow*NumColumn); /*返回无键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[18]={63,6,91,79,102,109,125,7,127,111,0,84,92,94,115,119,80,121}; /*0~9、黑、n、o、d、P、A、r、E共阴极段码*/unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyROCISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(6); /*延时约5ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/ }}void error(){ DispBuf[5]=17; /*显"E"*/DispBuf[4]=16; /*显"r"*/DispBuf[3]=16; /*显"r"*/DispBuf[2]=12; /*显"o"*/DispBuf[1]=16; /*显"r"*/DispBuf[0]=10; /*显黑*/}main(){ unsigned char temp,NumBit,i,KeyV alue; /*临时、数字位数,循环,键值*/ unsigned long result; /*实参值/测量结果*/bit lock=0 ; /*键联锁:0:"测量"键有效、1:数字键/"确认"键有效*/ TMOD=1; /*定时T0定时方式1*/TH0=0;TL0=0;ET0=1; /*开T0中断*/EA=1; /*开总中断*/while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/switch (KeyV alue) /*键处理*/{ case 12: break; /*无键按下不处理*/case 11: { if (lock==0){ /*"测量键"有效及处理*/DispBuf[5]=1; /*显"I"*/DispBuf[4]=11; /*显"n"*/DispBuf[3]=14; /*显"P"*/DispBuf[2]=15; /*显"A"*/DispBuf[1]=16; /*显"r"*/DispBuf[0]=15; /*显"A"*/NumBit=0; /*无数字输入*/lock=1; /*数字/"确认"键有效*/}} break;case 10: { if (lock){ /*"确认"键有效及处理*/if (NumBit>0) /*限定必须输入至少1位实参值*/{ /*获得有效数字位*/for (i=4;i>0;i--)if (DispBuf[i]==10) DispBuf[i]=0;else break;result=10000*DispBuf[4]+1000*DispBuf[3]+100*DispBuf[2]+10*DispBuf[1]+DispBuf[0]; /*获得实参值*/if (result<65536&&result!=0){ total=0; /*T0溢出计数初值0*/TR0=1; /*启动T0*/delaytest((unsigned int)result);TR0=0; /*关闭T0*/result=(total*65536+TH0+TL0)/1000; /*获得ms为单位的测量结果*/if (result<1000000){ /*显示测量结果*/for (i=0;i<6;i++) /*获得测量结果数字位*/{ DispBuf[i]=result%10;result/=10;}for (i=5;i>0;i--) /*去掉测量结果数字位无效0*/if (DispBuf[i]==0)DispBuf[i]=10 ;else break;}elseerror(); /*结果超出显示范围,提示出错*/}elseerror(); /*实参为0或超出65535,提示出错*/}elseerror(); /*实参为0,提示出错*/lock=0; /*"测量"键有效*/}} break;default: { if (lock){ /*数字键有效及处理*/if (NumBit++<5) /*限定只能输入1~5位实参值*/{ if(NumBit!=1){ /*数字位左移*/temp=DispBuf[5];for (i=5;i>0;i--) DispBuf[i]=DispBuf[i-1];DispBuf[0]=temp;DispBuf[0]=KeyV alue;}else{ if (KeyV alue==0){ /*第1位数字为0,提示出错*/error();lock=0; /*"测量"键有效*/}else{ for (i=5;i>0;i--) DispBuf[i]=10;DispBuf[0]=KeyV alue;}}}else{ error();lock=0; /*"测量"键有效*/}}}}display(6); /*数码管(6个)显示*/}}/*******T0中断处理程序*******/TC0() interrupt 1 using 1{ total++;}。
ps2键盘解码基础实验与串口通信进阶实验

PS2 键盘解码实验一、实验内容:基础实验:ps2键盘通过ps2接口和FPGA相连,通过在开发板上对接收到的键盘扫描码进行接收和解码,将键盘值在数码管上进行显示。
进阶实验:串口通信实验,ps2键盘作为输入,通过FPGA和电脑进行串行通信,将键盘值显示在电脑屏幕上。
二、实验代码:(1)基础实验:module ps2( rst_n,clk,ps2clk,ps2data,sw,seg);input rst_n; //高电平复位信号input clk; //50M固有时钟input ps2clk;//ps2时钟线input ps2data; //ps2数据线output [3:0] sw;//数码管位选择output [7:0]seg;//数码管段选择reg [5:0] num; // 用于循环寄存器reg [7:0] temp_data; //数据暂存reg ps2clk_r0,ps2clk_r1; //用于检测ps2clk时钟下降沿reg [7:0]seg;wire neg_ps2clk;// ps2clk时钟下降沿wire [3:0]sw;wire ps2clk;wire ps2data;//***********检测ps2clk时钟下降沿并存于neg_ps2clk寄存器中************// always @ (posedge clk or posedge rst_n)beginif(rst_n)beginps2clk_r0 <= 1'b1;ps2clk_r1 <= 1'b1;endelsebeginps2clk_r0 <= ps2clk;ps2clk_r1 <= ps2clk_r0;endendassign neg_ps2clk = ~ps2clk_r0 & ps2clk_r1;//**************检测到ps2clk的下降沿则传送一位数据****************// always @ (posedge clk or posedge rst_n)beginif(rst_n)beginnum <= 4'd0;temp_data <= 8'b0000_0000;endelseif(neg_ps2clk)begincase (num)6'd0: num <= num+1'b1;6'd1: beginnum <= num+1'b1;temp_data[0] <= ps2data; //bit0end6'd2: beginnum <= num+1'b1;temp_data[1] <= ps2data; //bit1end6'd3: beginnum <= num+1'b1;temp_data[2] <= ps2data; //bit2end6'd4: beginnum <= num+1'b1;temp_data[3] <= ps2data; //bit3end6'd5: beginnum <= num+1'b1;temp_data[4] <= ps2data; //bit4end6'd6: beginnum <= num+1'b1;temp_data[5] <= ps2data; //bit5end6'd7: beginnum <= num+1'b1;temp_data[6] <= ps2data; //bit6end6'd8: beginnum <= num+1'b1;temp_data[7] <= ps2data; //bit7end6'd9: beginnum <= num+1'b1;end6'd32: beginnum <= 6'd0;enddefault: num<=num+1;endcaseendend//***************************译码显示部分***************************// always @ (temp_data)begincase (temp_data)8'h45: seg <= 8'b0000_0011; //08'h16: seg <= 8'b1001_1111; //18'h1E: seg <= 8'b0010_0101; //28'h26: seg <= 8'b0000_1101; //38'h25: seg <= 8'b1001_1001; //48'h2E: seg <= 8'b0100_1001; //58'h36: seg <= 8'b0100_0001; //68'h3D: seg <= 8'b0001_1111; //78'h3E: seg <= 8'b0000_0001; //88'h46: seg <= 8'b0000_1001; //98'h00: seg <= 8'b1111_1111;default:;endcaseendassign sw = 4'b1011;endmodule(2)进阶实验:1.top模块:module top(clk,rst,ps2clk,ps2data,rs232_tx,ps2_state);input clk;input rst;input ps2clk;input ps2data;output rs232_tx;//串口输出端output ps2_state;//有键按下时数据准备好状态位wire [7:0]dout;//暂存按键的ASSIC码值wire bps_start;//发送启动信号wire clk_bps;//波特率控制信号dfps2m1(.rst(rst),.clk(clk),.ps2clk(ps2clk),.ps2data(ps2data),.ps2_state(ps2_state),.dout(dou t));bote m2(.bps_start(bps_start),.clk(clk),.rst(rst),.clk_bps(clk_bps));chuangkoum3(.clk(clk),.rst(rst),.clk_bps(clk_bps),.rx_int(ps2_state),.rx_data(dout),.bps_start(bps _start),.rs232_tx(rs232_tx));endmodule2.ps2键盘模块:module dfps2( rst,clk,ps2clk,ps2data,ps2_state,dout);input rst;input clk;input ps2clk;input ps2data;output ps2_state;output [7:0]dout;reg [5:0] num;reg [7:0] temp_data;reg ps2clk_r0,ps2clk_r1;reg [7:0]dout;reg ps2_state;wire neg_ps2clk;//*********检测ps2clk时钟下降沿并存于neg_ps2clk寄存器中********// always @ (posedge clk or posedge rst)beginif(rst)beginps2clk_r0 <= 1'b1;ps2clk_r1 <= 1'b1;endelsebeginps2clk_r0 <= ps2clk;ps2clk_r1 <= ps2clk_r0;endendassign neg_ps2clk = (~ps2clk_r0) & ps2clk_r1;//******检测到ps2clk的下降沿则传送一位数据并判断ps2_state的状态*****// always @ (posedge clk or posedge rst)beginif(rst)beginnum <= 4'd0;temp_data <= 8'b0000_0000;ps2_state<=1'b0;endelsebeginif(neg_ps2clk)begincase (num)6'd0: beginps2_state <= 1'b0;num <= num+1'b1;end6'd1: begintemp_data[0] <= ps2data; //bit0ps2_state <= 1'b0;num <= num+1'b1;end6'd2: begintemp_data[1] <= ps2data; //bit1ps2_state <= 1'b0;num <= num+1'b1;end6'd3: begintemp_data[2] <= ps2data; //bit2ps2_state <= 1'b0;num <= num+1'b1;end6'd4: begintemp_data[3] <= ps2data; //bit3ps2_state <= 1'b0;num <= num+1'b1;end6'd5: begintemp_data[4] <= ps2data; //bit4ps2_state <= 1'b0;num <= num+1'b1;end6'd6: begintemp_data[5] <= ps2data; //bit5ps2_state <= 1'b0;num <= num+1'b1;end6'd7: begintemp_data[6] <= ps2data; //bit6ps2_state <= 1'b0;num <= num+1'b1;end6'd8: begintemp_data[7] <= ps2data; //bit7ps2_state <= 1'b0;num <= num+1'b1;end6'd9: beginps2_state <= 1'b0;num <= num+1'b1;end6'd10: beginps2_state <= 1'b1;num <= num+1'b1;end6'd32: beginps2_state <= 1'b0;num <= 6'd0;enddefault: beginps2_state <= 1'b0;num <= num+1;endendcaseendendend//******************将输出键值通码转换成ASSIC码值******************// always @(posedge clk or posedge rst)//Generatebeginif(rst)dout<=8'b0000_0000;elsebeginif(num==6'd10)begincase (temp_data)8'h45: dout <= 8'd48; //08'h16: dout <= 8'd49; //18'h1E: dout <= 8'd50; //28'h26: dout <= 8'd51; //38'h25: dout <= 8'd52; //48'h2E: dout <= 8'd53; //58'h36: dout <= 8'd54; //68'h3D: dout <= 8'd55; //78'h3E: dout <= 8'd56; //88'h46: dout <= 8'd57; //98'h1C: dout <= 8'd65; //A8'h32: dout <= 8'd66; //B8'h21: dout <= 8'd67; //C8'h23: dout <= 8'd68; //D8'h24: dout <= 8'd69; //E8'h2B: dout <= 8'd70; //F8'h34: dout <= 8'd71; //G8'h33: dout <= 8'd72; //H8'h00: dout <= 8'd0;default: dout <= 8'd0;endcaseendendendendmodule3.波特率模块:module bote(bps_start,clk,rst,clk_bps);input rst;input clk;input bps_start;//波特率转换启动信号output clk_bps;//转换后输出信号reg clk_bps;reg [11:0]i;//用于分频计数parameter speed=2603;//波特率控制50M/9600/2//**********************9600bps波特率产生模块*********************// always @(posedge clk or posedge rst)//Generatebeginif(rst)beginclk_bps<=1'b0;i <= 12'b0;endelsebeginif(bps_start)beginif(i==speed)begini <= 12'b0;clk_bps <= ~clk_bps;endelsei<=i+1'b1;endendendendmodule4.串口通信模块:module chuangkou(clk,rst,clk_bps,rx_int,rx_data,bps_start,rs232_tx );input clk;input rst;input clk_bps;//波特率变换后信号input rx_int;//接收准备好信号input [7:0]rx_data;//暂存键值的ASSIC码值output bps_start;//传输启动信号output rs232_tx; //串口输出端口reg [3:0]j; //用于循环寄存器reg clk_bps_r0,clk_bps_r1;// 用于检测clk_bps时钟上升沿reg rs232_tx;reg bps_start;wire posedge_clk_bps; //clk_bps时钟上升沿寄存器//**************检测到clk_bps的上升沿则传送一位数据*************// always @ (posedge clk or posedge rst)beginif(rst)beginclk_bps_r0 <= 1'b0;clk_bps_r1 <= 1'b0;rs232_tx <= 1'b1;bps_start <= 1'b0;j <= 1'b0;endelsebeginclk_bps_r0 <= clk_bps;clk_bps_r1 <= clk_bps_r0;if(rx_int)beginbps_start <= 1'b1;endelse if(bps_start)beginif(posedge_clk_bps)begincase(j)4'd0: beginrs232_tx<=1'b0;j <= j+1'b1;end4'd1: beginrs232_tx<=rx_data[0];j<=j+1'b1;end4'd2: beginrs232_tx<=rx_data[1];j<=j+1'b1;end4'd3: beginrs232_tx<=rx_data[2];j<=j+1'b1;end4'd4: beginrs232_tx<=rx_data[3];j<=j+1'b1;end4'd5: beginrs232_tx<=rx_data[4];j<=j+1'b1;end4'd6: beginrs232_tx<=rx_data[5];j<=j+1'b1;end4'd7: beginrs232_tx<=rx_data[6];j<=j+1'b1;end4'd8: beginrs232_tx<=rx_data[7];j<=j+1'b1;end4'd9: beginrs232_tx<=1'b1;bps_start <= 1'b0;j<=4'b0;enddefault: j<=4'd0;endcaseendendendendassign posedge_clk_bps = clk_bps_r0 & ~clk_bps_r1; endmodule5.管脚约束文件NET"clk" LOC="B8";NET"rst" LOC="H13";NET"ps2clk" LOC="R12";NET"ps2data" LOC="P11";NET"rs232_tx" LOC="P9";三、进阶实验结果:四、实验感想Ps2键盘解码实验持续了近一周,在这一周的实验中,我失败的很多次,但也在一次次的失败中吸取教训,一次次的重复并最终完成实验达到预期的效果,在这次实验中收获了很多。
基于单片机的PS2键盘显示系统设计ppt课件

完整最新版课件
7
PS2接口的电气特性
❖ PS2模块由PS2键盘和PS2接口组成,利用通 信协议对PS2键盘进行操作,PS2通讯协议 是一种双向同步串行通讯协议。通讯的两端 通过 Clock(时钟脚)同步,并通过Data(数据 脚)交换数据。任何一方如果想抑制另外一方 通讯时,只需要把Clock(时钟脚)拉到低电平。
完整最新版课件
22
结束
完整最新版课件
23
此课件下载可自行编辑修改,供参考! 感谢您的支持,我们努力做得更好!
完整最新版课件
24
此课件下载可自行编辑修改,此课件供参考! 部分内容来源于网络,如有侵权请与我联系删除!感谢你的观看!
此课件下载可自行编辑修改,此课件供参考! 部分内容来源于网络,如有侵权请与我联系删除!感谢你的观看!
❖ 方案二:数码管显示设计方案
❖ 方案三:PS2键盘设计方案
完整最新版课件
4
1.2 方案比较
❖ 由于方案一采用的是4X4键盘,设计需要 CPU不断的扫描键盘,占用了大量的CPU资 源;而方案二利用PS2键盘,有键按下时才 发送数据,减轻了CPU的负担,但是用数码 管显示不够直观,交互界面不够好,因此综 合方案一和方案二的优点,本设计采用了方 案三。
完整最新版课件
12
2.3 LCD显示模块设计
❖ 本论文介绍了液晶显示器LCD12864 与单片机的接 口及编程的方法,主要的控制脚有读\写选择引脚 R/W、读写使能引脚E、数据输入输出引脚D0-D7。
完整最新版课件
13
❖ LCD12864接口由8位数据线,电源地电源正,液晶 显示偏压信号(VL),数据命令选择端(RS), 读写选择端(R/W)组成。
完整最新版课件
实验二 键盘输入并显示实验

南昌大学实验报告实验二键盘输入并显示实验一、实验目的掌握接收键盘数据的方法,并了解将键盘数据显示时须转换为ASCII码的原理,并在程序中设置错误出口。
二、实验要求编写程序,将键盘接收到的4位十六进制数转换成等值的二进制数,在显示在屏幕上。
若输入的不是0~F之间的数字,则显示出错信息,并要求重新输入。
三、编辑实验程序EDIT 22.ASMCRLF MACRO ;光标回车、换行宏程序MOV AH,02HMOV DL,0DHINT 21HMOV AH,02HMOV DL, 0AHINT 21HENDMDATA SEGMENTMARK DB ?MESS DB 'INPUT , ENTER,INSPACE!',0DH,0AH,'INPUT:$'ERROR DB 'ERROR!', 0DH, 0AH,'$'DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DA TASTART: MOV AX,DA TAMOV DS,AX;DS初始化HEAD: CRLF;宏调用,回车、换行MOV MARK,0;错误标志,0无误,1出错MOV AH,09HLEA DX,MESSINT 21H ;显示提示输入的信息MESSCALL GETNUM ;接收键入数值送DXCMP MARK,01HJE HEAD ;有错,重新输入MOV CX,16 ;16位MOV BX,DX ;转换后二进制结果已在DX中TTT: ROL BX,1 ;循环左移1位,逐位转为ASCII码,并在屏幕显示MOV DL,BLAND DL,01H ;屏蔽掉高7位ADD DL,30H ;转为ASCIIMOV AH,02HINT 21H ;在屏幕显示二进制位对应的ASCII字符LOOP TTTJMP HEADFINI: MOV AH,4CHINT 21H ;返回DOSGETNUM PROC NEAR ;子程序,接收键入ASCII数值,转换成二进制送DXXOR DX,DX ;DX清0GGG: MOV AH,01HINT 21H ;键入单个数,并将ASCII值送ALCMP AL,0DH ;输入为回车,表示输入结束,则进行转换JE PPPCMP AL,20H ;输入为空格,则退回DOSJE FINICMP AL,30HJB KKK ;非法输入SUB AL,30HCMP AL,0AHJB GETS ;输入的是0~9,ASCII值30H~39HCMP AL,11HJB KKK ;非法输入SUB AL,07HCMP AL,0FHJBE GETS ;输入的是A~F, ASCII值41H~46HCMP AL,2AHJB KKK ;非法输入CMP AL,2FHJA KKKSUB AL,20H ;输入的是小写字母a~f,ASCII值61H~66H GETS: MOV CL,04 ;单个输入数已在AL中,高4位为0SHL DX,CLMOV AH,0ADD DX,AX ;将AL凑成16位AX(高12位为0),叠加到DX中JMP GGGKKK: MOV AH,09HMOV DX,OFFSET ERRORINT 21H ;显示出错提示信息MOV MARK,01H;错误标志PPP: PUSH DXCRLF ;宏调用,回车、换行POP DXRETGETNUM ENDPCODE ENDSEND STARTEND四、编译程序MASM 22.ASM五、链接LINK 22.OBJ六、执行DEBUG 22.EXE-G-INPUT , ENTER,INSPACE!-385A-0011100001011010-INPUT , ENTER,INSPACE!-2b45-0010101101000101-INPUT , ENTER,INSPACE!-J-ERROR!-INPUT , ENTER,INSPACE!-51234-0001001000110100七、实验总结本实验做键盘输入并屏幕显示,将十六进制转换成等值二进制数。
PS2键盘接口设计之二(实现了从键盘输入并显示在LCD液晶屏上)

PS2 键盘接口设计之二(实现了从键盘输入并显示在
LCD 液晶屏上)
在熟悉了PS2 键盘接口设计之后,我想大家都希望将输入的数据在显示
屏中实时的显示出来或者看看我们到底输入的是什幺样的东西,基于这个原因,结合Spartan-3E 开发板上的资源,我利用了液晶1602 将输入的字符显示出来。
最终结果是可以从键盘上输入任意ASCII 字符,可以通过1602 显示
出来。
具体实现方法是基于我的上一篇博文上的PS2 键盘设计和修改后的1602 液晶接口,顶层文件定义如下图所示:
CapsLock 为大写锁定或者Shift 输入端,高有效,clk_50m 是系统时钟信号,ps2c,ps2d 为ps2 的时钟和数据端口定义,rst_n 为复位输入,低有效,disp_value 为输入字符的ASCII 值,sf_d 为LCD 数据端口,lcd_e,
lcd_rs,lcd_rs 为1602 控制信号。
具体包含两个模块:一个是键盘接口模块,一个是显示模块,键盘接口模块主要负责获取按键的ASCII 值,显示模块主要负责在LCD 上将该ASCII
值所代表的字符显示出来,具体定义如下所示:。
实例制作一个51单片机连接PS2键盘

实例制作的是用一个AT89C51单片机连接PS/2键盘接口和一个16x2的液晶显示屏,当敲击键盘时,字母可以显示在液晶显示屏上。
这个实例能启发你如何利用单片机来实现对PS/2接口的控制。
实例中提供的源代码修改后可以用到其他PS/2键盘制作项目中。
实例中提供的16x2字符型的液晶显示屏的驱动函数也可以其他项目。
电路原理主电路板中的AT89C51单片机(可以用AT89C52/S51/S52直接替换,如用AT89C2051/4051则需要改程序)组成了51最小化系统。
液晶显示屏于嗯了SMC1602A. 键盘通过PS/2六孔插座和主电路板。
PS/2设备的连接器使用mini-DIN连接器,正有6个引线,其中2个保留为用。
DATA和CLK是可双向通信的I/O线,也就是说通过这两根线,既可以把主机的数据发送到PS/2设备,有可以把设备的数据发向主机。
在无键按下是,DATA 和CLK一直处于高电平状态。
但有键按下时,键盘先检查CLK,看它是否处于高电平,如果是处在低电平,说明主机无空闲接收数据,这是键盘将会把数据放在自己的缓冲区(16Bytes).直到CLK重新被拉高。
键盘获得总线权,这是键盘产生始终信号在CLK上输出。
同时每一个时钟周期在DATA 线上输出一位数据。
第1位是起始位为0,第2-9位为一个八位二进制数据由地位到高位依次输出,第10位为奇偶校验位下面是电路原理图PS/2设备接口用于许多现代的鼠标和键盘,PS/2连接器上有四个管脚:电源地、+5V、数据和时钟。
Host(计算机)提供+5V并且键盘/鼠标的地连接到host的电源地上,数据和时钟都是集电极开路的这就意味着它们通常保持高电平而且很容易下拉到地(逻辑0)。
任何你连接到PS/2鼠标、键盘或host 的设备,在时钟和数据线上要有一个大的上拉电阻。
置“0”就把线拉低,置“1”就让线上浮成高。
从键盘/鼠标发送到主机的数据在时钟信号的下降沿(当时钟从高变到低的时候)被读取;从主机发送到键盘/鼠标的数据在上升沿(当时钟从低变到高的时候)被读取。
北邮数电实验——PS2键盘

实验名称:PS2键盘接口设计姓名:金小敏学号:班级:一、实验任务设计制作一个PS/2 键盘接口控制器。
(a)基本功能按照PS/2 键盘接口标准设计一个控制器,接收PS/2 键盘发送的数据,用数码管和8×8 点阵显示接收到的键值。
其中0~9 用数码管显示,A~Z用8×8 点阵显示,接收到其他键值则不显示。
(b)拓展功能(i)实现显示汉字、符号:按F3显示汉字“中”、按F4显示汉字“国”、按F5显示心型符号;(ii)实现音乐播放控制:按F1开始播放音乐、按F2停止播放音乐。
二、系统设计(a)设计思路系统总的分为输入输出两大部分。
输入即为PS2键盘,输出有显示输出:8×8点阵、数码管,声音输出。
根据PS2的协议,PS2按键的输出包含扫描码和断码,本次实验只使用扫描码。
将扫描码解码出来后,即可作为不同的判断条件来控制输出。
输出包括数码管显示、点阵显示和声音输出。
将其设计为:0~9按键时只有数码管显示对应数字,点阵熄灭;A~Z时只有点阵显示,数码管熄灭;按F1时,开始播放音乐并且点阵显示音乐符号“♫”;按F2时,停止播放音乐并且点阵熄灭;按F3时显示汉字“中”;按F4显示汉字“国”;按F5显示“♡”。
程序设计为四大模块:解码模块、显示模块、分频模块、音乐模块。
(b)总体框图(i)系统模块键盘输入(ii )状态转移图(c)分块设计:(1)PS2解码模块 ①输入输出框图:位)ret:选择信号p_clk:PS2键盘时钟信号 p_dat:PS2键盘数据信号 ②原理及算法:从键盘/鼠标发送到主机的数据在时钟信号的下降沿当时钟从高变到低的时候被读取从主机发送到键盘/鼠标的数据在上升沿当时钟从低变到高的时候被读取不管通讯的方向怎样键盘/鼠标总是产生时钟信号。
一次数据组成为:1位起始位(总为0),8位数据位(低位在前),1位奇校验位,1位停止位(总为1)。
由于本次实验只用到扫描码,所以只要接收第一段数据即可。
键盘接口实验实验报告及程序

键盘接口实验实验报告及程序一、实验目的本次实验的主要目的是深入了解计算机键盘接口的工作原理,并通过编程实现对键盘输入的读取和处理。
通过这个实验,我们将掌握如何与计算机硬件进行交互,提高对计算机系统底层运作的认识。
二、实验原理计算机键盘通常通过 PS/2 接口或 USB 接口与主机相连。
在本次实验中,我们以 PS/2 接口为例进行研究。
PS/2 接口使用双向同步串行协议进行通信,数据传输速率约为 10 167Kbps 。
键盘在向主机发送数据时,每个字节包含 11 位,分别是起始位(总是 0 )、 8 位数据位(低位在前)、校验位(奇校验)和停止位(总是 1 )。
主机通过向键盘发送命令来控制键盘的工作模式和获取相关信息。
三、实验设备及环境1、计算机一台2、开发板及相关配件3、编程软件(如 Keil 等)四、实验步骤1、硬件连接将开发板与计算机通过相应的接口连接好,确保连接稳定。
2、软件编程选择合适的编程语言和开发环境。
初始化相关的硬件接口和寄存器。
编写读取键盘输入数据的程序代码。
3、编译与下载对编写好的程序进行编译,检查是否有语法错误。
将编译成功的程序下载到开发板中。
4、实验测试按下键盘上的不同按键,观察开发板的输出结果。
检查读取到的数据是否准确,校验位是否正确。
五、程序代码实现以下是一个简单的基于 C 语言的键盘接口读取程序示例:```cinclude <reg51h>//定义 PS/2 接口相关引脚sbit PS2_CLK = P1^0;sbit PS2_DATA = P1^1;//读取一个字节的数据unsigned char ReadByte(){unsigned char data = 0;unsigned char i;while(PS2_CLK == 1);//等待时钟线拉低for(i = 0; i < 8; i++){while(PS2_CLK == 0);//等待时钟上升沿data =(data << 1) | PS2_DATA; //读取数据位}while(PS2_CLK == 1);//等待时钟线拉低return data;}void main(){unsigned char key;while(1){key = ReadByte();//读取键盘输入的数据//在此处对读取到的数据进行处理和显示}}```六、实验结果与分析在实验过程中,我们按下不同的键盘按键,开发板能够准确地读取到相应的键值。
基于51单片机的PS2键盘1602显示24c02存储的密码锁设计(附程序)

基于51单片机的PS2键盘密码锁设计摘要:AT89S52是一种低功耗、高性能CMOS 8位微控制器,具有8K在系统可编程Flash 存储器,被广泛应用于各个领域。
LCD1602液晶显示器以其微功耗、体积小、超薄轻巧等诸多优点而备受人们喜爱。
本作品是以AT89S52作为主控芯片,LCD1602作为显示器,以PS2键盘作为输入设备的密码锁。
PS2键盘与AT89S52通过PS2接口协议进行通信,可以完成密码设置,密码重置及显示等诸多功能。
本作品还使用了24C02存储器来实现密码锁的掉电保存功能。
关键词:AT89S52;LCD1602;24C02;PS2键盘Abstract:AT89S52 is a low power,high performance CMOS 8 bit microcontroller, with 8K flash memory, is widely applied in various fields. LCD1602 liquid crystalDisplay with its low power consumption, small size, thin lightweight and many other advantages, is liked by people.This work is based on the AT89S52 as the main chip, the LCD1602 as display, PS2 keyboard as an input device of the cipher lock. PS2 keyboard and AT89S52 through PS2 interface protocolFor communication, can complete password, password reset and display and other functions. This work we also used the 24C02 memory to realize the password lock the power-down save function.Keywork: A T89C52; LCD1602; 24C02;PS/2 keyboard1 实验目的及意义在单片机系统中,经常使用的键盘都是专用键盘.此类键盘为单独设计制作的,成本高、使用硬件连接线多,且可靠性不高,这一状况在那些要求键盘按键较多的应用系统中更为突出.与此相比,在PC系统中广泛使用PS/2键盘具有价格低、通用可靠,且使用连接线少(仅使用2根信号线)的特点,并可满足多种系统的要求.因此在单片机系统中应用PS/2键盘是一种很好的选择.对于单片机初学者的我而言,AT89S52简单易学,非常适合我学习。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PS2接口键盘显示实验一、实验目的1、学习用FPGA设计简单通信协议的方法。
2、学习PS2的工作原理,扫描码的ASCII码的转换。
3、掌握VHDL编写中的一些小技巧。
二、实验原理PS2通信协议是一种双向同步串行通迅协议。
通迅的两端通过CLOCK(时钟信号端)同步,并通过DATA(数据端口)交换数据。
任何一方如果想要抑制另外一方的通迅时,只需要把CLOCK拉到低电平。
PS2标准,规范每笔数据传输包含起始位(start bit)、扫描码(scan code)、奇同位检查(odd parity)、以及终止位(stop bit)共计11位,并以双向串行数据传输的方式,达到通信的目的。
且当主机端(host)或从机端(slave)并无传送或接收数据时,数据传输端口及频率均将升为高电位。
图21-1所示为每一笔数据传输所包含之内容如下:1.起始位(“0”)2.8位数据宽度的扫描码( scan code )。
3.奇同位检查,使扫描码与奇同位加起来1的数字为奇数个。
4.终止位(“1”)图21-1 PS2 串行传输标准Male(Plug)Female(Socket)6-pin Mini-DIN (PS2):1 - Data2 - Not Implemented3 - Ground4 - Vcc (+5V)5 - Clock6 - Not Implemented 图21-2 PS2 端口脚位定义PS2控制接口仅使用到两条传输端口,一为频率端口,另一则为数据端口如图21-2所示,且此传输埠必为三态(Tri-State)并具有双向(bidirectional)特性。
PS2 传输产品上,常见为鼠标与键盘,两者的驱动原理均相同,仅扫描码(scan code)不同。
因此我们以PS2键盘为例进行说明。
键盘其实就是一个大型的按键矩阵,它们由安装在电路板上的处理器(叫做“键盘编码器”)来监视着。
虽然不同的键盘可能采用不同的处理器,但是它们完成的任务都是一样的,即监视哪些按键被按下,哪些按键被释放了,并将这些信息传送到主机。
如果有必要,处理器处理所有的去抖动,并在它的16字节的缓冲区里缓冲数据。
主机端包含了一个“键盘控制器”与键盘处理器进行通讯,并解码来自键盘处理器的信息,然后高速系统当前按键对应的处理事情。
主机与键盘之间的通讯仍旧采用IBM的协议。
键盘处理器花费很多时间来扫描或监视按键矩阵。
如果发现有按键按下、释放或长按,键盘就发送“扫描码”的信息到主机。
扫描码有两种不同的类型:“通码”和“断码”。
当一个键被按下去或长按的时候,键盘就发送通码;当一个键被释放的时候,键盘就发送断码。
每个键盘被分配了唯一的通码和断码,这样主机通过查找唯一的扫描码就可以确定是哪个按键被按下或释放。
每个键一整套的通断码组成了“扫描码集”,现在所有的键盘都采用第二套扫描码。
由于没有一个简单的公式可以计算扫描码,所以要知道某个特定按键的通码和断码,只能采用查表的方法来获得。
需要特别注意的是,按键的通码值表示键盘上的一个按键,并不表示印刷在按键上的那个字符,这就意味着通码和ASCII码之间没有任何关联。
另外,第二套通码都只有一个字节宽,但也有少数“扩展按键”的通码是两字节或四字节宽,这类码的第一个字节总是0xE0。
与通码一样,每个按键在释放的时候,键盘就会发送一个断码。
每个键也都有它自己的唯一的断码,不过庆幸的是,断码与断码之间存在着必然的联系。
多数第二套断码有两个字长,它们的第一个字节是0xF0,第二个字节就是对应按键的通码。
扩展按键的断码通常有三个字节,前两个字节0xE0和0xF0,最后一个字节是这个按键通码的最后一个字节。
表21-1列出了键盘按键的通码和断码。
PS2 键盘扫描码键值通码断码键值通码断码键值通码断码A 1C F0,1C 9 46 F0,46 [ 54 F0,54INSERT67 F0,67B 32 F0,32 ` 0E F0,0EHOME 6E F0,6EC 21 F0,21 - 4E F0,4EPG UP 6F F0,6FD 23 F0,23 = 55 F0,55DELETE64 F0,64F0,5CE 24 F0,24 \ 5CBKSP 66 F0,66 END 65 F0,65F 2B F0,2BG 34 F0,34 SPACE 29 F0,29 PG DN 6D F0,6DH 33 F0,33 TAB 0D F0,0DU ARROW 63 F0,63 I 43 F0,48 CAPS 14 F0,14 L ARROW 61F0,61J 3B F0,3B L SHFT12F0,12D ARROW60 F0,60K 42 F0,42 L CTRL 11 F0,11 R ARROW6A F0,6AL 4B F0,4B L WIN 8B F0,8B NUM 76 F0,76 M 3A F0,3A L ALT 19 F0,19 KP / 4A F0,4A N 31 F0,31 R SHFT 59 F0,59 KP * 7E F0,7E O 44 F0,44 R CTRL 58 F0,58 KP - 4E F0,4E P 4D F0,4D R WIN 8C F0,8C KP + 7C F0,7C Q 15 F0,15 R ALT39F0,39KP EN79 F0,79 R 2D F0,2D APPS 8D F0,8D KP . 71 F0,71 S 1B F0,1B ENTER5A F0,5A KP 070 F0,70 T 2C F0,2C ESC 08 F0,08 KP 1 69 F0,69 U 3C F0,3C F1 07 F0,07 KP 2 72 F0,72 V 2A F0,2A F2 0F F0,0F KP 3 7A F0,7A W 1D F0,1D F3 17 F0,17 KP 4 6B F0,6B X 22 F0,22 F4 1F F0,1F KP 5 73 F0,73 Y 35 F0,35 F5 27 F0,27 KP 6 74 F0,74 Z 1A F0,1A F6 2F F0,2F KP 7 6C F0,6C 0 45 F0,45 F7 37 F0,37 KP 8 75 F0,75 1 16 F0,16 F8 3F F0,3F KP 97DF0,7D2 1E F0,1E F9 47 F0,47 ] 5B F0,5B3 26 F0,26 F10 4F F0,4F ; 4C F0,4C4 25 F0,25 F11 56 F0,56 ' 52 F0,52 5 2E F0,2E F12 5E F0,5E , 41 F0,41 6 36 F0,36PRNT SCRN 57F0,57. 49 F0,497 3D F0,3D SCROLL 5F F0,5F / 4A F0,4A 8 3E F0,3E PAUSE62 F0,62表21-1PS2 键盘扫描码三、实验内容本实验的任务就是利用PS2接口将键盘按键的通码在数码管上显示出来。
实验箱中用到PS2键盘接口与FPGA的接口电路如图21-3所示。
其与FPGA的管脚连接请参照用户使用手册附表二。
图21-3 PS2键盘接口电路图四、实验步骤1、打开QUARTUSII软件,新建一个工程。
2、建完工程之后,再新建一个VHDL File,打开VHDL编辑器对话框。
3、按照实验原理和自己的想法,在VHDL编辑窗口编写VHDL程序,用户可参照光盘中提供的示例程序。
示例程序共提供2个VHDL源程序和一个PLL。
每一个源程序完成一定的功能。
其具体的功能如下表21-3所示:文件名称完成功能keyboard.VHD PS2键盘控制器电路设计。
DISPLAY.VHD 七段显示器译码电路设计。
PLL25 提供25M时钟信号表21-3 示例程序功能表4、编写完VHDL程序后,保存起来。
方法同实验一。
5、将自己编写的VHDL程序进行编译并生成模块符号文件,并对程序的错误进行修改,最终所有程序通过编译并生成模块符号文件。
其具体方法请参照实验六。
6、新建一个图形编辑文件,将已生成的模块符号文件放入其中,并根据要求边接起来。
7、将自己编辑好的的程序进行编译仿真,并对程序的错误进行修改,最终通过编译。
8、编译仿真无误后,依照拨动开关、LED与FPGA的管脚连接表或参照用户手册附录表二进行管脚分配。
分配完成后,再进行全编译一次,以使管脚分配生效。
9、用下载电缆通过JTAG口将对应的sof文件加载到FPGA中。
观察实验结果是否与自己的编程思想一致。
五、 实验结果与现象以设计的参考示例为例,将PS2接口的键盘接入PS2接口内。
当设计文件加载到目标器件后,按下PS2键盘上的键,则在实验平台的八位数码管上的中间两位将显示被按键的扫描码。
观察其按下的键值所对应的扫描码是否与表21-1一一对应。
按下复位键则停止对键盘的扫描,数码管上的扫描码不会发生改变。
六、 实验报告1、绘出仿真波形,并作说明。
2、将实验原理、设计过程、编译仿真波形和分析结果、硬件测试结果记录下来。