0

我正在尝试为键盘输入实现 FIFO 队列,但似乎无法使其工作。我能够让键盘输入出现在 LCD 屏幕上,但这就是我所能做的。我认为代码应该读取键盘输入并将其推入队列,然后弹出键盘输入并将值读取到 LCD 屏幕上。谁能告诉我为什么它不显示我按下的所有值?谢谢你。

#include "project.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

// Keypad Variables

char KeyPad[4][4] = {
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}, 
};

char ReadKeyPad();

// FIFO Variables

struct FIFO {
    char            key;
    struct  FIFO    *next;
};

struct FIFO KeyQueue[] = {
    {0, &KeyQueue[1]},  //[0]
    {0, &KeyQueue[2]},  //[1]
    {0, &KeyQueue[3]},  //[2]
    {0, &KeyQueue[4]},  //[3]
    {0, &KeyQueue[5]},  //[4]
    {0, &KeyQueue[6]},  //[5]
    {0, &KeyQueue[7]},  //[6]
    {0, &KeyQueue[8]},  //[7]
    {0, &KeyQueue[0]}   //[8]
};

struct FIFO *Head;
struct FIFO *Tail;
int KeyQueue_Size=0;
bool KeyQueue_IsEmpty();
bool KeyQueue_IsFull();
void KeyQueue_Push(char key);
char KeyQueue_Pop();
char ReadKeyPad();

int delay = 10;

int main(void)
{
    Head = Tail = &KeyQueue[0];
    char key;

    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

    LCD_Start();
    LCD_ClearDisplay();
    LCD_Enable();

    for(;;)
    {
        /* Place your application code here. */
        key = ReadKeyPad();
        LCD_Position(1,8);
        LCD_PutChar(key);

        if (key !=0)
        {
            if (!KeyQueue_IsFull())   
                KeyQueue_Push(key);
        }
        //task for poping key
        delay --;
        if(delay <= 0 && !KeyQueue_IsEmpty())
        {
            KeyQueue_Pop();
            switch (key)
            {
                case '1':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 1");
                break;
                case '2':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 2");
                break;
                case '3':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 3");
                break;
                case '4':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 4");
                break;
                case '5':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 5");
                break;
                case '6':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 6");
                break;
                case '7':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 7");
                break;
                case '8':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 8");
                break;
                case '9':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 9");
                break;
                case 'A':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed A");
                break;
                case 'B':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed B");
                break;
                case 'C':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed C");
                break;
                case 'D':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed D");
                break;
                case '*':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed *");
                break;
                case '#':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed #");
                break;
                case '0':
                    LCD_Position(0,1);
                    LCD_PrintString("You pressed 0");
                break;
                delay = 10;            
            }

            CyDelayUs(100);
        }   

    }
}

bool KeyQueue_IsEmpty()
{
    if(KeyQueue_Size == 0) return true;
    return false;
}
bool KeyQueue_IsFull()
{
    //if (Head == Tail) return truel
    if(KeyQueue_Size ==9) return true;
    return false;
}
void KeyQueue_Push(char key)
{
    Head->key=key;
    Head = Head->next;
    KeyQueue_Size ++;
}
char KeyQueue_Pop()
{
    char key;
    key = Tail->key;
    Tail = Tail->next;
    KeyQueue_Size --;
    return key;
}
char ReadKeyPad()
{    
    int     i;
    char    key;
    uint8_t col;

    for (i=0; i<4; i++)
    {
        key = 0;
        ROW_Write(1<<i);
        col=COL_Read();
        //LCD_Position(1,0);
        //LCD_PrintNumber(key);

        if (col & 0x01) key=KeyPad[i][0];
        if (col & 0x02) key=KeyPad[i][1];
        if (col & 0x04) key=KeyPad[i][2];
        if (col & 0x08) key=KeyPad[i][3];
        if (key != 0) break;
    }

    return key;
}
4

1 回答 1

0

您的代码中的一些问题:

  • 如前所述,delay = 10;位置不好
  • keymain 函数的变量仅在for循环开始时设置。

所以一个更正的代码可能是:

for(;;)
{
    key = ReadKeyPad();
    LCD_Position(1,8);
    LCD_PutChar(key);

    if (key !=0)
    {
        if (!KeyQueue_IsFull())   
            KeyQueue_Push(key);
    }
    //task for poping key
    delay --;
    if(delay <= 0 && !KeyQueue_IsEmpty())
    {
        /* don't forget to store what have been poped from fifo */
        key = KeyQueue_Pop();


        switch (key)
        {
            case '1':
                LCD_Position(0,1);
                LCD_PrintString("You pressed 1");
                delay = 10;
            break;
            case '2':
                LCD_Position(0,1);
                LCD_PrintString("You pressed 2");
                delay = 10;
            break;
            /*
             .
             .
             .
             */                
            case '0':
                LCD_Position(0,1);
                LCD_PrintString("You pressed 0");
                delay = 10;
            break;                           
        }

        CyDelayUs(100);
    }   
}

也许你可以写得更短:

for(;;)
{
    key = ReadKeyPad();
    LCD_Position(1,8);
    LCD_PutChar(key);

    if (key !=0)
    {
        if (!KeyQueue_IsFull())   
            KeyQueue_Push(key);
    }
    //task for poping key
    delay --;
    if(delay <= 0 && !KeyQueue_IsEmpty())
    {
        /* don't forget to store what have been poped from fifo */
        key = KeyQueue_Pop();

        /* print what have been pressed */
        LCD_Position(0,1);
        LCD_PrintString("You pressed ");
        LCD_Position(0,12);
        LCD_PutChar(key);
        delay = 10;

        CyDelayUs(100);
    }   
}
于 2017-12-05T14:11:58.147 回答