tag 标签: 矩阵键盘

相关帖子
相关博文
  • 热度 21
    2016-3-28 13:11
    836 次阅读|
    0 个评论
    1 keyboard 2 多位加法器 keyboard遇到的问题 1 col在循环扫描,因此当有按键按下的时候,row应该有三个tq的高电平,一个tq的低电平,因此要合理选择后抖消除开始的条件 2 前抖开始的条件,输入信号和输入缓存信号不相等 3 后抖开始的条件,当col == col_tmp的时候,row == 1‘b1; 4 col,row的缓存时间 5 输出数字和输出数字有效的flag要保持在同样的时钟边沿,flag为握手信号证明输出num有效 总结: 1 善用握手信号 2 按键模型和矩阵键盘的原理
  • 热度 25
    2014-8-23 21:47
    3046 次阅读|
    1 个评论
    最近在北京至芯科技参加20140712届的FPGA培训,其中夏老师课程的第一个项目就是设计一个基于FPGA的简易计算器,要求能够实现0—999999以内的整数+、-、*、/运算,并支持连续运算(连加、连减、连乘、连除)。接到题目后,我首先对设计需要的硬件进行了初步划分,初步确定了如图(1)所示的板级硬件结构。 图(1)板级硬件结构   当板级硬件结构确定之后,就该设计具体的计算器架构了。这里有两种观点,观点一是由顶自下的设计方式,即先设计顶层模块,然后再一级一级的往下设计。这种设计观念是有着多年丰富工程实践经验的李凡老师所推荐的,另一种观点是我自己的观点,也是结合本设计题目的实际情况,因为系统中涉及到了5个外设硬件模块的驱动,虽然此前还在大学里时已经都做过这些模块的驱动设计,但此次来到至芯科技,我决定还是依照夏老师讲的规范科学的设计方法,重新来设计所有的模块驱动。因为以前自己做的时候,模块设计意识不是很强,设计出来的模块不便于移植,因此,此番重做也是理所应当,既然要设计,就要设计一系列通用性强,便于移植的模块,方便以后使用。于是,接下来的任务,首先就是设计5个硬件模块的驱动。 关于驱动设计的先后顺序,是一个值得思考的地方。数码管设计可以采用仿真加板级验证的方式来设计,数码管模块的仿真比较容易做,也容易验证,led、蜂鸣器的验证就更简单,难点在于按键驱动的验证。因为按键在按下的过程中必然存在抖动,要想能够确保设计的正确性,除了仿真外,实际观察按键效果会是一个更加有效的验证方式。而观察按键效果,可以采用将按键检测模块检测到的按键信息显示在数码管或led上来实现。因此,我在设计的时候,首先设计的是数码管模块。(led模块由于过于简单,实在没必要单独为其建一个模型) 数码管的硬件电路目前在实验室的机器上,暂时没工夫再去绘制一份,所以今天先把代码贴上来,等明天把图弄来了再补上。 以下是代码片段: //数码管扫描模块 module shumaguan(data,i_clk,rst_n,o_seg,o_sel);  input data;  input i_clk;  input rst_n;  output o_seg;  output o_sel;  parameter cnt1_WIDTH = 15;  parameter cnt1_MAX = 24999;  reg cnt1;  reg clk_1K;//扫描时钟,1KHz  reg sel_r;//数码管位选  reg seg_r;//数码管段选  reg disp_data;//单位显示数据缓存  //1KHz时钟分频计数器  always@(posedge i_clk)  begin   if(!rst_n)cnt1=0;   else if(cnt1==cnt1_MAX)cnt1=0;   else cnt1=cnt1+1'b1;  end  //得到1KHz时钟  always@(posedge i_clk)  begin   if(!rst_n)clk_1K=0;   else if(cnt1==cnt1_MAX)    clk_1K=~clk_1K;   else ;  end  //位选信号控制  always@(posedge clk_1K)  begin   if(!rst_n)sel_r=3'd0;   else    if(sel_r == 3'd6)     sel_r=3'd0;    else     sel_r=sel_r+1'b1;  end  //根据不同的数码管位选择不同的待显示数据  always@(*)  begin   case(sel_r)    0:disp_data=data ;    1:disp_data=data ;    2:disp_data=data ;    3:disp_data=data ;    4:disp_data=data ;    5:disp_data=data ;    default :disp_data=4'd0;   endcase  end  //数据译码,将待显示数据翻译为符合数码管显示的编码  always@(disp_data)  begin   case(disp_data)    4'd0:  seg_r=8'hc0;    4'd1:  seg_r=8'hf9;    4'd2:  seg_r=8'ha4;    4'd3:  seg_r=8'hb0;    4'd4:  seg_r=8'h99;    4'd5:  seg_r=8'h92;    4'd6:  seg_r=8'h82;    4'd7:  seg_r=8'hf8;    4'd8:  seg_r=8'h80;    4'd9:  seg_r=8'h90;    4'd10: seg_r=8'h88;    4'd11: seg_r=8'h83;    4'd12: seg_r=8'hc6;    4'd13: seg_r=8'ha1;    4'd14: seg_r=8'h86;    4'd15: seg_r=8'h8e;    default : seg_r=8'hff;   endcase  end  assign o_seg = seg_r;  assign o_sel = sel_r; endmodule   因为今天准备比较仓促,到时很多仿真文件都不在手头,等明天去教室把需要的资料弄好之后再来系统的写。 初次写博客,确实感觉准备不足,不过初稿写了,总会有这样那样的不足,于是就非得去丰富去改正所以,这样下去,我相信,我会很快习惯并爱上写博客的。
  • 热度 22
    2012-5-23 19:28
    1864 次阅读|
    2 个评论
    如果用单片机来写这个程序,我们会这么写,先输出col,再检测row行值。同样上面的Verilog代码目的也是要实现这个时序,但恰恰是检测 row在输出col之前。所以对这个代码进行修改的话就是让它满足,先输出col,再检测row的时序。我们可以通过插入额外的状态来实现,修改后的代码 如下:   /*************************************************/          parameter NO_KEY_PRESSED=4'b0000;//没有键按下        parameter SET_COL0      =4'b0001;        parameter SCAN_COL0     =4'b0010;//扫描第 0 列        parameter SET_COL1      =4'b0011;        parameter SCAN_COL1     =4'b0100;//扫描第 1 列        parameter SET_COL2      =4'b0101;        parameter SCAN_COL2     =4'b0110;//扫描第 2 列        parameter SET_COL3      =4'b0111;        parameter SCAN_COL3     =4'b1000;//扫描第 3 列        parameter SET_ALL       =4'b1001;        parameter KEY_PRESSED   =4'b1010;//有键按下   /*************************************************/               reg current_state,next_state;  //现态和次态          /*************************************************/        always @(posedge key_clk or negedge rst_n)               if(!rst_n)                      current_state=SET_ALL;               else                      current_state=next_state;   /*************************************************/                  always @ (current_state)     //根据条件转移状态               case (current_state)                      SET_ALL :                                    next_state=NO_KEY_PRESSED;                        NO_KEY_PRESSED:      //没有键按下                                                     if(row!=4'hf)                                    next_state=SET_COL0;                                 else                                    next_state=SET_ALL;                        SET_COL0:                            next_state=SCAN_COL0;                      SCAN_COL0:           //扫描第 0 列                             if(row!=4'hF)                                    next_state=KEY_PRESSED;                             else                                    next_state=SET_COL1;                            SET_COL1:                            next_state=SCAN_COL1;                                  SCAN_COL1:          //扫描第 1 列                             if(row!=4'hF)                                    next_state=KEY_PRESSED;                             else                                    next_state=SET_COL2;                      SET_COL2:                            next_state=SCAN_COL2;                                  SCAN_COL2:         //扫描第 2 列                             if(row!=4'hF)                                    next_state=KEY_PRESSED;                             else                                    next_state=SET_COL3;                            SET_COL3:                            next_state=SCAN_COL3;                                  SCAN_COL3:        //扫描第 3 列                             if(row!=4'hF)                                    next_state=KEY_PRESSED;                             else                                    next_state=NO_KEY_PRESSED;                            KEY_PRESSED:      //有按键按下                             if(row!=4'hf)                                    next_state=KEY_PRESSED;                             else                                    next_state=SET_ALL;                                endcase   /*************************************************/               reg key_pressed_flag; //按键按下标志               reg col_val;      //列值               reg row_val;     //行值   /*************************************************/               //根据次态,给相应的寄存器赋值 /*************************************************/               always @(posedge key_clk or negedge rst_n)                      if(!rst_n)       //复位                             begin                             col=4'h0;                             key_pressed_flag=0;                             end                      else begin                             case (next_state)                                    SET_ALL : col=4'b0000 ;                                                           NO_KEY_PRESSED:                                           begin                                           key_pressed_flag=0;                                           end                                    SET_COL0 : col=4'b1110 ;                                                                         SCAN_COL0: ;      //扫描第 0 列                                             SET_COL1 : col=4'b1101;                                    SCAN_COL1: ;      //扫描第 1 列                                    SET_COL2 : col=4'b1011;                                    SCAN_COL2: ;            //扫描第 2 列                                    SET_COL3 : col=4'b0111;                                    SCAN_COL3: ;       //扫描第 3 列                                    KEY_PRESSED:     //有按键按下                                           begin                                           col_val=col; // 锁存列值                                           row_val=row; // 锁存行值                                           key_pressed_flag=1;         // 置键盘按下标                                               end                                    end                              endcase   话说终于可以松口气了…喝口雪碧…   等等!好像有什么不对,为什么以前写状态机没遇到过这种情况呢? 我左想友想上想下想,跟以前的状态机一比较,还真发现问题了。   比如说典型的售货机,投进去多少钱(当然要是它能认的,不认的它可不收),币值是多少,顺序咋样,谁说了算?当然是我们说了算,售货机只管钱够不够,够了就吐东西,不够继续等待投币。也就是说输出跟输入没有半毛关系。   再看这个按键检测,输入的数据,不仅受按键是否按下、哪个键按下有关,还跟此时Col的输出有关,而输出又要受状态控制,这就是症结所在了。   哎 ,算是彻底的解脱了,但以后碰到这种输入与输出相关的状态机,还得多加注意时序啊!  
  • 热度 20
    2012-5-23 19:25
    1722 次阅读|
    0 个评论
    可一到运行起来就蛋疼了,呵呵…. 下面分析一下,仅供参考,若有不对,敬请指正!   看上面时序图在 1、第0~2个时钟周期内 row(输入)为4’b1111代表无键按下,next_state=NO_KEY_PRESSED,Current_state= NO_KEY_PRESSED无限循环…. 2、在3个时钟周期内 第3个上升沿之后(注意是“之后”),假设第1列、第1行的键按下,此时row=’4b1101, next_state=SCAN_COL0, urren_state=NO_KEY_PRESSED; col=4’b0000 ; 3、在4个上升沿时 因为col=4’b0000; row=4’b1101 ;所以next_state=KEY_PRESSED ; 此时current_state = SCAN_COL0 。 4、在第5个上升沿时 Curren_state=SCAN_COL0生效,即col=4’b1110 ; 同时current_state=KEY_PRESSED 。 5、第6个上升沿 因为col=4’1110 , row=4’b1101 ,(前面说过是第1列、第1行的键按下),所以row==4’hF, next_state=NO_KEY_PRESSED; 同时current_state=KEY_PRESSED生效,装载值col_val=4’b1110, row_val=4’b1101;很显然这个值不对,(正确的应该是col_val=4’b1101, row_val=4’b1101)。   大家有没有发现到第6个上升沿的时候,本来next_state应该要跳转到SCAN_COL1但是现在是跳转到NO_KEY_PRESSED,也就是说SCAN_COL1状态被跳过了,状态只能在NO_KEY_PRESSED和SCAN_COL0之间切换。   经过分析发现,是Col值的变化延迟导致的,换句话说,如果col的变化能在下一次判断nex_state(第4个上升沿)之前及时变化的话,状态的判断就不会出错。  
  • 热度 19
    2012-3-18 14:45
    5052 次阅读|
    2 个评论
    //write by dragonbao 2011-9-16. 这是硬件上的键盘规划 // | 1 | 2 | 3 | 4 | ---line 1 PE6 // // --------------------------- // // | 5 | 6 | 7 | 8 | ---line 2 PE5 // // --------------------------- // // | 9 | 10| 11| 12| ---line 3 PE4 // // --------------------------- // // | 13| 14| 15| 16| ---line 4 PE3 // // --------------------------- // // | 17| 18| 19| 20| ---line 5 PE2 // // --------------------------- // // | | | | // // col1 col2 col3 col4 // // PE0 PB5 PB8 PB9 // //_________________________________________________// 参考了下基于avr的矩阵键盘程序,耐着性子移植到符合上面硬件规划的stm32板子上。 volatile uint8_t key_flag = 0; void key_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; //key output GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_Init(GPIOE,GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_Init(GPIOB,GPIO_InitStructure); //key input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6; GPIO_Init(GPIOE,GPIO_InitStructure); } //判断是否有键按下函数,对键盘进行一次扫描 //返回键盘接口状态,有键按下时返回键值;没有键按下返回无效标志位 uint8_t Is_Key_PressOn(void) { volatile uint8_t i,ScanCode; for(i=0;i4;i++) { switch(i) //扫描信号产生 { case 0: GPIOE-BSRR = 0x00010000;//PE0 = 0; GPIOB-BSRR = 0x00000320;//PB5 = 1; PB8 = 1; PB9 = 1; key_flag = 1; break; case 1: GPIOE-BSRR = 0x00000001;//PE0 = 1; GPIOB-BSRR = 0x00200300;//PB5 = 0; PB8 = 1; PB9 = 1; key_flag = 2; break; case 2: GPIOE-BSRR = 0x00000001;//PE0 = 1; GPIOB-BSRR = 0x01000220;//PB5 = 1; PB8 = 0; PB9 = 1; key_flag = 3; break; case 3: GPIOE-BSRR = 0x00000001;//PE0 = 1; GPIOB-BSRR = 0x02000120;//PB5 = 1; PB8 = 1; PB9 = 0; key_flag = 4; break; default: key_flag = 0; break; } if((((uint8_t)GPIOE-IDR)|0x83)!=0xff) return ((uint8_t)GPIOE-IDR | 0x83); } return(PRESS_INVALID); } //找到闭合键,判断延时前后两次键值是否相同,如果相同则返回键值 uint8_t Find_Key_PressOn(uint8_t KeyCode_before,uint8_t KeyCode_after) { if(KeyCode_before==KeyCode_after) return(KeyCode_after); else return(PRESS_INVALID); } //计算键值,根据返回的键值计算相应的返回值 uint8_t Calc_Key_PressOn(uint8_t KeyCode) { uint8_t TempNum; switch(KeyCode) { case 0xBF: if(1==key_flag) { TempNum = 1;break; } else if(2==key_flag) { TempNum = 2;break; } else if(3==key_flag) { TempNum = 3;break; } else if(4==key_flag) { TempNum = 4;break; } else break; case 0xDF: if(1==key_flag) { TempNum = 5;break; } else if(2==key_flag) { TempNum = 6;break; } else if(3==key_flag) { TempNum = 7;break; } else if(4==key_flag) { TempNum = 8;break; } else break; case 0xEF: if(1==key_flag) { TempNum = 9;break; } else if(2==key_flag) { TempNum = 10;break; } else if(3==key_flag) { TempNum = 11;break; } else if(4==key_flag) { TempNum = 12;break; } else break; case 0xF7: if(1==key_flag) { TempNum = 13;break; } else if(2==key_flag) { TempNum = 14;break; } else if(3==key_flag) { TempNum = 15;break; } else if(4==key_flag) { TempNum = 16;break; } else break; case 0xFB: if(1==key_flag) { TempNum = 17;break; } else if(2==key_flag) { TempNum = 18;break; } else if(3==key_flag) { TempNum = 19;break; } else if(4==key_flag) { TempNum = 20;break; } else break; default : TempNum=0;break; //发生错误时返回,无效标志 } return(TempNum); //正常返回值为1~16 } //键盘扫描主程序 uint8_t Keyboard(void) { uint8_t key_temp; //暂存键值的变量 key_temp=Is_Key_PressOn(); //判断是否有键闭合 // PORTC=key_temp; 调试过程中使用,正常运行时没用可以删除 if (key_temp==PRESS_INVALID) //判断该次扫描中是否有键按下 return(PRESS_INVALID); //没有闭合则建立无效标志 else delay_nus(100); //闭合则延时 key_temp=Find_Key_PressOn(key_temp,((uint8_t)GPIOE-IDR | 0x83)); //找到闭合键 if (key_temp==PRESS_INVALID) return(key_temp); //若延时前后键值不相等则返回无效标志 else key_temp=Calc_Key_PressOn(key_temp); //有效则计算键值 while((((uint8_t)GPIOE-IDR)|0x83)!=0xff)//等待键放。。。看实际情况使用 { delay_nus(10); } return(key_temp); //返回键值 } 。。。。。。。 有更好建议或意见的请不吝指出。。。。  
