首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >4x4矩阵键盘stm32不能与它接口

4x4矩阵键盘stm32不能与它接口
EN

Stack Overflow用户
提问于 2022-03-03 21:03:41
回答 3查看 445关注 0票数 -1

我想将stm32 l053r8中的键盘与计时器中断连接起来。我有一个SysTick_Handler函数,我在那里处理,按钮的开关卸载,每次按钮计数器等于10,我使用一个标志,以检查按钮何时被按下。所以现在我把键盘的所有行作为输入,所有的键区的列作为输出。我的想法是

  1. 每个计时器int,它激活一个新列并读取4行输入
  2. ,检查按钮标志是否为"1“,并将适当的消息发送到屏幕上。

我有一个实现,但它不是主函数中的working.For示例,我有一个条件来检查是否按下key1 (expect 1作为屏幕中的输出),但它什么也不做。任何建议都会很好。

代码语言:javascript
复制
void TIM2_IRQHandler(void) {

if (TIM2->SR & TIM_SR_UIF ) {
    //Clear Timer 2 Flag
    CLEAR_BIT(TIM2->SR, TIM_SR_UIF);
    if (column_counter==4)
        column_counter=0;
    column_counter++;
    keypad_scanning(column_counter); // activate col=1 or 2 or 3 depends on counter.
}
}

void keypad_scanning(uint8_t column_pos) {

switch (column_pos) {
    case 1:
        SET_BIT(GPIOC->ODR,GPIO_ODR_OD15);   // C1 HIGH
        CLEAR_BIT(GPIOA->ODR,GPIO_ODR_OD1);  // C2 LOW
        CLEAR_BIT(GPIOA->ODR,GPIO_ODR_OD4);  // C3 LOW

        if (flag0.fl.f5 && !(flag0.fl.f6) && !(flag0.fl.f7)) {
            key0.fl.f1 = 1; // key 1 is pressed.
        }

        if (!(flag0.fl.f5) && flag0.fl.f6 && !(flag0.fl.f7)) {
            key0.fl.f4 = 1; // key 4 is pressed.
        }

        if (!(flag0.fl.f5) && !(flag0.fl.f6) && flag0.fl.f7) {
            key0.fl.f7 = 1; // key 7 is pressed.
        }
        break;

    case 2:
        CLEAR_BIT(GPIOC->ODR,GPIO_ODR_OD15);   // C1 LOW
        SET_BIT(GPIOA->ODR,GPIO_ODR_OD1);  // C2 HIGH
        CLEAR_BIT(GPIOA->ODR,GPIO_ODR_OD4);  // C3 LOW

        if (flag0.fl.f5 && !(flag0.fl.f6) && !(flag0.fl.f7)) {
            key0.fl.f2 = 1; // key 2 is pressed.
        }

        if (!(flag0.fl.f5) && flag0.fl.f6 && !(flag0.fl.f7)) {
            key0.fl.f5 = 1; // key 5 is pressed.
        }

        if (!(flag0.fl.f5) && !(flag0.fl.f6) && flag0.fl.f7) {
            key0.fl.f8 = 1; // key 8 is pressed.
        }
        break;

    case 3:
        CLEAR_BIT(GPIOC->ODR,GPIO_ODR_OD15);   // C1 LOW
        CLEAR_BIT(GPIOA->ODR,GPIO_ODR_OD1);  // C2 LOW
        SET_BIT(GPIOA->ODR,GPIO_ODR_OD4);  // C3 HIGH

        if (flag0.fl.f5 && !(flag0.fl.f6) && !(flag0.fl.f7)) {
            key0.fl.f3 = 1; // key 3 is pressed.
        }

        if (!(flag0.fl.f5) && flag0.fl.f6 && !(flag0.fl.f7)) {
            key0.fl.f6 = 1; // key 6 is pressed.
        }

        if (!(flag0.fl.f5) && !(flag0.fl.f6) && flag0.fl.f7) {
            key0.fl.f9 = 1; // key 9 is pressed.
        }
        break;
}
}

void SysTick_Handler(void) {
    //------------------------------
    //key 1 sampling ( ROW 1 FLAG)
    if(!flag0.fl.f5) {
        if(!KEY1_READ()) {
            if(key1_counter == 10)
                flag0.fl.f5 = 1; // R1 is HIGH
            key1_counter = 0;
        } else {
            if(key1_counter < 10) //10 ms sampling
                key1_counter ++;
        }
    }
    //------------------------------

    //------------------------------
    //key 2 sampling (ROW 2 FLAG)
    if(!flag0.fl.f6) {  
        if(!KEY2_READ()) {
            if(key2_counter == 10)
                flag0.fl.f6 = 1; // R2 is HIGH

            key2_counter = 0;
        } else {  
            if(key2_counter < 10) //10 ms sampling
                key2_counter ++;
        }
    }
    //------------------------------

    //------------------------------
    //key 3 sampling (ROW 3 FLAG)
    if(!flag0.fl.f7) {
        if(!KEY3_READ()) {
            if(key3_counter == 10)
                flag0.fl.f7 = 1; // R3 is HIGH
            key3_counter = 0;
        } else {
            if(key3_counter < 10) //10 ms sampling
                key3_counter ++;
        }
    }
    //------------------------------
}
EN

回答 3

Stack Overflow用户

发布于 2022-03-03 21:49:00

首先,标题是4x4,但代码似乎是3x3的代码。

接下来,电信号几乎可以瞬间地通过密钥矩阵传播。你应该一个接一个地做每一列,你不需要计时器。只需做:列高,读行,列低,下一列高,等等。

在此之后,您只会读取键的状态,如果它尚未按下。你试图攻克上升的边缘,但一旦键被按下,它似乎永远保持按压,你永远不会寻找下降的边缘,当钥匙被释放。下降的边缘也可以反弹,所以你也需要有一个计数。

此外,您正在检查只使用if(x && !y && !z)激活一行的状态。如果用户一次按多个按钮会怎样?对于每个标志,只需检查一个输入。

这些点并不能解决所有问题,但希望能让你走得更远!

票数 0
EN

Stack Overflow用户

发布于 2022-03-04 00:17:55

我怀疑下面的代码会导致一些问题。

代码语言:javascript
复制
if(!KEY1_READ()){
    if(key1_counter == 10)

当计数器正好是10的时候,你释放按钮的可能性有多大?

您似乎想要一个发布事件,所以我会编写如下扫描代码:

代码语言:javascript
复制
if (KEY1_READ()) {
    key1_counter++;
} else {
    if (key1_counter > 10) {
        flag0.fl.f5 = 1;
    }
    key1_counter = 0;
}

处理完毕后,不要忘记重置标志。

票数 0
EN

Stack Overflow用户

发布于 2022-03-07 15:22:06

我找到了解决办法。首先,谢谢你们给我提了个建议,并提出了一个问题。我使用了计时器(TIM2),每隔1ms就创建一个中断。对于我在3列中给出的每一个中断,这是我的输出端口,一个二进制数字序列,而我的所有输入端口(行)都被接地了。第一个序列是1 0 0,第2 0 1 0和第3 0 0 1。在该序列之后,我读取输入(行),以检测哪个输入(行)被设置为高(“1”),从而能够通过重选一个标志来检测哪个键被按下。所有这些都类似于我发布的代码,但我使用了不同的寄存器,使输出(列)从高(逻辑"1")到地面(逻辑"0"),即BSRR寄存器。为了检测是否按下按钮,我使用了debounce方法。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71343794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档