0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA学习系列:25. PS2通信电路的设计

FPGA学习交流 2018-08-09 18:59 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

设计背景:

PS2接口是一种PC兼容型电脑系统上的接口,可以用来链接键盘及鼠标。PS2的命名来自于1987年时IBM所推出的个人电脑:PS/2系列。PS2的键盘和鼠标在电气特性上十分类似,主要差别在于键盘接口需要双向的沟通。PS2接口不支持热插拔,使用时需要关机插上,目前已逐渐被USB所替代,只有少部分台式机仍然提供PS2接口。

设计原理:

PS2的接口如下图所示:

上图中,1是数据线DATA;2是预留N/C;3是GND;4是VCC(+5V);5是时钟信号线CLK;6是预留N/C。

PS2原理电路图如下:

image.png

PS2协议总共由两根线组成,从电路原理图中也可以看出,需要控制的只有PS2_CLK和PS2_SDA,即一根时钟线和一根数据线。PS2设备中的时钟和数据都是集电极开路的,平时都是高电平。本设计将采用PS2接口的键盘称为从机,将控制和解码PS2协议的一方称为主机(FPGA)。PS2协议的时钟线始终由从机(即键盘)产生的,PS2协议发送一个字节数据共有11位。时序如下图所示:

image.png

1Bit起始位,总是0;8Bit数据位,低位在前;1Bit校验位,奇校验;1Bit停止位,总是1。

从机(键盘)按照这个时序发送数据,主机(FPGA)只需要实现该协议的解码,即可将其中的8Bit数据位提取出来。根据时序图可以看出,数据在PS2时钟的下降沿是保持稳定的,主机只需在检测到PS2时钟出现下降沿时,去读取数据线上的电平,就可得到正确的数据。

通过上述的内容,已经知道了PS2从机到主机的通信协议,接下来就需要知道从机发送过来的每个字节代表什么?这时就要对照键盘编码表进行查看。键盘上一个按键由按下到释放时,键盘是按照如下的规定向主机发送数据的:

只要一个按键被按下,这个键的通码(MAKE)就会被发送到主机,按键一被释放断码BREAK)也会被发送如果按键被按下不释放的话,键盘会以一定的频率发送那个按键的通码。每个按键都有自己唯一的通码和断码,从而组成键盘编码表,表上的码值为16进制:

image.png


例如,如果键盘上‘A’键被按下时,键盘就会向主机发送‘A’键对应的通码‘1C’,直到按键被释放。在按键被释放后,键盘将会向主机发送‘A’键的断码,即首先发送‘F0’,然后下一个字节发送‘1C’。通过观察键盘编码表,可以发现按键的通码与断码存在一定的联系,多数断码的第一个字节是‘F0’,第二个字节则是这个键的通码。

如果按下键盘上的扩展按键时,如‘END’,当‘END’键被按下后,键盘会首先向主机发送‘E0’,然后发送‘F0’,最后再发送‘69’。 根据上述的分析可知,在主机(FPGA)解码一次数据后,还需要对这个数据进行分析判断,判断该数据是否为断码标志‘F0’以及扩展码标志‘E0’。


设计架构图:

本设计将实现在PS2键盘上按下26个字母任一个,在数码管上显示其对应的ASCII码。架构图如下:

image.png

ps2scan模块是根据PS2的时序协议,将键盘的按键值译成一个8位的数据(out_data)输出;ASCII模块,根据ASCII表,将数据与字母一一对应;seg_num模块将相应的数据在数码管上显示。

设计代码:

ps2scan模块代码:

0moduleps2scan (clk,rst_n,ps2_sclk,ps2_sda,out_data);

1

2//端口信号:模块的输入输出接口

3inputclk;//系统时钟

4inputrst_n;//低电平复位

5inputps2_sclk;//ps2时钟信号(ps2设备自动产生,大约10KHz左右)

6inputps2_sda;//ps2数据信号

7outputreg[7:0]out_data;//键值数据(采集ps2的一帧信号中间的8位有效位)

8

9//在发送时序中,数据在ps2_sclk的下降沿采集信号,以下为检测下降沿

10regin1,in2;

11wireen;

12

13always@(posedgeclk ornegedgerst_n)

14begin

15if(!rst_n)

16begin

17in1 <=1'b0;

