我已经编写了用于在 Atmega 328 中读取键盘矩阵的代码。但是我没有得到连接到 Row0 和 Column0 的键的结果。其余所有 3 个键都被正确检测到。下面是代码。我无法弄清楚问题是什么。一定有一个小问题。键盘工作正常,我单独测试过。
#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);
}