键盘是广泛用于各种电子设备和嵌入式项目的输入设备。它们用于接收数字和字母形式的输入,并将其输入系统以进行进一步处理。在本教程中,我们将 连接一个4x4矩阵键盘和PIC16F877A。
在进入详细逻辑并学习如何使用键盘之前,我们将需要了解的知识很少。
为什么需要4x4键盘:
通常,我们使用微控制器单元的单个I / O引脚读取数字信号,例如开关输入。在少数需要9、12、16个按键用于输入的应用中,如果将每个按键添加到微控制器端口中,最终将使用16个I / O端口。这16个I / O端口不仅用于读取I / O信号,而且还可以用作外设连接,例如ADC支持,I2C,这些I / O引脚也支持SPI连接。由于这些引脚与开关/键相连,因此我们不能将它们用作I / O端口。这根本没有道理。那么,如何减少引脚数呢?答案是使用十六进制键盘或矩阵键盘。我们可以减少针数,它关联4x4矩阵键。它将使用8个引脚,其中4个以行连接,4个以列连接,因此节省了微控制器的8个引脚。
4x4矩阵键盘如何工作:
在上方的图像中,左侧显示了矩阵键盘模块。右侧显示内部连接以及端口连接。如果我们看到端口有8个引脚,则从左到右的前4个是X1,X2,X3和X4的行,从左到右的后4个是Y1,Y2,Y3,Y4的四列。如果我们将4行或X面作为输出,并将它们设为逻辑低或0,并且使4列作为输入并读取键,则当对应的Y为0时,将读取开关按下。
同样的事情也会在nxn矩阵中发生,其中n是数字。可以是3x3、6x6等。
现在只想按1。然后1位于X1行和Y1列。如果X1为0,则Y1将为0。以同样的方式,我们可以通过感测Y1,Y2,Y3和Y4列来感测X1行中的每个键。每个开关都会发生这种情况,我们将读取矩阵中开关的位置。
每个绿色圆圈都是开关,它们都以相同的方式连接在一起。
在本教程中,我们将按以下规范连接键盘:
- 我们将使用内部上拉
- 我们将添加按键去抖动选项
但是,当未按下开关时,我们需要将Y1,Y2,Y3和Y4设为高电平或1。否则,当按下开关时,我们无法检测到逻辑变化。但是由于这些引脚被用作输入而不是输出,因此我们无法通过代码或程序来实现。因此,我们将在微控制器中使用内部操作寄存器,并将这些引脚作为弱上拉使能模式进行操作。通过使用它,当它处于默认状态时,将有一个逻辑高使能模式。
同样,当我们按下键时,开关触点会产生尖峰或噪声,并且由于这种多重开关,会发生意外情况。因此,我们将首先检测开关按下,等待几毫秒,然后再次检查开关是否仍处于按下状态,如果开关仍处于按下状态,我们将最终接受开关按下,否则不接受。这称为开关的反跳。
我们将在我们的代码中实现所有这些,并在面包板上进行连接。
还要检查如何将4x4键盘与其他微控制器接口:
- 键盘与Arduino Uno的接口
- 与8051单片机接口的4x4矩阵键盘
- 与ATmega32单片机连接的4x4键盘
- 面包板上的Raspberry Pi数字密码锁
所需材料:
- 面包板
- PC中的Pic-kit 3和开发环境,即MPLABX
- 电线和连接器
- 字符LCD 16x2
- 20Mhz晶体
- 2个33pF陶瓷圆盘盖。
- 4.7k电阻
- 10k预设(可变电阻器)
- 4x4矩阵键盘
- 5 V适配器
电路原理图:
我们将在相关引脚上连接晶体和电阻。同样,我们将通过PORTD以4位模式连接LCD 。我们通过端口RB4连接了十六进制键盘或矩阵键盘。
如果您不熟悉PIC,请从PIC单片机入门开始:PIC和MPLABX简介
编程说明:
最后给出了用于将Matrix Keypad与PIC微控制器接口的完整代码。代码简单易懂。键盘库仅是代码中要理解的东西。在这里,我们使用了 keyboard.h 和 lcd.h 库来连接小键盘和16x2 LCD。因此,让我们看看其中发生了什么。
在keyboard.h内部,我们将看到使用了xc.h标头,它是默认的寄存器库,晶振频率是为在kepad.c文件中使用的延迟使用而定义的。我们在PORTRB寄存器处定义了键盘端口,并将各个引脚定义为行(X)和列(Y)。
我们还使用了两个功能,一个用于键盘初始化,它将重定向端口作为输出和输入,另一个功能是按下开关扫描,当调用时将返回开关按下状态。
#包括
在keyboard.c中,我们将看到以下功能将在键盘扫描器功能未返回“ n”时返回按键。
char switch_press_scan(void)//从用户获取密钥 { char key ='n'; //假设 while(key =='n')时 未按下任何键//等待直到按下某个键key = keyboard_scanner(); //再次扫描键,然后再次 返回键;//按下按键后返回其值 }
以下是键盘读取功能。在每一步中,我们将X1,X2,X3和X4行设为0,并读取Y1,Y2,Y3和Y4状态。该延迟用于去抖效果,当仍然按下开关时,我们将返回与之关联的值。当没有按下任何开关时,我们将返回“ n”。
char keyboard_scanner(void) { X_1 = 0; X_2 = 1; X_3 = 1; X_4 = 1; 如果(Y_1 == 0){__delay_ms(100);而(Y_1 == 0);返回“ 1”; } 如果(Y_2 == 0){__delay_ms(100);而(Y_2 == 0);返回'2'; } 如果(Y_3 == 0){__delay_ms(100);而(Y_3 == 0);返回“ 3”; } 如果(Y_4 == 0){__delay_ms(100);而(Y_4 == 0);返回'A'; } X_1 = 1; X_2 = 0; X_3 = 1; X_4 = 1; 如果(Y_1 == 0){__delay_ms(100);而(Y_1 == 0);返回'4'; } 如果(Y_2 == 0){__delay_ms(100);而(Y_2 == 0);返回“ 5”; } 如果(Y_3 == 0){__delay_ms(100);而(Y_3 == 0);返回“ 6”; } 如果(Y_4 == 0){__delay_ms(100);而(Y_4 == 0);返回“ B”; } X_1 = 1; X_2 = 1; X_3 = 0; X_4 = 1; 如果(Y_1 == 0){__delay_ms(100);而(Y_1 == 0);返回“ 7”; } 如果(Y_2 == 0){__delay_ms(100);而(Y_2 == 0);返回'8'; } 如果(Y_3 == 0){__delay_ms(100);而(Y_3 == 0);返回“ 9”; } 如果(Y_4 == 0){__delay_ms(100);而(Y_4 == 0);返回“ C”; } X_1 = 1; X_2 = 1; X_3 = 1; X_4 = 0; 如果(Y_1 == 0){__delay_ms(100);而(Y_1 == 0);返回'*'; } 如果(Y_2 == 0){__delay_ms(100);而(Y_2 == 0);返回'0'; } 如果(Y_3 == 0){__delay_ms(100);而(Y_3 == 0);返回'#'; } 如果(Y_4 == 0){__delay_ms(100);而(Y_4 == 0);返回'D'; } return'n'; }
我们还将在最后四个位上设置弱上拉,还将端口的方向设置为后4个输入,并将前4个设置为输出。所述OPTION_REG&= 0x7F的; 用于在最后一个引脚上设置弱上拉模式。
无效的InitKeypad(void) { Keypad_PORT = 0x00; //将键盘端口引脚值设置为零 Keypad_PORT_Direction = 0xF0; //最后4个引脚输入,前4个引脚输出 OPTION_REG&= 0x7F; }
在主PIC程序(如下所示)中,我们首先设置配置位,并包括一些所需的库。然后在 void system_init函数中,初始化键盘和LCD。最后, 在 主 函数中,我们通过调用 switch_press_scan() 函数并将值返回给lcd来读取键盘。
从此处下载带有头文件的完整代码,并查看下面的演示视频。