相关资源
  • 所需E币: 2
    时间: 2023-4-20 14:10
    大小: 159.56KB
    上传者: 木头1233
    基于FPGA的44矩阵键盘8位动太显示源代码
  • 所需E币: 2
    时间: 2023-4-20 13:58
    大小: 117.94KB
    上传者: 木头1233
    基于51单片机4x4矩阵键盘实验设计资料源程序
  • 所需E币: 0
    时间: 2023-4-20 13:58
    大小: 116.83KB
    上传者: 木头1233
    基于51单片机4X4矩阵键盘(查表法)设计资料源程序
  • 所需E币: 1
    时间: 2023-4-17 09:22
    大小: 374.8KB
    上传者: 张红川
    嵌入式linux下基于单片机的矩阵键盘与ARM的串行通信.pdf
  • 所需E币: 1
    时间: 2022-8-19 14:44
    大小: 49.1KB
    上传者: xyzzyxaaa
    Protues仿真实例(8051)-4X4矩阵键盘.zip
  • 所需E币: 1
    时间: 2022-8-3 18:54
    大小: 22.23KB
    上传者: xyzzyxaaa
    实验5.LCD1602显示矩阵键盘键值.zip
  • 所需E币: 1
    时间: 2022-7-31 11:03
    大小: 14.2KB
    上传者: xyzzyxaaa
    检测独立按键与矩阵键盘.zip
  • 所需E币: 1
    时间: 2022-7-31 10:51
    大小: 53.69MB
    上传者: xyzzyxaaa
    矩阵键盘(实践编程).zip
  • 所需E币: 1
    时间: 2022-7-31 10:50
    大小: 22.95MB
    上传者: xyzzyxaaa
    矩阵键盘(理论课程).zip
  • 所需E币: 0
    时间: 2022-3-10 21:52
    大小: 250KB
    上传者: samewell
    矩阵键盘技术资料PPT.ppt
  • 所需E币: 0
    时间: 2021-3-20 20:18
    大小: 25.36KB
    上传者: samewell
    ProtelDXP程序_矩阵键盘
  • 所需E币: 1
    时间: 2020-12-26 23:02
    大小: 289.2KB
    上传者: Argent
    喜欢Arduino开发的工程师有福咯,本人收集了一些有关Arduino开发的综合资料,Arduino是一个准标准的软硬件开发平台,类似VC开发Windows软件一样的平台,集成各类库文件。ArduinoIDE可以在Windows、MacintoshOSX、Linux三大主流操作系统上运行。
  • 所需E币: 1
    时间: 2020-12-26 23:54
    大小: 150.62KB
    上传者: zendy_731593397
    单片机新手入门实例详解之三4×4矩阵键盘的工作原理与编程
  • 所需E币: 0
    时间: 2020-9-12 00:59
    大小: 24.42KB
    上传者: kaidi2003
    ProtelDXP程序_矩阵键盘.rar
  • 所需E币: 0
    时间: 2020-9-8 14:16
    大小: 24.3KB
    上传者: samewell
    矩阵键盘技术资料.rar
  • 所需E币: 1
    时间: 2020-8-21 23:24
    大小: 816.72KB
    上传者: Argent
    本人从事电子行业多年,由电子硬件开发到软件设计,从工业控制到智能物联,收集了不少单片机产品的开发资料,希望通过这个平台,能够帮助到更多志同道合的网友,资料不在于多而在于精,有需要的老铁们可以下载下来参考参考。
  • 所需E币: 5
    时间: 2019-12-25 10:58
    大小: 2.23MB
    上传者: 16245458_qq.com
    单片机课程设计__电子密码锁报告基于单片机控制的电子密码锁摘要:本系统由单片机系统、矩阵键盘、LED显示和报警系统组成。系统能完成开锁、超时报警、超次锁定、管理员解密、修改用户密码基本的密码锁的功能。除上述基本的密码锁功能外,还具有调电存储、声光提示等功能,依据实际的情况还可以添加遥控功能。本系统成本低廉,功能实用关键词:AT89S51,AT24C02,电子密码锁,矩阵键盘一、引言随着人们生活水平的提高,如何实现家庭防盗这一问题也变的尤其的突出,传统的机械锁由于其构造的简单,被撬的事件屡见不鲜,电子锁由于其保密性高,使用灵活性好,安全系数高,受到了广大用户的亲呢。设计本课题时构思了两种方案:一种是用以AT89s51为核心的单片机控制方案;另一种是用以74LS112双JK触发器构成的数字逻辑电路控制方案。考虑到数字电路方案原理过于简单,而且不能满足现在的安全需求,所以本文采用前一种方案。二、方案论证与比较方案一:采用数字电路控制。其原理方框图如图1-1所示。[pic]图2-1数字密码锁电路方案采用数字密码锁电路的好处就是设计简单。用以74LS112双JK触发器构成的数字逻辑电路作为密码锁的核心控制,共设了9个用户输入键,其中只有4个是有效的密码按键,其它的都是干扰按键,若按下干扰键,键盘输入电路自动清零,原先输入的密码无效,需要重新输入;如果用户输入密码的时间超过40秒(一般情况下,用户不会超过40秒,若用户觉得不便,还可以修改)电路将报警80秒,若电路连续报警三次,电路将锁定键盘5分钟,防止他人的非法操作。电路由两大部分组成:密码锁电路和备用电源(UPS),其中设置UPS电源是为了防止因为停电造成的密码……
  • 所需E币: 4
    时间: 2019-12-25 10:57
    大小: 372KB
    上传者: 2iot
    用单片机控制直流电机用单片机控制直流电机摘要本设计以AT89C51单片机为核心,以4*4矩阵键盘做为输入达到控制直流电机的启停、速度和方向,完成了基本要求和发挥部分的要求。在设计中,采用了PWM技术对电机进行控制,通过对占空比的计算达到精确调速的目的。1.设计方案比较与分析:1、电机调速控制模块:方案一:采用电阻网络或数字电位器调整电动机的分压,从而达到调速的目的。但是电阻网络只能实现有级调速,而数字电阻的元器件价格比较昂贵。更主要的问题在于一般电动机的电阻很小,但电流很大;分压不仅会降低效率,而且实现很困难。方案二:采用继电器对电动机的开或关进行控制,通过开关的切换对小车的速度进行调整。这个方案的优点是电路较为简单,缺点是继电器的响应时间慢、机械结构易损坏、寿命较短、可靠性不高。方案三:采用由达林顿管组成的H型PWM电路。用单片机控制达林顿管使之工作在占空比可调的开关状态,精确调整电动机转速。这种电路由于工作在管子的饱和截止模式下,效率非常高;H型电路保证了可以简单地实现转速和方向的控制;电子开关的速度很快,稳定性也极佳,是一种广泛采用的PWM调速技术。兼于方案三调速特性优良、调整平滑、调速范围广、过载能力大,因此本设计采用方案三。2、PWM调速工作方式:方案一:双极性工作制。双极性工作制是在一个脉冲周期内,单片机两控制口各输出一个控制信号,两信号高低电平相反,两信号的高电平时……
  • 所需E币: 3
    时间: 2019-12-25 00:16
    大小: 3.1KB
    上传者: rdg1993
    矩阵键盘控制数码管显示……
  • 所需E币: 3
    时间: 2020-1-6 12:07
    大小: 614.08KB
    上传者: 2iot
    矩阵键盘的工作原理与编程……