第四章 矩阵键盘

合集下载

第四章 矩阵键盘

第四章 矩阵键盘

一.键盘电路基础
4.按键消抖
(1).抖动的原因:由于按键的机械特性,其机 械触点不能够立刻完全闭合或断开,因此会产 生一系列的电平抖动信号。
一. 键盘电路基础
(2).消抖办法
硬件消抖:在键数较少时可用硬件方法消除键 抖动。如图所示。
一. 键盘电路基础
软件消抖 在软件中编写键盘消抖处理程序,因为 在嵌入式系统中,大部分产品使用的都 是价格便宜且容易发生抖动的开关按键。 如果键盘能够在进行消抖处理后还能正 确地读取所按下的键值,则表明该键被 按下。
读取P1
存储第四行 键盘状态值
存储第三行 键盘状态值
存储第二行 键盘状态值
存储第一行 键盘状态值
否 有键按下 是
主程序
第四章 键盘开发与设计
教学目录
1.键盘电路基础 2.键盘电路的硬件设计 3.键盘电路的软件设计
重难点
1.键盘的原理及抖动处理 2.矩阵键盘的硬件设计 3.矩阵键盘的软件设计
一. 键盘电路基础
1.键盘的作用 键盘是嵌入式系统中人机交互界面不可 缺少的外围设备,客户可以通过键盘进 行数据输入、命令控制、程序生产等操 作,是非常重要的输入工具。
程序开始
否 按键按下 是
延时
否 按键按下是
主程序
二. 键盘电路设计方法
3.阵列式键盘接口电路设计 按键开关被组合成了行和列的矩阵,单 片机的I/O接口一部分作为行线,一部分 作为列线,按键布置在行线和列线的交 叉点上。行列式键盘中的按键数量可以 达到行线数与列线数的乘积。
二. 键盘电路设计方法
4.阵列式键盘的软件设计
读取阵列式键盘的按键值,必须采用扫描键值 的方式。下面以扫描第四行为例: 首先置单片机的P1_3口为低,其他引脚都为高, 然后再读取P1口的值,与该行各个键盘按下后 P1口的值相匹配。

4X4扫描式矩阵键盘课程设计

4X4扫描式矩阵键盘课程设计

4X4扫描式矩阵键盘课程设计课程设计名称: 4_4扫描式矩阵键盘设计姓名:DUKE班级:电子1008班学号:*****成绩:日期:2014年1月6日摘要随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,式设施现代化的基础,也是人类通往科技巅峰的直通路。

电子行业的发展从长远来看很重要,但最主要的还是科技问题。

矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。

是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。

矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N个按键,显示在LED数码管上。

单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。

4*4矩阵式键盘采用AT89C51单片机为核心,主要由矩阵式键盘电路、译码电路、显示电路等组成,软件选用C语言编程。

单片机将检测到的按键信号转换成数字量,显示于LED显示器上。

该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。

目录第一章:系统功能要求--------------------------------------------------------1.1 4*4 矩阵式键盘系统概述------------------------------------------------1.2 本设计任务和主要内容--------------------------------------------------- 第二章:方案论证--------------------------------------------------------------- 第三章:系统硬件电路的设计------------------------------------------------ 3.1 单片机控制系统原理-----------------------------------------------------3.2 原理图绘制说明---------------------------------------------------------- 3.3 画出流程图----------------------------------------------------------------3.4 原理图绘制--------------------------------------------------------------- 第四章:系统程序的设计------------------------------------------------------4.1 程序的编写步骤----------------------------------------------------------- 4.2 编写的源程序-------------------------------------------------------------- 第五章:调试及性能分析------------------------------------------------------第六章:心得体会---------------------------------------------------------------参考文献----------------------------------------------------------------------------第一章:系统功能要求1.1 4*4 矩阵式键盘系统概述AT89C51单片机对4*4矩阵键盘进行动态扫描,当有按键盘的键时,可将相应按键值(0~F)实时显示在数码管上。

《矩阵键盘》课件

《矩阵键盘》课件

游戏机按键通常配备震动反馈 功能,提供触觉反馈,增强游 戏体验的真实感。
工业控制设备
工业控制设备如自动 化仪表、数控机床等 也采用矩阵键盘布局 。
工业控制设备的矩阵 键盘通常防水、防尘 ,适应恶劣的工业环 境。
矩阵键盘的设计使得 工业控制设备能够实 现快速、准确的输入 控制指令。
06
矩阵键盘的未来展望

扫描程序
按照一定的规则逐行逐列扫描键盘 ,检测按键状态变化。
识别程序
根据按键电路的状态变化,判断具 体哪个按键被按下,并执行相应的 操作。
接口通信方式
并行通信
通过数据线将按键信号直接传输 到微控制器,数据传输速度快,
但需要较多的数据线。
串行通信
通过串行数据线将按键信号传输 到微控制器,数据传输速度较慢
键。
矩阵键盘的设计使得电子琴能够 模拟传统钢琴的触感,提供逼真
的演奏体验。
电子琴的矩阵键盘通常配备力度 感应功能,根据按下琴键的力度
来调整音符的音量和音质。
游戏机按键
游戏机按键通常采用矩阵键盘 布局,以适应游戏过程中快速 输入指令的需求。
矩阵键盘的设计使得游戏机按 键能够实现多键同时按下,提 高游戏操作的准确性和速度。
THANKS
感谢观看
03
矩阵键盘的电路设计
硬件电路设计
电源电路
为矩阵键盘提供稳定的电 源,确保按键的正常工作 。
按键电路
每个按键对应一个或多个 行列交叉点,通过检测行 和列的状态变化来确定按 键的按下状态。
输出电路
将按键信号输出到微控制 器或其他处理设备进行处 理。
软件编程设计
初始化程序
对矩阵键盘进行初始化设置,包 括设置扫描频率、去抖动时间等

AVR基本输入:矩阵键盘

AVR基本输入:矩阵键盘

矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式按键复杂。 矩阵键盘的检测方法有多种,常见的有:逐点扫描法、逐行扫描法、全局扫描法。 在本实例中我们采用逐行扫描法来实现按键检测,其中 PA0-PA3 作为列线,PA4-PA7 作为行线。识别 过程如下:
- 专业电子技术交流社区 电子工程师网上家园 - 电子园
PORTA = 0xdf;
DDRA = 0xf0;
temp = PINA;
temp &= 0x0f;
if(temp != 0x0f)
{
_delay_ms(20);
temp = PINA;
temp &= 0x0f;
if(temp != 0x0f)
{
temp = PINA;
switch(temp)
{
case 0xde: KEY = 4;break;
[基本输入:矩阵键盘]
电子园
第 9 课 独立按键
上两课已经学习了在单片机系统中检测独立式按键的接口电路和程序设计,独立式按键的每个 按键占用 1 位 I/O 口线,其状态是独立的,相互之间没有影响,只要单独测试链接案件的 I/O 口线电平的 高低就能判断键的状态。独立式按键电路简单、配置灵活,软件结构也相对简单。此种接口方式适用于 系统需要按键数目较少的场合。在按键数量较多的情况下,如系统需要 8 个以上按键的键盘时,采用独 立式接口方式就会占用太多的 I/O 口,这对于 I/O 口资源不太丰富的单片机系统来说显得相当浪费,那么 当按键数目相对较多的时候, 为了减少 I/O 口资源的占用, 应该采取什么样的方式才能够既满足多按键 识别,又减少 I/O 口的占用呢?
case 0xdd: KEY = 5;break;

4-4矩阵键盘控制16个LED灯

4-4矩阵键盘控制16个LED灯

一、任务说明本次的任务是利用51单片机设计一个4*4矩阵键盘输入系统,用16个发光二级管对应16个不同的按键。

每按下一个按键对应的发光二极管就亮。

矩阵式键盘又称行列键盘,它是用N条I/O线作为行线,N条I/O线作为列线组成的键盘。

在行线和列线的每个交叉点上设置一个按键。

这样键盘上按键的个数就为N*N个。

这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。

最常见的键盘布局如图1所示。

一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,本设计就采用这个键盘模式。

图1 键盘布局利用单片机的并行口P1连接4×4矩阵键盘,并以单片机的P1.0-P1.3各管脚作输入线,以单片机的P1.4-P1.7各管脚作输出线;利用P2、P3口控制灯1-灯16,。

用Proteus绘制其电路原理图(附录一)。

此任务用到了AT89C51芯片,还用到了晶体振荡器、按钮开关、发光二级管以及一些电阻。

这次任务中采用C语言编写程序,在编译过程中设置成自动产生HEX文件,将此文件导入AT89C51中,即可实现相应的功能。

二、原理图绘制说明电路原理图的设计与绘制是整个电路设计的基础,设计一个电路原理图的工作包括:设置电路图图纸的大小,规划电路图的总体布局,在图纸上放置元器件并对元器件进行调整,进行布线和整体布局,最后保存并打印输出等几个步骤。

安装完Proteus后,运行ISIS 7 Professional,在原理图编辑窗口绘制电路图,在该界面下还有预览窗口和元件列表区,在左侧的工具箱中还有模型选择工具栏,方向工具栏及仿真按钮等工具。

其具体的使用步骤如下:1.运行该软件后,新建一个设计文件,设置图纸大小。

选择界面如图2所示。

图2 选择图纸大小界面2.接下来开始查找任务中所用到的元器件,查找界面如图3所示。

图3 元器件查找界面3.将查找的元器件放置到界面中,并进行相应的引脚连线,本次是采用标注的方式进行引脚连接,标注符号相同的表示引脚相连接,具体操作是先将引脚引出一小段导线,右击导线选择放置网络标号,标注标号界面如图4所示。

矩阵键盘及其电路设计

矩阵键盘及其电路设计
键(9键)。
3、矩阵式键盘的按键识别方法
• 逐行扫描法是一种逐行或逐列判断是否有键按下的方法。扫描法又称为逐行或列扫 描查询法,是一种最常用的按键识别方法。利用行扫描法判断矩阵键盘中被按下的 键时主要经过以下步骤。
• 第一步、识别有无键按下 • 让所有的行线均置为0电平,即P1.4-P1.7均输出低电平,读取列线P1.0-P1.3的值,
若P1.0-P1.3均为高电平,则表示无键按下,若不全为高电平,则表示有键按下 • 第二步、若有键被按下,识别出具体的按键 • 方法是采用逐行扫描的办法,即逐行置零电平,检查各列线的电平。如首先置第一
行为0,其余行为1,也就是让P1.4-P1.7输出0111,读取列线P1.0-P1.3的值,若不 全为1,则根据读取的列值即可判断出按键在第一行第几列上,从而识别出按键的 位置,若全为1,表示第一行无键按下,那么就再置第二行为0,其余行为1,即 P1.4-P1.7输出1011,再读取列值,根据列值结果,判断第二行上有无键被按下, 依此类推,识别出按键的键值。
1、独立式键盘及其接口
• 独立式键盘,是一种最简单的键盘构成 方法,它将每个按键的一端接到单片机 的I/O口,另一端接地,如图所示。
• 主要特点是各个键相互独立,每一个按 键对应一根输入口线。键盘软件结构简 单,但当键盘数目较多时,需占用大量 的输入口线,所以在使用上受到了很大 的限制。
2、矩阵式键盘及其接口
键盘及其电路设计
一、键盘的基本概念
• 键盘是一组开关的集合,是最常用的输入设备之一。组成键盘的按键 有触点式和非触点式两种。
• 触点式按键通常是机械触点开关,它利用了机械触点的通、断特性来 完成信息的输入。
• 非触点式按钮主要指利用电子器件的通、断来完成信息的输入,如工 作在开关状态的三极管等。

矩阵键盘

矩阵键盘

FPGA学习心得——矩阵键盘1、行列式键盘概述为了减少键盘与单片机接口时所占用I/O口线的数目,在键数较多时,通常都将键盘排列成行列矩阵式,行列式键盘又叫矩阵式键盘。

用带有I/O口的线组成行列结构,按键设置在行列的交点上。

例如用2*2的行列结构可以构成4个键的键盘,4*4的行列结构可以构成有16个键的键盘。

这样,当按键数量平方增长时,I/O口线只是线性增长,这样就可以节省I/O口线。

2、行列式键盘原理教研室已有薄膜矩阵键盘,其实物图如图所示。

其电路原理图如下图所示。

由行列式键盘的原理可以知道,要正确地完成按键输入工作必须有按键扫描电路产生keydrv3~keydrv0信号。

同时还必须有按键译码电路从keydrv3~keydrv0信号和keyin3~keyin0信号中译码出按键的键值。

此外,一般还需要一个按键发生标志信号用于和其他模块接口,通知其它模块键盘上有按键动作发生,并可以从键盘模块中读取按键键值。

由于各个模块需要的时钟频率是不一样的,因此时钟产生模块就是用于产生各个模块需要的时钟信号。

因此得到键盘接口电路的结构如图2所示。

图2 键盘接口电路结构图行列式键盘电路的FPGA实现主要解决三个问题,一是如何检测是否有按键按下并防止采集到干扰信号;二是在按键闭合时如何防止抖动;三是如何判断为哪一个按键位动作,并对其进行译码。

因此,为了解决这些问题,程序中使用不同的进程分别实现键盘扫描信号的产生、键盘去抖以及键盘的译码。

3、源程序[plain]view plaincopy1.----------------------------------------------------------------------------------2.-- Company:3.-- Engineer:4.--5.-- Create Date: 08:46:57 07/31/20126.-- Design Name:7.-- Module Name: MatrixKeyboard - Behavioral8.-- Project Name:9.-- Target Devices:10.-- Tool versions:11.-- Description:12.--13.-- Dependencies:14.--15.-- Revision:16.-- Revision 0.01 - File Created17.-- Additional Comments:18.--19.----------------------------------------------------------------------------------20.library IEEE;e IEEE.STD_LOGIC_1164.ALL;e IEEE.STD_LOGIC_ARITH.ALL;e IEEE.STD_LOGIC_UNSIGNED.ALL;24.25.---- Uncomment the following library declaration if instantiating26.---- any Xilinx primitives in this code.27.--library UNISIM;28.--use UNISIM.VComponents.all;29.30.entity MatrixKeyboard is31. Port ( Clk : in STD_LOGIC;32. Reset : in STD_LOGIC;33. KeyIn : in STD_LOGIC_VECTOR (3 downto 0);34. KeyScan : out STD_LOGIC_VECTOR (3 downto 0);35. LED : out STD_LOGIC_VECTOR (3 downto 0)36. );37.end MatrixKeyboard;38.39.architecture Behavioral of MatrixKeyboard is40.41.Signal Clk_scan : STD_LOGIC := '0';42.Signal Clk_5ms : STD_LOGIC := '0';43.Signal Clk_2ms : STD_LOGIC := '0';44.Signal Key_Scan : STD_LOGIC_VECTOR(3 downto 0);45.Signal Key_Decode : STD_LOGIC_VECTOR(7 downto 0);46.47.Type State_Key is(st_key1,st_key2,st_key3,st_key4);48.Signal Current_Key : State_Key := st_key1;49.50.Type State_Scan is(st_scan1,st_scan2,st_scan3,st_scan4);51.Signal Current_Scan : State_Scan := st_scan1;52.53.begin54.55. Proc_Clk_5ms : process(Clk)56. variable cnt_clk : integer range 0 to 250000 := 0;57. begin58. if(rising_edge(Clk)) then59. if(cnt_clk < 125000) then60. cnt_clk := cnt_clk + 1;61. Clk_scan <= '0';62. elsif(cnt_clk < 249999) then63. cnt_clk := cnt_clk + 1;64. Clk_scan <= '1';65. else66. cnt_clk := 0;67. end if;68. Clk_5ms <= Clk_scan;69. end if;70. end process Proc_Clk_5ms;71.72. Proc_Clk_2ms : process(Clk)73. variable cnt_clk : integer range 0 to 100000 := 0;74. begin75. if(rising_edge(Clk)) then76. if(cnt_clk < 50000) then77. cnt_clk := cnt_clk + 1;78. Clk_2ms <= '0';79. elsif(cnt_clk < 99999) then80. cnt_clk := cnt_clk + 1;81. Clk_2ms <= '1';82. else83. cnt_clk := 0;84. end if;85. end if;86. end process Proc_Clk_2ms;87.88.89. Proc_Scan:process(Clk_5ms)90. begin91. if(rising_edge(Clk_5ms)) then92. case Current_Scan is93. when st_scan1 =>94. Key_Scan <= "1110";95. Current_Scan <= st_scan2;96. when st_scan2 =>97. Key_Scan <= "1101";98. Current_Scan <= st_scan3;99. when st_scan3 =>100. Key_Scan <= "1011";101. Current_Scan <= st_scan4;102. when st_scan4 =>103. Key_Scan <= "0111";104. Current_Scan <= st_scan1;105. end case;106. end if;107.108. end process Proc_Scan;109.110. KeyScan <= Key_Scan;111. Key_Decode <= Key_Scan & Keyin;112.113. Proc_Keyboard:process(Clk_2ms,Reset)114. variable cnt_btn : integer range 0 to 50000 := 0;115. begin116. if(Reset = '1') then117. LED <= x"1";118. Current_Key <= st_key1;119. elsif(falling_edge(Clk_2ms)) then120. case Current_Key is121. when st_key1 => --Check whether any keys are p ressed122. if((Keyin and "1111") = "1111") then123. Current_Key <= st_key1;124. else125. Current_Key <= st_key2;126. end if;127. when st_key2 => --keys debouncing128. if((Keyin and "1111") = "1111") then129. Current_Key <= st_key1;130. else131. case Key_Decode is132. when "11101110" => LED <= "0001";133. when "11101101" => LED <= "0010";134. when "11101011" => LED <= "0011";135. when "11100111" => LED <= "1010";136. when "11011110" => LED <= "0100";137. when "11011101" => LED <= "0101";138. when "11011011" => LED <= "0110";139. when "11010111" => LED <= "1011";140. when "10111110" => LED <= "0111";141. when "10111101" => LED <= "1000";142. when "10111011" => LED <= "1001";143. when "10110111" => LED <= "1100";144. when "01111110" => LED <= "1110";145. when "01111101" => LED <= "0000";146. when "01111011" => LED <= "1111";147. when "01110111" => LED <= "1101";when others => null;148. end case;149. end if;150. Current_Key <= st_key3;151. when st_key3 => --Check whether the pressed keys a re released152. if((Keyin and "1111") /= "1111") then153. Current_Key <= st_key3;154. else155. Current_Key <= st_key4;156. end if;157. when st_key4 => --keys debouncing158. if((Keyin and "1111") /= "1111") then159. Current_Key <= st_key3;160. else161. LED <= x"0";162. Current_Key <= st_key1;163. end if;164. end case;165. end if;166. end process Proc_Keyboard;167.168.end Behavioral;169.薄膜键盘矩阵键盘4x4 ,单片机开发配件,机械手按键。

4-4矩阵键盘控制16个LED灯

4-4矩阵键盘控制16个LED灯

一、任务说明本次的任务是利用51单片机设计一个4*4矩阵键盘输入系统,用16个发光二级管对应16个不同的按键。

每按下一个按键对应的发光二极管就亮。

矩阵式键盘又称行列键盘,它是用N条I/O线作为行线,N条I/O线作为列线组成的键盘。

在行线和列线的每个交叉点上设置一个按键。

这样键盘上按键的个数就为N*N个。

这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。

最常见的键盘布局如图1所示。

一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,本设计就采用这个键盘模式。

图1 键盘布局利用单片机的并行口P1连接4×4矩阵键盘,并以单片机的P1.0-P1.3各管脚作输入线,以单片机的P1.4-P1.7各管脚作输出线;利用P2、P3口控制灯1-灯16,。

用Proteus绘制其电路原理图(附录一)。

此任务用到了AT89C51芯片,还用到了晶体振荡器、按钮开关、发光二级管以及一些电阻。

这次任务中采用C语言编写程序,在编译过程中设置成自动产生HEX文件,将此文件导入AT89C51中,即可实现相应的功能。

二、原理图绘制说明电路原理图的设计与绘制是整个电路设计的基础,设计一个电路原理图的工作包括:设置电路图图纸的大小,规划电路图的总体布局,在图纸上放置元器件并对元器件进行调整,进行布线和整体布局,最后保存并打印输出等几个步骤。

安装完Proteus后,运行ISIS 7 Professional,在原理图编辑窗口绘制电路图,在该界面下还有预览窗口和元件列表区,在左侧的工具箱中还有模型选择工具栏,方向工具栏及仿真按钮等工具。

其具体的使用步骤如下:1.运行该软件后,新建一个设计文件,设置图纸大小。

选择界面如图2所示。

图2 选择图纸大小界面2.接下来开始查找任务中所用到的元器件,查找界面如图3所示。

图3 元器件查找界面3.将查找的元器件放置到界面中,并进行相应的引脚连线,本次是采用标注的方式进行引脚连接,标注符号相同的表示引脚相连接,具体操作是先将引脚引出一小段导线,右击导线选择放置网络标号,标注标号界面如图4所示。

矩阵键盘学习资料(重新整理)

矩阵键盘学习资料(重新整理)

矩阵键盘嵌入式移动设备的应用越来越广,以其体积小、重量轻、便于携带等特点而备受青睐。

键盘是一种最为普遍使用的输入工具,但嵌入式移动设备因其体积小的特点决定了它的键盘不大可能采用普通PC机上的标准键盘,因而大多数采用键数相对较少的矩阵键盘。

利用矩阵键盘用户可以很方便的实现对嵌入式移动设备进行相应的操作,是极方便的人机交互设备。

随着微软的嵌入式操作系统Windows CE的普及,Windows CE的矩阵键盘开发得到了越来越多开发者的重视,本文与大家分享我在开发矩阵键盘的一些总结。

1.Windows CE驱动分类Windows CE提供了许多用于开发设备驱动的模型,这些驱动程序模型使得Windows CE 能适应大部分的内部和外围设备。

因此,在深入探讨Windows CE矩阵键盘驱动程序之前,先了解在WinCE平台上使用的两种设备:内建设备和可安装设备。

因此,从驱动加载方式来看WinCE可分为本机设备驱动(Built-In Driver)、可加载驱动(Loadable Driver)。

本机设备驱动即Native Device Drivers,WinCE设计成可直接使用内建设备,这些设备由本机驱动过程控制。

本机驱动程序是与WinCE的核心组件紧密相连,这些驱动对应的设备通常在系统启动时,在GWES的进程空间内被加载,因此它们不是以独立的DLL形式存在。

可加载设备是指可与平台连接和分离的第三方接口设备,可由用户随时安装和卸载这些驱动,可以在系统启动时或者和启动后的任何时候由设备管理器动态加载。

通常这类驱动是以DLL动态链接库的形式存在,系统加载后这些驱动程序是以用户态的角色运行,这种外围设备的驱动也被称为流驱动。

两者的差别在于它们提供的编程接口不同:本地设备驱动可以根据具体设备的需求提供本机的相应接口;而流接口驱动则是提供一组通用接口即流接口函数,应用程序可以通过流接口提供的接口函数来访问外围设备。

2.嵌入式矩阵键盘驱动原理嵌入式设备上的键盘受设备本身体积影响,键盘设计大多数采用矩阵形式。

矩阵键盘介绍与使用程序

矩阵键盘介绍与使用程序

单片机外接键盘电路一、原理简介键盘接口电路是单片机系统设计非常重要的一环,作为人机交互界面里最常用的输入设备。

我们可以通过键盘输入数据或命令来实现简单的人机通信。

在设计键盘电路与程序前,我们需要了解键盘和组成键盘的按键的一些知识。

1. 按键的分类一般来说,按键按照结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关等;另一类是无触点式开关按键,如电气式按键,磁感应按键等。

前者造价低,后者寿命长。

目前,微机系统中最常见的是触点式开关按键(如本学习板上所采用按键)。

按键按照接口原理又可分为编码键盘与非编码键盘两类,这两类键盘的主要区别是识别键符及给出相应键码的方法。

编码键盘主要是用硬件来实现对键的识别,非编码键盘主要是由软件来实现键盘的识别。

全编码键盘由专门的芯片实现识键及输出相应的编码,一般还具有去抖动和多键、窜键等保护电路,这种键盘使用方便,硬件开销大,一般的小型嵌入式应用系统较少采用。

非编码键盘按连接方式可分为独立式和矩阵式两种,其它工作都主要由软件完成。

由于其经济实用,较多地应用于单片机系统中(本学习板也采用非编码键盘)。

2. 按键的输入原理在单片机应用系统中,通常使用机械触点式按键开关,其主要功能是把机械上的通断转换成为电气上的逻辑关系。

也就是说,它能提供标准的TTL 逻辑电平,以便与通用数字系统的逻辑电平相容。

此外,除了复位按键有专门的复位电路及专一的复位功能外,其它按键都是以开关状态来设置控制功能或输入数据。

当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能。

因此,键信息输入是与软件结构密切相关的过程。

对于一组键或一个键盘,通过接口电路与单片机相连。

单片机可以采用查询或中断方式了解有无按键输入并检查是哪一个按键按下,若有键按下则跳至相应的键盘处理程序处去执行,若无键按下则继续执行其他程序。

3. 按键的特点与去抖机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。

矩阵键盘电路

矩阵键盘电路
矩阵键盘电路
知识点目录
1
矩阵键盘电路结构与工作原理
矩阵键盘的编码
矩阵式键盘按键识别
键盘的工作方式
1.矩阵键盘电路结构与工作原理
2
矩阵式键盘又称为行列式键盘。用I/O接口线组成行和列结构,键位设置在行和 列的交叉点上。如图1所示,8个I/O口实现了16个按键。
图1 矩阵键盘电路结构
1.矩阵键盘电路结构与工作原理
3
工作原理:以第一组键盘为例。设置KeyOut1输出一个低电平,相当于KeyOut1接 地,电路相当于4个独立按键电路,此时KeyIn1-KeyIn4四个输入端为高电平;当 键盘K1按下时,由于电路导通,此时KeyIn1变为低电平。同理,哪个按键按下, 相对应的输入端为低电平,单片机通过读输入端的状态,判断是否有按键按下。 对应图1四组按键,当KeyOut1输出为低电平时,KeyOut2-KeyOut4输出必须为高 电平,才能避免相互间的干扰。
2.矩阵键盘的编码
பைடு நூலகம்
4
对于矩阵式键盘,按键的位置由行号 和列号唯一确定,因此可分别对行号 和列号进行二进制编码,然后将两值 合成一个字节,高4位是行号,低4位 是列号。
3.矩阵式键盘按键识别
5
扫描法:
1) 判断有无键按下。
2) 如果有键按下,识别是哪一个键按下,键盘扫描取得闭合键的行、列值。
3) 用计算法或查表法得到键值。
4) 判断闭合键是否释放,如没释放则继续等待。
5) 将闭合键键号保存,同时转去执行该闭合键的功能。
4.键盘的工作方式
6
(1)编程扫描方式
利用CPU在完成其它工作的空余时间,调用键盘扫描子程序来响应键盘输入 的要求。
(2)定时扫描工作方式

