Home > Net >  4x4 matrix keypad stm32 cant interface it
4x4 matrix keypad stm32 cant interface it

Time:03-04

Hello I want to interface a keypad in stm32 l053r8 with timer interrupt. I have a SysTick_Handler function which I am handling there the switch debouncing of push buttons and every time the push button counter gets equal to 10 I am using a flag in order to check when the button is pressed. So now I have all the rows of the keypad as input and all the collumns of the keypad as output. My idea is 1) every timer int, it activates a new column and reads the 4 row inputs. 2) check if a button flag is "1" and send the appropriate message to the screen. I have an implementation but it is not working.For example in main function I have a condition that checks if the key1(expect 1 as output in screen) is pressed but it dont do anything. Any advice would be great.

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   ;
        }
    }
    //------------------------------
}

CodePudding user response:

First, your title says 4x4 but the code appears to be for 3x3.

Next, an electrical signal can propagate through a key matrix almost instantaneously. You should do do every column one straight after the other, you don't need a timer to do that. Just do: column high, read row, column low, next column high, etc.

After that, you only read the state of the key if it is not already pressed. You try to debounce the rising edge, but once the key is pressed it seems to stay pressed for ever, you never look for the falling edge when the key is released. Falling edges can bounce too, so you need to have a count there too.

Also, you are checking for the state where only one row is active with if(x && !y && !z). What if the user presses more than one button at a time? For each flag you only need to check for one input.

These points won't fix everything, but hopefully will get you further along the way!

CodePudding user response:

I suspect the following code to cause you some problems.

if(!KEY1_READ()){
    if(key1_counter == 10)

What are the chances that you will release the button when counter is exactly 10?

You seem to want an on-release event, so I would write the scanning code like so:

if (KEY1_READ()) {
    key1_counter  ;
} else {
    if (key1_counter > 10) {
        flag0.fl.f5 = 1;
    }
    key1_counter = 0;
}

Don't forget to reset the flag after you're done processing it.

  • Related