Teclado de interfaz con microcontrolador 8051 en Proteus

1

Intento simular este proyecto en Proteus utilizando keil C. Básicamente estamos interconectando un teclado 4x4 con un microcontrolador 8051.

Este es el código para el proyecto:

 #include<reg51.h>

    //Function declarations
    void cct_init(void);
    void delay(int);
    void lcdinit(void);
    void writecmd(int);
    void writedata(char);
    void Return(void);
    char READ_SWITCHES(void);
    char get_key(void);

    //*******************
    //Pin description
    /*
    P2 is data bus
    P3.7 is RS
    P3.6 is E
    P1.0 to P1.3 are keypad row outputs
    P1.4 to P1.7 are keypad column inputs
    */
    //********************
    // Define Pins
    //********************
    sbit RowA = P1^0;     //RowA
    sbit RowB = P1^1;     //RowB
    sbit RowC = P1^2;     //RowC
    sbit RowD = P1^3;     //RowD

    sbit C1   = P1^4;     //Column1
    sbit C2   = P1^5;     //Column2
    sbit C3   = P1^6;     //Column3
    sbit C4   = P1^7;     //Column4

    sbit E    = P3^6;     //E pin for LCD
    sbit RS   = P3^7;     //RS pin for LCD

    // ***********************************************************
    // Main program
    //
    int main(void)
    {
       char key;                // key char for keeping record of pressed key

       cct_init();              // Make input and output pins as required
       lcdinit();               // Initilize LCD

       writecmd(0x95);
       writedata('w');                                 //write
       writedata('w');                                 //write
       writedata('w');                                 //write
       writedata('.');                                 //write
       writedata('T');                                 //write
       writedata('h');                                 //write
       writedata('e');                                 //write
       writedata('E');                                 //write
       writedata('n');                                 //write
       writedata('g');                                 //write
       writedata('i');                                 //write
       writedata('n');                                 //write
       writedata('e');                                 //write
       writedata('e');                                 //write
       writedata('r');                                 //write
       writedata('i');                                 //write
       writedata('n');                                 //write
       writedata('g');                                 //write

       writecmd(0xd8);

       writedata('P');                                 //write
       writedata('r');                                 //write
       writedata('o');                                 //write
       writedata('j');                                 //write
       writedata('e');                                 //write
       writedata('c');                                 //write
       writedata('t');                                 //write
       writedata('s');                                 //write
       writedata('.');                                 //write
       writedata('c');                                 //write
       writedata('o');                                 //write
       writedata('m');                                 //write
       writecmd(0x80);
       while(1)
       { 
         key = get_key();       // Get pressed key
         //writecmd(0x01);        // Clear screen
         writedata(key);        // Echo the key pressed to LCD
       }
    }


    void cct_init(void)
    {
        P0 = 0x00;   //not used
        P1 = 0xf0;   //used for generating outputs and taking inputs from Keypad
        P2 = 0x00;   //used as data port for LCD
        P3 = 0x00;   //used for RS and E   
    }

    void delay(int a)
    {
       int i;
       for(i=0;i<a;i++);   //null statement
    }

    void writedata(char t)
    {
       RS = 1;             // This is data
       P2 = t;             //Data transfer
       E  = 1;             // => E = 1
       delay(150);
       E  = 0;             // => E = 0
       delay(150);
    }


    void writecmd(int z)
    {
       RS = 0;             // This is command
       P2 = z;             //Data transfer
       E  = 1;             // => E = 1
       delay(150);
       E  = 0;             // => E = 0
       delay(150);
    }

    void lcdinit(void)
    {
      ///////////// Reset process from datasheet /////////
         delay(15000);
       writecmd(0x30);
         delay(4500);
       writecmd(0x30);
         delay(300);
       writecmd(0x30);
         delay(650);
      /////////////////////////////////////////////////////
       writecmd(0x38);    //function set
       writecmd(0x0c);    //display on,cursor off,blink off
       writecmd(0x01);    //clear display
       writecmd(0x06);    //entry mode, set increment
    }

    void Return(void)     //Return to 0 location on LCD
    {
      writecmd(0x02);
        delay(1500);
    }

    char READ_SWITCHES(void)    
    {   
        RowA = 0; RowB = 1; RowC = 1; RowD = 1;     //Test Row A

        if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
        if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
        if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
        if (C4 == 0) { delay(10000); while (C4==0); return '/'; }

        RowA = 1; RowB = 0; RowC = 1; RowD = 1;     //Test Row B

        if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
        if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
        if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
        if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }

        RowA = 1; RowB = 1; RowC = 0; RowD = 1;     //Test Row C

        if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
        if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
        if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
        if (C4 == 0) { delay(10000); while (C4==0); return '-'; }

        RowA = 1; RowB = 1; RowC = 1; RowD = 0;     //Test Row D

        if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
        if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
        if (C3 == 0) { delay(10000); while (C3==0); return '='; }
        if (C4 == 0) { delay(10000); while (C4==0); return '+'; }

        return 'n';             // Means no key has been pressed
    }

    char get_key(void)           //get key from user
    {
        char key = 'n';              //assume no key pressed

        while(key=='n')              //wait untill a key is pressed
            key = READ_SWITCHES();   //scan the keys again and again

        return key;                  //when key pressed then return its value
    }

Tengo dificultades para entender que si se llama a la función READ_SWITCHES (void), no hay una sentencia condicional, es decir, una sentencia if-else para verificar si

FilaA = 0; RowB = 1; RowC = 1; RowD = 1;

o

FilaA = 1; FilaB = 0; RowC = 1; RowD = 1;

o

FilaA = 1; RowB = 1; RowC = 0; RowD = 1;

o

FilaA = 1; RowB = 1; RowC = 1; RowD = 0;

Esto tampoco es una declaración de caso. ¿Cómo funciona entonces este código?

EDITAR:

¿No debería haber sido el código como está escrito abajo con las declaraciones if-else? ¿Cómo funciona el código sin las declaraciones if-else o las declaraciones de caso

if{RowA = 0 && RowB = 1 && RowC = 1 && RowD = 1} {...}

else if{RowA = 1 && RowB = 0 && RowC = 1 && RowD = 1;} {...}

else if{RowA = 1 && RowB = 1 && RowC = 0 && RowD = 1;} {...}

else if{RowA = 1 && RowB = 1 && RowC = 1 && RowD = 0;} {...}


else return n;
    
pregunta Anwesa Roy

1 respuesta

0

El sistema funciona al conducir una línea de "fila" en un momento bajo.

Si ve alguna de las bajas de C1-C4 en respuesta (es decir, si se presiona un botón) espera un tiempo de rebote, la espera adicional para que esa línea deje de ser baja (el botón se suelte) y luego devuelve un valor .

Por lo tanto, está escaneando un teclado de matriz.

(Podría decirse que el rebote se realiza incorrectamente, probablemente debería esperar después de ver un lanzamiento, especialmente antes de estar dispuesto a detectar otra prensa. Como se implementó, parece ser susceptible de detectar rebotes en liberación de una tecla presionada durante más tiempo que el tiempo de retardo. Tampoco hay tiempo de permanencia en cada configuración de la unidad de transmisión - muchos más procesadores modernos podrían realizar la verificación y decidir que no se presione ninguna tecla más rápido que la entrada con alguna carga capacitiva que realmente podría cambiar en respuesta a la salida.)

    
respondido por el Chris Stratton

Lea otras preguntas en las etiquetas