4 4矩阵键盘(未消抖)verilog

4 4矩阵键盘(未消抖)verilog

4*4矩阵键盘(未消抖):module Matrix_keyboard(clk,in_s,out_s,num);//定义模块端口信息input clk;input [3:0] in_s;output [3:0] out_s;output [4:0] num;//定义输出信号类型及局部变量reg [4:0] num;reg [1:0] cnt = 0;reg [1:0] tmp = 0;reg [3:0] o_ut_st = 0;wire [7:0] dsample;//将扫描输出和输入信号级联,得到矩阵扫描结果assign dsample = {o_ut_st, in_s};assign out_s = o_ut_st;//产生按钮矩阵的列扫描信号always @(posedge clk)begincnt <= cnt + 1'b1;case (cnt)2'b00: o_ut_st <= 4'b1000;2'b01: o_ut_st <= 4'b0100;2'b10: o_ut_st <= 4'b0010;2'b11: o_ut_st <= 4'b0001;endcaseend//根据按钮的列扫描信号和行输入信号判断按钮是否被按下always @(posedge clk)begin//如果无按钮按下,定义num=16为无效状态if (in_s == 4'b0000)beginif (tmp == 3)beginnum <= 16; //无按键输入,输出16tmp <= 0;endelsebeginnum <= num;tmp <= tmp + 1'b1; //扫描周期,3个时钟周期endendelsebegintmp <= 0;case (dsample)//第1列扫描结果8'b1000_0001: num <= 0;8'b1000_0010: num <= 1;8'b1000_0100: num <= 2;8'b1000_1000: num <= 3;//第2列扫描结果8'b0100_0001: num <= 4;8'b0100_0010: num <= 5;8'b0100_0100: num <= 6;8'b0100_1000: num <= 7;//第3列扫描结果8'b0010_0001: num <= 8;8'b0010_0010: num <= 9;8'b0010_0100: num <= 10;8'b0010_1000: num <= 11;//第4列扫描结果8'b0001_0001: num <= 12;8'b0001_0010: num <= 13;8'b0001_0100: num <= 14;8'b0001_1000: num <= 15;endcaseendendendmodule独立按键消抖程序:module Btn_without_shake(Clk_50MHz,PB_UP,PB_Out,count_sel); //定义模块端口信息input Clk_50MHz; //模块时钟50MHzinput PB_UP; //按钮输入output PB_Out; //去抖后按钮输出output [1:0] count_sel; //计数器输出//定义输出信号类型及局部变量reg [19:0] count_high = 0; //按钮输入高电平计数器reg [19:0] count_low = 0; //按钮输入低电平计数器reg PB_reg = 0;reg [1:0] count_sel_reg = 0;//输出赋值assign PB_Out = PB_reg;assign count_sel = count_sel_reg;//对输入进行采样,计数always @(posedge Clk_50MHz)if(PB_UP == 1'b0)count_low <= count_low + 1'b1;elsecount_low <= 20'h0_0000;always @(posedge Clk_50MHz)if(PB_UP == 1'b1)count_high <= count_high + 1'b1;elsecount_high <= 20'h0_0000;//防抖输出always @(posedge Clk_50MHz)if(count_high == 20'h7_FFFF) //判断高电平信号是否符合输出条件10msPB_reg <= 1'b1; //如果符合条件,则防抖输出高电平elseif(count_low == 20'h7_FFFF) //判断低电平信号是否符合输出条件10msPB_reg <= 1'b0; //如果符合条件,则防抖输出低电平elsePB_reg <= PB_reg;//使用去抖输出PB_reg控制count_sel计数always @(posedge PB_reg)count_sel_reg <= count_sel_reg + 1'b1;endmodule初学,参考书上的《Verilog HDL程序设计与实践》,准备用状态机做一下矩阵键盘,恩,坛子里也有,不过还是自己尝试一下,坛里老牛很多呀!。

