我已经编写了用于在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);
}
答案 0 :(得分:1)
仔细观察你的循环,可能是它们不覆盖(0,0)对但是从(1,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);
}