2015-06-07 5 views
0

Я написал код для чтения клавиатуры в Atmega 328. Но я не получаю результат для ключа, связанного с Row0 и Column0. Остановить все 3 клавиши обнаружены правильно. Ниже приведен код. Я не могу понять, в чем проблема. Должна быть небольшая проблема. Клавиатура отлично работает, и я тестировал это отдельно.Проблема с AVR Код клавиатуры

#include "cloudECommon.h" 

#define ROW_DDR DDRD   //I/O Port to which rows are connected 
#define ROW_PORT PORTD  // I/O Port to which rows are connected 
#define COLUMN_PIN PIND  // I/O Port to which columns are connected 
#define COLUMN_DDR DDRD 
#define NUM_ROWS 2   // Number of rows in the keypad 
#define NUM_COLS 2   // number of columns in the keypad 


unsigned char rowBitNumbers[NUM_ROWS] = {0,1}; // Assign port bit numbers based on the hardware connectivity 
unsigned char columnBitNumbers[NUM_COLS] = {6,7}; // Assign port bit numbers based on the hardware connectivity 

// keyAssignments gives the value of the key pressed. This sends out character value to the calling portion. 

unsigned char keyAssignments[NUM_ROWS][NUM_COLS] = { 
                 {'3', 'A'}, 
                 {'6', 'B'}, 
                }; 



void CL_delayMS(unsigned int delayMS) 
{ 
     while(delayMS--) 
     { 
      _delay_ms(1); 
     } 
} 

int initializeKeyPad(void) 
{ 
    unsigned char loopCnt; 

    for(loopCnt=rowBitNumbers[0];loopCnt<=rowBitNumbers[NUM_ROWS-1];loopCnt++) 
    { 
     ROW_DDR &= ~(1<<loopCnt);  // Set direction as input 
     ROW_PORT &= ~(1<<loopCnt); // Keep all rows in high impudence by writing 0. External pull ups are connected. 

    } 

    // Set all columns as inputs 
    for(loopCnt=columnBitNumbers[0]; loopCnt<=columnBitNumbers[NUM_COLS-1]; loopCnt++) 
    { 
     COLUMN_DDR &= ~(1<<loopCnt);   

    } 
    return 0; 
} 


// The following function just reads the state of the switch from the key matrix 
// If detected, returns true. Or returns false. 

unsigned char readSwitch(unsigned char columnNum) 
{ 
    //check if key is pressed. If pressed, wait until it is released. 
    if(!(COLUMN_PIN & (1<<columnNum))) 
    { 
     //wait for release 
     //while(!(COLUMN_PIN & (1<<columnNum))); 

     //Key De bounce. 
     // Need to change this implementation. Time is getting wasted. Even after releasing, CPU will wait for KEY_DEBOUNCE_TIME 

     CL_delayMS(KEY_DEBOUNCE_TIME); 
     if(!(COLUMN_PIN & (1<<columnNum))) 
     { 
      return (1); 
     } 

    } 
     return(0); 
} 

// Function to read the key that is being pressed. 
// Returns the value of the key pressed. 
// First one row will be set low and then all the columns are read. 
// Process is repeated for all the rows. 

unsigned char getKey(void) 
{ 
    unsigned char key='\0'; // If '\0' is returned, no key is pressed. 
    unsigned char rowLoopCount; 
    unsigned char columnLoopCount; 

    //Loop for maximum rows configured 
    for(rowLoopCount=rowBitNumbers[0];rowLoopCount<=rowBitNumbers[NUM_ROWS-1];rowLoopCount++) 
    { 

     // Make the Row as output port. So row will be low at this moment 
     ROW_DDR|=(1<<rowBitNumbers[rowLoopCount]); 
     //CL_delayMS(1); // Wait for 1 msec. 


     // Repeat for columns. Read each column. 
     for(columnLoopCount=columnBitNumbers[0];columnLoopCount<=columnBitNumbers[NUM_COLS-1] ;columnLoopCount++) 
     { 
      if(readSwitch(columnLoopCount)) 
      { 
       key=(keyAssignments[rowLoopCount][columnLoopCount]); 
      } 
     } 

     // Change the direction as input so that port goes to high impedance 
     ROW_DDR &= ~(1<<rowBitNumbers[rowLoopCount]); 

    } 
    return(key); 

    } 

ответ

1

Посмотрите ближе к своим петлям, может быть, они не покрывают (0,0) пару, а начинаются с (1,1).

0