44矩阵键盘课程设计

44矩阵键盘课程设计

4 4矩阵键盘课程设计一、课程目标知识目标:1. 学生能够理解4x4矩阵键盘的基本原理,掌握其电路连接方式和扫描原理。

2. 学生能够运用所学知识,设计并搭建一个简单的4x4矩阵键盘电路。

3. 学生了解矩阵键盘在嵌入式系统中的应用和重要性。

技能目标:1. 学生能够运用编程软件(如Arduino)编写程序,实现对4x4矩阵键盘的扫描和按键识别。

2. 学生能够运用调试工具,对矩阵键盘电路进行故障排查和优化。

3. 学生具备团队协作能力,共同完成矩阵键盘电路设计和程序编写。

情感态度价值观目标:1. 学生通过动手实践,培养对电子技术和编程的兴趣,增强学习动力。

2. 学生在团队合作中,学会沟通、协作、分享,培养团队精神和责任感。

3. 学生认识到科技发展对社会进步的重要性,激发为我国科技事业贡献力量的志向。

本课程针对高中年级学生,结合电子技术和编程知识,以实用性为导向,旨在培养学生的动手实践能力和创新精神。

课程内容紧密联系课本知识,通过设计4x4矩阵键盘电路,使学生在实践中掌握相关原理和方法。

