带有 XC8 v1.43 的 PIC16F1717,可用于键盘按键
Posted
技术标签:
【中文标题】带有 XC8 v1.43 的 PIC16F1717,可用于键盘按键【英文标题】:PIC16F1717 with XC8 v1.43, variable for keypad presses 【发布时间】:2018-08-01 12:55:59 【问题描述】:我有一个 4x3 矩阵键盘连接到 PIC16F1717 的端口 B (RB1-RB7)。我通过依次将每一行设置为高并读取列值来扫描键盘按键。按下的键可以通过匹配行和列来解码。我正在以短暂的延迟去抖动:
while(1)
//scan for key presses
__delay_ms(10);
ROW1 = 1;
ROW2 = 0;
ROW3 = 0;
ROW4 = 0;
if (COL1 == 1)
__delay_ms(100);
if (COL1 == 1)
key = 1;
keyCount = keyCount ++ 1;
else if (COL2 == 1)
__delay_ms(100);
if (COL2 == 1)
key = 2;
keyCount = keyCount + 1;
//and so on for the other rows and columns
两个变量 key 和 keyCount 分别记录按下了哪个键,以及按下了多少个键。当按下 4 个键时,我想执行以下代码:
if (keyCount == 4)
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
LED = 1;
__delay_ms(500);
LED = 0;
__delay_ms(500);
LED = 1;
__delay_ms(500);
servoDemo();
__delay_ms(500);
LED = 0;
keyCount = 0;
这也在 main 函数内的 while(1) 循环中。我遇到的问题是增加 keyCount 不起作用。以前,我尝试过 keyCount++ 并且它有效,但在此之前这也不起作用。我尝试通过设置 keyCount = 4 而不是将其递增一来进行调试,并且成功了。
这两个变量都在主函数内声明(并初始化),但在 while(1) 循环之外。另外,我定义了以下内容:
//pin definitions
//////////////////////////
#define ROW1 PORTBbits.RB2
#define ROW2 PORTBbits.RB7
#define ROW3 PORTBbits.RB6
#define ROW4 PORTBbits.RB4
#define COL1 PORTBbits.RB3
#define COL2 PORTBbits.RB1
#define COL3 PORTBbits.RB5
#define SERVOSIG PORTDbits.RD0
#define LED PORTDbits.RD1
【问题讨论】:
首先最好对 row 和 col 使用循环。您也不计算按钮的边缘,这可能是您想要的。你有任何中断吗?或许贴出完整的代码会有所帮助,尤其是寄存器的初始化。 这里是寄存器初始化://disable analog ANSELA = 0x00; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; //set column pins as inputs TRISBbits.TRISB3 = 1; TRISBbits.TRISB1 = 1; TRISBbits.TRISB5 = 1; //set row pins as outputs TRISBbits.TRISB2 = 0; TRISBbits.TRISB7 = 0; TRISBbits.TRISB6 = 0; TRISBbits.TRISB4 = 0; //set LED pins as outputs TRISDbits.TRISD0 = 0; TRISDbits.TRISD1 = 0;
我没有为此使用中断。我看到使用循环如何使按键解码代码更紧凑。只要按下键,变量 keyCount 是否可能会增加?我不认为这就是它的工作原理,因为它只是一个 if 语句,但我真的想不出任何解释为什么会发生这种情况。如果是这种情况,那么边缘检测听起来是一个合理的解决方案。比如,我将如何检测一个积极的边缘?
是的,它就是这样工作的。只要按下该键,您每次都输入 if 语句。边缘检测的一个例子是记住键的旧值并将其与新值进行比较。
【参考方案1】:
问题是您的按键没有边缘检测。这意味着只要您按下一个键,就会在每个循环周期中输入 if 语句。这是一个小例子,它可以让您了解如何实现循环检测。
int key[12];
int key_old[12];
read_keys(key); //function that reads the keys in
while(1)
memcpy(key_old, key, 12*sizeof(key[0])); //copy key to key_old
read_keys(key); //function that reads the keys in
for(int i=0;i<12;i++)
if(key[i] && !key_old[i])
//positive edge on key i
__delay_ms(50); //Debouncing
这段代码并不完美,但应该给出上述的基本概念。
【讨论】:
以上是关于带有 XC8 v1.43 的 PIC16F1717,可用于键盘按键的主要内容,如果未能解决你的问题,请参考以下文章