18in2 <=1'b0;

19end

20else

21begin

22in1 <=ps2_sclk;

23in2 <=in1;

24end

25end

26

27assignen =(~in1)&in2;//当出现ps2_sclk下降沿后拉高一个时钟,以进行数据的采集

28

29

30//采集ps2的一帧信号中间的8位有效位:每检测一个下降沿算一位数据位,在中间8位采集有效数据

31reg[7:0]temp_data;

32reg[3:0]num;

33

34always@(posedgeclk ornegedgerst_n)

35begin

36if(!rst_n)

37begin

38num <=4'd0;

39temp_data <=8'd0;

40end

41elseif(en)

42case(num)

434'd0:num <=num+1'b1;//开始位

444'd1:begin

45num <=num+1'b1;

46temp_data[0]<=ps2_sda;//bit0

47end

484'd2:begin

49num <=num+1'b1;

50temp_data[1]<=ps2_sda;//bit1

51end

524'd3:begin

53num <=num+1'b1;

54temp_data[2]<=ps2_sda;//bit2

55end

564'd4:begin

57num <=num+1'b1;

58temp_data[3]<=ps2_sda;//bit3

59end

604'd5:begin

61num <=num+1'b1;

62temp_data[4]<=ps2_sda;//bit4

63end

644'd6:begin

65num <=num+1'b1;

66temp_data[5]<=ps2_sda;//bit5

67end

684'd7:begin

69num <=num+1'b1;

70temp_data[6]<=ps2_sda;//bit6

71end

724'd8:begin

73num <=num+1'b1;

74temp_data[7]<=ps2_sda;//bit7

75end

764'd9:num <=num+1'b1;//结束位

774'd10:num <=4'd0;

78default:;

79endcase

80end

81

82//判断是否有键按下:根据通码、断码的特性判断

83regkey;

84

85always@(posedgeclk ornegedgerst_n)

86begin

87if(!rst_n)

88key <=1'b0;