课程目标具体、可衡量,为后续教学设计和评估提供明确方向。

二、教学内容1. 矩阵键盘基础知识:介绍矩阵键盘的原理、电路连接方式及其在嵌入式系统中的应用。

- 相关章节:课本第三章第二节“矩阵键盘及其应用”2. 4x4矩阵键盘电路设计:讲解如何搭建4x4矩阵键盘电路,包括硬件连接、电路图绘制等。

- 相关章节:课本第三章第三节“矩阵键盘电路设计”3. 矩阵键盘编程:介绍如何使用Arduino编程软件编写程序,实现对4x4矩阵键盘的扫描和按键识别。

- 相关章节:课本第四章第一节“Arduino编程基础”及第四节“矩阵键盘编程实例”4. 矩阵键盘电路调试与优化:教授学生如何运用调试工具进行故障排查,以及如何对电路和程序进行优化。

- 相关章节:课本第五章“电路调试与优化”5. 团队合作与展示:学生分组进行项目实践,共同完成矩阵键盘电路设计与程序编写,并进行成果展示。

实验4 矩阵键盘的使用

实验4  矩阵键盘的使用
*函数名: main
*函数功能:主函数
*输入:无
*输出:无
*******************************************************************************/
void main(void)
{
while(1)
{
KeyDown();
GPIO_DIG = ~DIG_CODE[KeyValue];
ORG 0000H
MOV SP,#6FH
MOV R0,#5;延时0.5秒
LOOP1:MOV R1,#200
LOOP2:MOV R2,#250
DJNZ R2,$
DJNZ R1,LOOP2
DJNZ R0,LOOP1
MOV DPTR,#4003H ;8255初始化
MOV A,#10000001B; A口、B口方式0输出,C口高4位输出,低4位输入
MOVX @DPTR,A
LOOP3:LCALL DISP;调用显示子程序DIS,设显示子程序入口为DISP
LCALL KEY;调用键盘扫描子程序,设键盘扫描子程序入口为KEY
CJNE A,#0FFH,LOOP4;如果有键按下转
SJMP LOOP3
LOOP4:MOV 20H,21H
MOV 21H,22H
入口:行列关键值码放在累加器A中,高4位是列驱动码(被扫描列的对应位为0,其余位均为1),低4位是行状态(按下键的对应位为0,其余位均为1)。
出口:键码放在A中带出。
占用:R1、A、PSW、DPTR。
程序清单如下:
;查键值子程序,起始地址为KEY20
KEY20:PUSH ACC;暂存关键值
MOV R1,#00H;查键值自变量清0

4 4 矩阵键盘工作原理

4 4 矩阵键盘工作原理

4 4 矩阵键盘工作原理
矩阵键盘是一种常见的输入设备,它通常用于计算机、手机等电子设备上。

其工作原理如下:
1. 矩阵排列:矩阵键盘由多行多列的按钮组成,形成一个矩阵结构。

每个按钮都有一个唯一的位置,行和列分别编号,以便识别用户按下的按钮。

2. 状态扫描:矩阵键盘使用一个扫描线(即行线)和一个检测线(即列线)来扫描按钮的状态。

扫描线一次只能激活一行按钮,而检测线会检测每一列的按钮状态。

通过激活不同的行和检测每一列的状态,可以确定用户按下的是哪个按钮。

3. 按钮编码:每个按钮被按下或释放时,状态会以电信号的形式传递给控制器。

这些状态信号经过编码后,被转换为可以识别的二进制数据。

4. 数据传输:编码后的数据会通过连接线路传输给计算机或其他设备,进行进一步的处理。

计算机通过解析接收到的数据,可以确定用户按下的具体按钮。

总结:矩阵键盘的工作原理是通过扫描行和检测列的方式,识别用户按下的按钮,并将其状态通过编码后传输给设备。

这样,设备可以根据接收到的数据来确定用户的输入。

4-1 矩阵键盘

4-1 矩阵键盘

Page 4
矩阵键盘的识别
键扫描就是要判断有无键按下,当扫描到有键
按下时再进行下一步处理,否则退出键盘处理程序。 独立式键盘扫描只需读取IO口状态,而矩阵式键盘 描通常有两种实现方法:逐行扫描法和线反转法。
Page 5
逐行扫描法
逐行扫描法 依次从第一至最末行线上发出低电平信号, 如果 该行线所连接的键没有按下的话, 则列线所接的端
0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15
Page 8
键盘接口的控制方式
在单片机的运行过程中,何时进行键盘扫描和处理, 可有下列三种情况: 1.查询方式:单片机通过调用键盘扫描子程序,查询
有无键按下。
2.定时扫描方式:每隔一定时间执行一次键盘扫描子 程序。 3.中断方式:每当有键闭合时才向CPU发出中断请求, 中断服务时进行键盘扫描和处理。
Page 12
合肥宏晶信息科技有限公司 ITek-Training Co.,Ltd.
Web: Add: 安徽省合肥市高新区中国科学技术大学先进技术研究院未来中心4楼
Thanks
Page 6
1 1 1 1
1 1
0 1 1 1
闭合键的一种常用方法, 该法比行扫描速度快, 但 在硬件上要求行线与列线外接上拉电阻。 先将行线作为输出线, 列线作为输入线, 行线输出全“0”信号, 读入列 线的值, 那么在闭合键所在的列线上的值必为0;然后从列线输出全“0” 信号,再读取行线的输入值,闭合键所在的行线值必为 0。这样,当一个 设第2行第 键被按下时, 必定可读到一对唯一的行列值。再由这一对行列值可以求 4列键按下 出闭合键所在的位置。
Page 9
短按及长按
短按:轻触一次,立即弹开。软件判断完成一项功能。 长按:按住不放,持续一段时间。软件判断完成另一项功能。

矩阵键盘的工作原理和扫描确认方式

矩阵键盘的工作原理和扫描确认方式
在该方式中要使用mcu的一个定时器使其产生一个10ms的定时中断mcu响应定时中断执行键盘扫描当在连续两次中断中都读到相同的按键按下间隔10ms作为消抖处理mcu才执行相应的键处理程序中断方式
9.3.1 矩阵键盘的工作原理和扫描确认方式
来源:《AVR 单片机嵌入式系统原理与应用实践》M16 华东师范大学电子系 马潮 当键盘中按键数量较多时,为了减少对 I/O 口的占用,通常将按键排列成
矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图 9-7 所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交 点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU 通过检测行 或列线上的电平变化可以确定哪个按键被按下。
图 9-7 为一个 4 x 3 的行列结构,可以构成 12 个键的键盘。如果使用 4 x 4 的行列结构,就能组成一个 16 键的键盘。很明显,在按键数量多的场合,矩 阵键盘与独立式按键键盘相比可以节省很多的 I/O 口线。
File name
: demo_9_3.c
Chip type
: ATmega16
Program type
: Application
Clock frequency
: 4.000000 MHz
// 输出行线电平 // 必须送 2 次!!!(注 1 // 读列电平 // 没有按键,继续扫描
// 有按键,停止扫描 // 转消抖确认状态
// 再次读列电平, // 与状态 0 的相同,确认按键 // 键盘编码,返回编码值
case 0b01000110:
key_return = K4_1;
break;
它们不仅与键盘的硬件连接有关系,同时还要注意他们在程序中是如何使用的, 其值的保存等等。

矩阵键盘键值的计算方法

矩阵键盘键值的计算方法

矩阵键盘键值的计算方法矩阵键盘是一种常见的输入设备,广泛应用于计算机、手机、电子器件等。

它通过将按下的键映射为一个特定的键值,实现对应用程序的输入控制。

本文将介绍矩阵键盘键值的计算方法,帮助读者了解矩阵键盘的工作原理和键值计算的方法。

一、矩阵键盘的基本原理矩阵键盘由多个行和列的按键构成,这些按键被排列成一个矩阵,行与列之间形成交叉点。

按下某个按键时,会使得对应行和列之间形成闭合电路。

矩阵键盘通过扫描行和列,检测到闭合电路,从而确定所按下的按键。

二、矩阵键盘键值计算的方法1. 扫描行和列矩阵键盘首先需要扫描行和列,以检测闭合电路。

这个过程可以通过控制行和列的输入输出来实现。

首先将所有行设置为高电平输出状态,然后逐行将其设置为低电平状态,同时检测列的输入状态。

如果某一列为低电平,则说明该行和列之间的按键闭合,即键盘检测到按键按下的动作。

2. 确定键值在检测到按键闭合后,需要进一步确定对应的键值。

这个过程需要根据键盘的布局和键盘的编码规则来实现。

一般情况下,我们可以以行列号的方式对键盘按键进行编码。

假设有N 行M 列的键盘,按下的按键位于第i 行第j 列,则键值可表示为(i-1)*M + j。

通过这种方式,我们可以根据按下的行和列号计算出对应按键的键值。

假设有一个4 行4 列的矩阵键盘,按下的按键位于第3 行第2 列。

按照上述计算方法,我们可以得到键值为(3-1)*4 + 2 = 10。

因此,按下的按键对应的键值为10。

3. 键值的应用计算出按键的键值后,我们可以将其应用于对应的应用程序中。

键值可以作为输入信号传递给应用程序,根据键值的不同,应用程序可以执行相应的操作。

例如,将键值与预先定义的按键映射表进行匹配,可以实现不同按键对应的功能,如快捷键、功能键等。

矩阵键盘键值的计算方法涉及到扫描行和列,确定键值等关键步骤。

通过扫描行和列,可以检测到按键的闭合电路;通过确定键值,可以识别所按下的按键。

这种计算方法可以广泛应用于矩阵键盘的设计和开发中,帮助我们理解矩阵键盘的工作原理和键值计算的方法,并将其应用到实际的应用程序中。

矩阵键盘原理

矩阵键盘原理

距阵键盘矩阵键盘是单片机编程中所使用的键盘.1.矩阵式键盘的结构与工作原理在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。

在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。

这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。

这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。

行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

具体的识别及编程方法如下所述。

2、矩阵式键盘的按键识别方法确定矩阵式键盘上何键被按下介绍一种“行扫描法”。

行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。

1、判断键盘中有无键按下将全部行线Y0-Y3置低电平,然后检测列线的状态。

只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。

若所有列线均为高电平,则键盘中无键按下。

2、判断闭合键所在的位置在确认有键按下后,即可进入确定具体闭合键的过程。

其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。

在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。

若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。

下面给出一个具体的例子:图仍如上所示。

8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一. 键盘电路基础
2.基本原理 基本的键盘都是不同按键开关的组合。 目前常使用的按键是机械式按键。它是 通过机械触点的通断作用,实现电压信 号高低的输入。
yeK R7K4 D S N CCV G yeK R 7K4 D S N CCV G
一. 键盘电路基础
3.按键确认 按键的闭合与断开,在系统中的响应分 别是高电平或者是低电平。故在设计过 程中可以采用两种方式来设计按键接口。 (1).上拉式按键接口 (2).下拉式按键接口
程序开始
否 按键按下 是
延时
否 按键按下 是
主程序
二. 键盘电路设计方法
3.阵列式键盘接口电路设计 按键开关被组合成了行和列的矩阵,单 片机的I/O接口一部分作为行线,一部分 作为列线,按键布置在行线和列线的交 叉点上。行列式键盘中的按键数量可以 达到行线数与列线数的乘积。
U1
P10 P11 P12 P13 P14 P15 P16 P17
二. 键盘电路设计方法
1.直接式键盘接口电路设计 将各按键开关单独连接到一个单片机的输 入引脚上,每个按键占用一个单片机的 I/O口。也称为独立式键盘。 优缺点:配置灵活,但占用的I/O过多, 成本较高,因此实用输入按键较少的情 况。
二. 键盘电路设计方法
2.直接式键盘的软件设计
在直接式键盘中,可以通过 检测与按键相连I/O接口的电 平值来判断按键是否按下。
P 14 P 15 P 16 P 17
8 K9 C K13
9 K10 D K14
A K11 E K15
B F
二. 键盘电路设计方法
4.阵列式键盘的软件设计
读取阵列式键盘的按键值,必须采用扫描键值 的方式。下面以扫描第四行为例: 首先置单片机的P1_3口为低,其他引脚都为高, 然后再读取P1口的值,与该行各个键盘按下后 P1口的值相匹配。
程序开始
P1=0xf7
P1=0xfb
P1=0xfd
P1=0xfe
读取P1
读取P1
读取P1
读取P1
存储第四行 键盘状态值
存储第三行 键盘状态值
存储第二行 键盘状态值
存储第一行 键盘状态值
否 有键按下 是
主程序
第四章 键盘开发与设计
教学目录
1.键盘电路基础 2.键盘电路的硬件设计 3.键盘电路的软件设计
重难点
1.键盘的原理及抖动处理 2.矩阵键盘的硬件设计 3.矩阵键盘的软件设计
一. 键盘电路基础
1.键盘的作用 键盘是嵌入式系统中人机交互界面不可 缺少的外围设备,客户可以通过键盘进 行数据输入、命令控制、程序生产等操 作,是非常重要的输入工具。
1 2 3 4 5 6 7 8
P10 P11 P12 P13 P14 P15 P16 P17
P00 P01 P02 P03 P04 P05 P06 P07
39 38 37 36 35 34 33 32
K0
P10
K4
P11
0 K1 4 K5
1 K2 5 K6
2 K3 6 K7
3 7
13 12
INT1 INT0
89C52 15
14
T1 T0
31 EA/VP
19 18
X1 X2
9 RESET
17 16
RD WR
P20 P21 P22 P23 P24 P25 P26 P27
21 22 23 24 25 26 27 28
P12 K8 P13 K12
VCC GND RXD20 10 11 30 29
一.键盘电路基础
4.按键消抖
(1).抖动的原因:由于按键的机械特性,其机 械触点不能够立刻完全闭合或断开,因此会产 生一系列的电平抖动信号。
一. 键盘电路基础
(2).消抖办法
硬件消抖:在键数较少时可用硬件方法消除键 抖动。如图所示。
一. 键盘电路基础
软件消抖 在软件中编写键盘消抖处理程序,因为 在嵌入式系统中,大部分产品使用的都 是价格便宜且容易发生抖动的开关按键。 如果键盘能够在进行消抖处理后还能正 确地读取所按下的键值,则表明该键被 按下。
相关文档
最新文档