выяснил ошибку. В функции getKey() возникла некоторая проблема. Ниже приведен код (его нельзя оптимизировать). Также я использую строку с открытым коллектором и динамически меняю направление с использованием DDR, чтобы избежать короткого замыкания на клавиатуре при многократном нажатии клавиши. Не уверен, что это правильный метод.

/* 
* keypad.c 
* 
* Created: 30-05-2015 07:09:51 
* 
*/ 
#include "cloudECommon.h" 

#define ROW_DDR DDRD   //I/O Port to which rows are connected 
#define ROW_PORT PORTD  // I/O Port to which rows are connected 
#define COLUMN_PIN PIND  // I/O Port to which columns are connected 
#define COLUMN_DDR DDRD 
#define NUM_ROWS 2   // Number of rows in the keypad 
#define NUM_COLS 2   // number of columns in the keypad 


unsigned char rowBitNumbers[NUM_ROWS] = {2,3}; // Assign port bit numbers based on the hardware connectivity 
unsigned char columnBitNumbers[NUM_COLS] = {0,1}; // Assign port bit numbers based on the hardware connectivity 

// keyAssignments gives the value of the key pressed. This sends out character value to the calling portion. 

unsigned char keyAssignments[NUM_ROWS][NUM_COLS] = { 
                 {'3', 'A'}, 
                 {'6', 'B'}, 
                }; 

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


void CL_delayMS(unsigned int delayMS) 
{ 
     while(delayMS--) 
     { 
      _delay_ms(1); 
     } 
} 

int initializeKeyPad(void) 
{ 
    unsigned char loopCnt; 

    for(loopCnt=rowBitNumbers[0];loopCnt<=rowBitNumbers[NUM_ROWS-1];loopCnt++) 
    { 
     ROW_DDR &= ~(1<<loopCnt);  // Set direction as input 
     ROW_PORT &= ~(1<<loopCnt); // Keep all rows in high impudence by writing 0. External pull ups are connected. 

    } 

    // Set all columns as inputs 
    for(loopCnt=columnBitNumbers[0]; loopCnt<=columnBitNumbers[NUM_COLS-1]; loopCnt++) 
    { 
     COLUMN_DDR &= ~(1<<loopCnt);   

    } 
    return 0; 
} 


// The following function just reads the state of the switch from the key matrix 
// If detected, returns true. Or returns false. 

unsigned char readSwitch(unsigned char columnNum) 
{ 
    //check if key is pressed. If pressed, wait until it is released. 
    if(!(COLUMN_PIN & (1<<columnNum))) 
    { 
     //wait for release 
     //while(!(COLUMN_PIN & (1<<columnNum))); 

     //Key De bounce. 
     // Need to change this implementation. Time is getting wasted. Even after releasing, CPU will wait for KEY_DEBOUNCE_TIME 

     CL_delayMS(KEY_DEBOUNCE_TIME); 
     if(!(COLUMN_PIN & (1<<columnNum))) 
     { 
      return (1); 
     } 

    } 
     return(0); 
} 

// Function to read the key that is being pressed. 
// Returns the value of the key pressed. 
// First one row will be set low and then all the columns are read. 
// Process is repeated for all the rows. 

unsigned char getKey(void) 
{ 
    unsigned char key='\0'; // If '\0' is returned, no key is pressed. 
    unsigned char rowLoopCount; 
    unsigned char columnLoopCount; 

    //Loop for maximum rows configured 
    for(rowLoopCount=rowBitNumbers[0];rowLoopCount<=rowBitNumbers[NUM_ROWS-1];rowLoopCount++) 
    { 

     // Make the Row as output port. So row will be low at this moment 
     ROW_DDR|=(1<<rowBitNumbers[rowLoopCount-rowBitNumbers[0]]); 

     // Repeat for columns. Read each column. 
     for(columnLoopCount=columnBitNumbers[0];columnLoopCount<=columnBitNumbers[NUM_COLS-1] ;columnLoopCount++) 
     { 
      if(readSwitch(columnLoopCount)) 
      { 
       // Since keyAssignments[][] is always starts from 0 and rowBitNumbers[] or columnBitNumbers[] 
       //may not start from 0, we need to subtract the BitNumbers offset. 
       key=(keyAssignments[rowLoopCount-rowBitNumbers[0]][columnLoopCount-columnBitNumbers[0]]); 
      } 
     } 

     // Change the direction as input so that port goes to high impedance 
     ROW_DDR &= ~(1<<rowBitNumbers[rowLoopCount-rowBitNumbers[0]]); 
    } 
    return(key); 

    } 
Смежные вопросы