89elseif(num==4'd10)

90begin

91if(temp_data ==8'hf0)

92key <=1'b1;

93else

94begin

95if(!key)

96out_data <=temp_data;

97else

98key <=1'b0;

99end

100end

101end

102

103endmodule


ASCII模块代码:

0moduleASCII(out_data,tx_out);

1

2//端口信号:模块的输入输出接口

3input[7:0]out_data;//键盘的扫描键值

4outputreg[7:0]tx_out;//通过ASCII码转换之后的值

5

6//通过查找表的方式,对照ASCII码将键值转换为二进制数值

7always@(*)

8case(out_data)

98'h1c:tx_out <=8'h41;//A

108'h32:tx_out <=8'h42;//B

118'h21:tx_out <=8'h43;//C

128'h23:tx_out <=8'h44;//D

138'h24:tx_out <=8'h45;//E

148'h2b:tx_out <=8'h46;//F

158'h34:tx_out <=8'h47;//G

168'h33:tx_out <=8'h48;//H

178'h43:tx_out <=8'h49;//I

188'h3b:tx_out <=8'h4a;//J

198'h42:tx_out <=8'h4b;//K

208'h4b:tx_out <=8'h4c;//L

218'h3a:tx_out <=8'h4d;//M

228'h31:tx_out <=8'h4e;//N

238'h44:tx_out <=8'h4f;//O

248'h4d:tx_out <=8'h50;//P

258'h15:tx_out <=8'h51;//Q

268'h2d:tx_out <=8'h52;//R

278'h1b:tx_out <=8'h53;//S

288'h2c:tx_out <=8'h54;//T

298'h3c:tx_out <=8'h55;//U

308'h2a:tx_out <=8'h56;//V

318'h1d:tx_out <=8'h57;//W

328'h22:tx_out <=8'h58;//X

338'h35:tx_out <=8'h59;//Y

348'h1a:tx_out <=8'h5a;//Z

35default:tx_out <=8'h00;

36endcase

37

38endmodule


seg_num模块代码:

0moduleseg_num (clk,rst_n,num,sel,seg);

1

2//端口信号:模块的输入输出接口

3inputclk;//系统时钟50MHz

4inputrst_n;//低电平复位

5input[7:0]num;//输入的数据

6outputreg[2:0]sel;//数码管位选

7outputreg[7:0]seg;//数码管段选

8

9

10//计数分频,通过选择cnt的相应位的变化来大致分频

11reg[23:0]cnt;

12wireclk_r;

13

14always@(posedgeclk ornegedgerst_n)

15begin

16if(!rst_n)

17cnt <=24'd0;

18else

19cnt <=cnt +1'b1;

20end

21

22assignclk_r =cnt[15];//通过计数cnt的第10位来分频计数,2^10/50M

23//通过查找表的方式将数据与相应的数码管显示一一对应

24reg[3:0]data;

25

26always@(*)

27case(data)

284'h0:seg <=8'hC0;//8'b1100_0000

294'h1:seg <=8'hF9;//8'b1111_1001

304'h2:seg <=8'hA4;//8'b1010_0100

314'h3:seg <=8'hB0;//8'b1011_0000

324'h4:seg <=8'h99;//8'b1001_1001

334'h5:seg <=8'h92;//8'b1001_0010

344'h6:seg <=8'h82;//8'b1000_0010

354'h7:seg <=8'hF8;//8'b1111_1000

364'h8:seg <=8'h80;//8'b1000_0000

374'h9:seg <=8'h90;//8'b1001_0000

384'hA:seg <=8'h88;

394'hB:seg <=8'h83;

404'hC:seg <=8'hC6;

414'hD:seg <=8'hA1;

424'hE:seg <=8'h86;

434'hF:seg <=8'h8E;

44default:seg <=8'hFF;//8'b1111_1111

45endcase

46

47//通过查找表的方式,在不同位选下,显示数据的相应位

48always@(*)

49begin

50case(sel)

51000:data <=num[7:4];

52001:data <=num[3:0];

53default:;

54endcase

55end

56

57always@(posedgeclk_r ornegedgerst_n)

58begin

59if(!rst_n)

60sel <=3'd0;

61elseif(sel ==3'd1)

62sel <=3'd0;

63else

64sel <=sel +1'b1;

65end

66

67endmodule


top顶层模块代码:

0moduletop (clk,rst_n,ps2_sclk,ps2_sda,sel,seg);

1

2//外部接口

3inputclk;//系统时钟50MHz

4inputrst_n;//低电平复位

5inputps2_sclk;//ps2时钟

6inputps2_sda;//ps2数据

7output[2:0]sel;//数码管位选

8output[7:0]seg;//数码管段选

9

10wire[7:0]out_data,tx_out;

11

12/*****键盘扫描模块*****/

13ps2scan ps2scan_inst(

14.clk(clk),

15.rst_n(rst_n),

16.ps2_sclk(ps2_sclk),

17.ps2_sda(ps2_sda),

18.out_data(out_data)

19);

20

21/*****数据转ASCII码模块*****/

22ASCII ASCII_inst(

23.out_data(out_data),

24.tx_out(tx_out)

25);

26

27/*****数码管显示模块*****/

28seg_num seg_num_inst(

29.num(tx_out),

30.clk(clk),

31.rst_n(rst_n),

32.sel(sel),

33.seg(seg)

34);

35

36endmodule


top_tb顶层测试代码:

0`timescale1ns/1ns

1

2moduletop_tb;

3

4regclk;

5regrst_n;

6regps2_sda;

7regps2_sclk;

8wire[7:0]seg;

9wire[2:0]sel;

10

11top top_dut(

12.clk(clk),

13.rst_n(rst_n),

14.ps2_sclk(ps2_sclk),

15.ps2_sda(ps2_sda),

16.sel(sel),

17.seg(seg)

18);

19

20initialbegin

21clk =1;

22rst_n =0;

23ps2_sda =1;

24ps2_sclk =1;

25

26#200;

27rst_n =1;

28Key_Event(8'h1A);/* Z */

29#40000;

30Key_Event(8'h22);/* X */

31#80000;

32Key_Event(8'h44);/* O */

33#13200;

34Key_Event(8'h4D);/* P */

35#25600;

36Key_Event(8'h24);/* E */

37#12300;

38Key_Event(8'h31);/* N */

39

40#2000000;

41$stop;

42end

43

44/*---------生成工作时钟-----------*/

45always#10clk =~clk;

46

47/*----任务:以PS2协议发送一个字节的数据-----*/

48taskSend_data;

49input[7:0]data;

50begin

51ps2_sda =0;/*发送起始位*/

52#20000;ps2_sclk =0;

53#40000;ps2_sclk =1;

54

55#20000;ps2_sda =data[0];/*发送第0*/

56#20000;ps2_sclk =0;

57#40000;ps2_sclk =1;

58

59#20000;ps2_sda =data[1];/*发送第1*/

60#20000;ps2_sclk =0;

61#40000;ps2_sclk =1;

62

63#20000;ps2_sda =data[2];/*发送第2*/

64#20000;ps2_sclk =0;

65#40000;ps2_sclk =1;

66

67#20000;ps2_sda =data[3];/*发送第3*/

68#20000;ps2_sclk =0;

69#40000;ps2_sclk =1;

70

71#20000;ps2_sda =data[4];/*发送第4*/

72#20000;ps2_sclk =0;

73#40000;ps2_sclk =1;

74

75#20000;ps2_sda =data[5];/*发送第5*/

76#20000;ps2_sclk =0;

77#40000;ps2_sclk =1;

78

79#20000;ps2_sda =data[6];/*发送第6*/

80#20000;ps2_sclk =0;

81#40000;ps2_sclk =1;

82

83#20000;ps2_sda =data[7];/*发送第7*/

84#20000;ps2_sclk =0;

85#40000;ps2_sclk =1;

86

87#20000;ps2_sda =0;/*暂时忽略校验位*/

88#20000;ps2_sclk =0;

89#40000;ps2_sclk =1;

90

91#20000;ps2_sda =1;/*停止位*/

92#20000;ps2_sclk =0;

93#40000;ps2_sclk =1;

94end

95endtask

96

97/*-----任务:模拟按下按键的操作------*/

98taskpress_key;

99input[7:0]Key_Number;

100begin

101Send_data(Key_Number);

102#50000;

103end

104endtask

105

106/*-----任务:模拟释放按键的操作------*/

107taskrelease_key;

108input[7:0]Key_Number;

109begin

110Send_data(8'hF0);

111#50000;

112Send_data(Key_Number);

113#50000;

114end

115endtask

116

117/*----任务:模拟一次短码的按下和释放操作-----*/

118taskKey_Event;

119input[7:0]Key_Number;

120begin

121press_key(Key_Number);

122#30000;

123release_key(Key_Number);

124end

125endtask

126

127endmodule

仿真:

仿真结果如下图:


测试文件中发送的Z’、‘X’、‘O’、‘P’、‘E’、‘N’等字母,在仿真图中显示,通过与ASCII码表对应,得知是正确的。分配引脚,下板后,数码管也得到了与之对应的ASCII码值。

image.png



声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1665

    文章

    22594

    浏览量

    641513
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用IIC与max96752通信存在问题为什么

    Category: Datasheet/Specs Product Number: max96752, max967, max967 使用IIC与max96752通信,问题: (1)发现有
    发表于 06-02 07:31

    【紫光HiYou开源入门轻量级PCIE开发板PG2L25G】实验例程8-PCIE 通信测试

    国产FPGA开发板OPHW-25H问世,开启开源开发新时代 在5G、AI及低空经济快速发展的背景下,小眼睛科技联合紫光同创推出的OPHW-25H开发板成为国产FPGA技术的重要突破。这
    的头像 发表于 05-21 18:36 109次阅读
    【紫光HiYou开源入门轻量级PCIE开发板PG<b class='flag-5'>2L25</b>G】实验例程8-PCIE <b class='flag-5'>通信</b>测试

    【紫光HiYou开源入门轻量级PCIE开发板PG2L25G】实验例程3-基于紫光FPGA 的UART 串口通信

    显示。开发板采用紫光同创Logos-2系列芯片,提供高性价比的国产FPGA学习平台,助力5G、AI等领域的技术创新。
    的头像 发表于 05-20 14:27 3687次阅读
    【紫光HiYou开源入门轻量级PCIE开发板PG<b class='flag-5'>2L25</b>G】实验例程3-基于紫光<b class='flag-5'>FPGA</b> 的UART 串口<b class='flag-5'>通信</b>

    CW25 R2评估板:轻松探索CW25 R2模块功能

    CW25 R2模块的各种功能的。 文件下载: CW25-EVAL BOARD.pdf 评估板概述 CW25 R2评估板的设计初衷是为了让我们
    的头像 发表于 05-12 11:55 348次阅读

    兆芯全系列CPU深度适配统桌面操作系统V25

    这款号称国内操作系统里程碑式版本的统桌面操作系统V25在智能化、高效性、可靠性三个维度实现了突破,推动国内操作系统从“可用”全面迈向“成熟与智能”的发展新阶段。V25桌面操作系统与兆芯全系列
    的头像 发表于 04-15 18:03 1130次阅读

    深入解析IGLOO2 FPGA与SmartFusion2 SoC FPGA:性能、特性与应用

    的表现。 文件下载: M2S090-1FG676IX417.pdf 一、产品概述 IGLOO2 FPGA和SmartFusion2 SoC FPGA
    的头像 发表于 04-07 11:55 329次阅读

    探索Altech PS - 75系列电源:功能、规格与设计考量

    探索Altech PS - 75系列电源:功能、规格与设计考量 在电子工程领域,电源的选择和设计是确保设备稳定运行的关键环节。今天,我们来深入了解Altech的PS - 75系列电源,
    的头像 发表于 03-30 14:20 298次阅读

    探索Altech PS - 60系列电源:性能与设计解析

    探索Altech PS - 60系列电源:性能与设计解析 在电子设备的设计与应用中,电源模块的性能和稳定性至关重要。Altech的PS - 60系列电源以其丰富的功能和出色的性能,成为
    的头像 发表于 03-29 09:10 274次阅读

    PSOC 4100PS系列微控制器

    PSOC 4100PS系列微控制器PSoC 4100PS系列微控制器是英飞凌(原Cypress)推出的一款基于32位Arm® Cortex®-M0+内核的可编程片上系统(PSoC),具
    发表于 03-11 09:45

    Microsemi IGLOO2 FPGA与SmartFusion2 SoC FPGA深度剖析

    : M2S025TS-FCS325I.pdf 一、产品概述 Microsemi的IGLOO2 FPGA和SmartFusion2 SoC FPGA
    的头像 发表于 02-09 17:20 614次阅读

    ST25DV系列NFC/RFID标签IC:开启高效通信新时代

    ST25DV系列NFC/RFID标签IC:开启高效通信新时代 在当今物联网飞速发展的时代,NFC/RFID技术作为数据交互的重要手段,得到了广泛的应用。ST25DV04K、ST
    的头像 发表于 02-05 15:40 608次阅读

    解析SN65HVD2x系列:RS-485通信的理想解决方案

    解析SN65HVD2x系列:RS-485通信的理想解决方案 在工业自动化、安防网络等诸多领域,可靠的通信是系统稳定运行的关键。RS-485作为一种常用的
    的头像 发表于 12-30 11:15 566次阅读

    深度剖析SN65HVD2x:RS - 485通信的理想之选

    深度剖析SN65HVD2x:RS - 485通信的理想之选 在工业通信领域,RS - 485标准凭借其出色的抗干扰能力和长距离传输特性,成为了众多工程师的首选。而德州仪器(TI)的SN65HVD
    的头像 发表于 12-30 10:30 478次阅读

    村田LQW15AN系列电感:高频射频电路低损耗解决方案

    、卫星通信等高频需求,具体分析如下: 一、核心特性:高频低损耗的基石 1、超高Q值,降低高频损耗 Q值是衡量电感能量损耗的关键指标,Q值越高,损耗越低。LQW15AN系列在1GHz频率下Q值可达80以上,部分型号(如LQW15AN2
    的头像 发表于 12-04 16:10 1052次阅读
    村田LQW15AN<b class='flag-5'>系列</b>电感:高频射频<b class='flag-5'>电路</b>低损耗解决方案

    使用Xilinx 7系列FPGA的四位乘法器设计

    随着 IoT、边缘计算等应用对低位宽、高并行、高效率算术运算的需求攀升,基础算术电路,如 4 位乘法,如何在 FPGA 上做到“资源最小化+速度极致”便成为一道新的挑战。来自日本州大学
    的头像 发表于 11-17 09:49 3778次阅读
    使用Xilinx 7<b class='flag-5'>系列</b><b class='flag-5'>FPGA</b>的四位乘法器设计