2015-02-10 116 views
0

我正试图将Atmega32微控制器与16x2 LCD和4x4键盘矩阵接口。我正在模拟Proteus并使用WinAVR编译器。液晶显示器部分没问题(我已经彻底测试过了)。但键盘代码没有按照我的预期运行。 无论何时我按下某个键,键盘行的扫描将无限期停止将4x4键盘矩阵与Atmega32接口

此外,键不显示在液晶显示器上。请帮我找到错误。

下面是在Proteus中绘制的电路原理图以及代码。因为我知道这部分工作得很好,所以我没有在这里包含LCD的代码。

电路:

enter image description here

代码:

#include <avr/io.h> 
#include<util/delay.h> 



//Keypad Information 
#define R0 0 
#define R1 1 
#define R2 2 
#define R3 3 
#define C0 4 
#define C1 5 
#define C2 6 
#define C3 7 

#define keypadPORT PORTA 
#define keypadPIN PINA 
#define keypadDDR DDRA 


//Keypad functions and global variables 
char getkey(); 
int keypadRow[] = {R0, R1, R2, R3}; //rows of the keypad 
int keypadCol[] = {C0, C1, C2, C3};//columnd 



int main() 
{ 
    char key_pressed; 

    keypadDDR |= (1<<R0)|(1<<R1)|(1<<R2)|(1<<R3);//set upper part of keypad port as output 
               //this will be required for scanning the rows 
    keypadDDR &= ~((1<<C0)|(1<<C1)|(1<<C2)|(1<<C3));//set lower part of keypad port as input.This is 
                //the part of the keypad port where the rows are connected. 

    LCD_init(); //initialize LCD 

    while(1) 
    { 
     key_pressed = getkey(); 
     switch(key_pressed) 
     { 
     case('A'): 
      break;//do nothing if no key is pressed 
     default: 
      send_char(key_pressed);//send the key pressed to LCD 
     } 
    }  
    return 0; 
} 



char getkey() 
{ 
    int i, j; 
    for(i = 0; i < 4; i++) 
    { 
    keypadPORT = 0x00; 
    keypadPORT |= (1 << keypadRow[i]);//send a high to a particular row of the keypad 

    for(j = 0; j < 4; j++) 
    { 
     if(bit_is_set(keypadPIN,keypadCol[j]))//check if key is pressed 
     { 
      while(bit_is_set(keypadPIN,keypadCol[j])); //wait for key to be released 
      switch(i) 
      { 
       case(0): 
       { 
        if (j == 0) return '7'; 
        else if (j == 1) return '8'; 
        else if (j == 2) return '9'; 
        else if (j == 3) return '/'; 
        break; 
       } 
       case(1): 
       { 
        if (j == 0) return '4'; 
        else if (j == 1) return '5'; 
        else if (j == 2) return '6'; 
        else if (j == 3) return '*'; 
         break; 
       } 
       case(2): 
       { 
        if (j == 0) return '1'; 
        else if (j == 1) return '2'; 
        else if (j == 2) return '3'; 
        else if (j == 3) return '-'; 
         break; 
       } 
       case(3): 
       { 
        if (j == 0) return '?'; 
        else if (j == 1) return '0'; 
        else if (j == 2) return '='; 
        else if (j == 3) return '+'; 
         break; 
       } 
      } 
     } 
    } 
    } 
    return 'A';//Return 'A' if no key is pressed. 
} 

回答

0

如果,当你按一个键, “键盘行的扫描停止无限期” 和“关键没有按在液晶显示器上不显示“,然后我会查看任何潜在的无限循环,例如以下行:

while(bit_is_set(keypadPIN,keypadCol[j])); 

我不知道是否列排走地面或保持较高水平,当你松开按键,但你应该能够通过替换该行来检查行为:

send_char('<'); 
while(bit_is_set(keypadPIN,keypadCol[j])); 
send_char('>'); 

如果您确实遇到了无限循环,显示屏会显示你<