[Help] Keypad 4x4

lee_trieu

Gà con
Chào mọi người !!
Cho em hỏi chút về việc quét bàn phím hex.

Em viết code như thế này
PHP:
#include "msp430f2122.h"
#define read (P1IN & 0x0F)
 
int scan_code[4]={0xE0,0xD0,0xB0,0x70};
int keyin[4]={0xfE,0xfD,0xfB,0xf7};
int key[4][4]={1,2,3,4,
              5,6,7,8,
              9,0,10,11,
              12,13,14,15};
int c=0,r=0,i,j;
int checkkey(void);
void conf_clock(void)
{
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                 
  {
    while(1);                              // If calibration constants erased
                                            // do not load, trap CPU!!
  }
  BCSCTL1 = CALBC1_1MHZ; //calibration clock - (1MHz , 8MHz, 12MHz, or 16MHz)
  DCOCTL = CALDCO_1MHZ;
 
}
 
void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  conf_clock();
  P1DIR |= 0xf0;
  P2DIR |= 0xff;
  P3DIR |= 0xff;
  conf_lcd(1);
  while(1)
  {
  P1OUT |= 0xf0; //giu 4 cot o muc cao
  checkkey();
  if(key[r][c]==5)//gia su phim 5 duoc an
  {
    P3OUT ^=BIT0;  //thi cho LED nhay
    __delay_cycles(100000);
  }
  }
 
}
//Chuong trinh quet ban phim ma tran
int checkkey()
{
  if(read != 0x0F) //Neu co nut nhan
  {
    for(i=0;i<4;i++)//quet cot(Lan luot keo 4 cot xuong thap)
    {
      P1OUT = scan_code[i];
      for(j=0;j<4;j++)//quet hang
      {
        if(read==keyin[j])
        {
        c=i;
        r=j;
     
        }
      }
    }
  }
  return key[r][c];
}
Mọi người xem giúp em code lỗi chỗ nào mà em làm hoài nó vẫn không chạy:-smất mấy ngày rồi em làm vẫn không ra !! Mọi người vào giúp em với ! Em cảm ơn !!:-(
 

lee_trieu

Gà con

tranhieu_hcmut

Cố Vấn CLB
Staff member
Phần cứng như trên thì đúng rồi. Nhưng code thì chưa ổn. a chưa đọc kỹ code của e nhưng e nên xem lại dòng đầu tiên trong hàm while(1)
P1OUT |= 0xf0; //giu 4 cot o muc cao
 

lee_trieu

Gà con
Phần cứng như trên thì đúng rồi. Nhưng code thì chưa ổn. a chưa đọc kỹ code của e nhưng e nên xem lại dòng đầu tiên trong hàm while(1)
P1OUT |= 0xf0; //giu 4 cot o muc cao
Dạ...Em viết lệnh này để kéo 4 cột lên cao ạ:-(
Ý tưởng quét phím của em thế này

Lần lượt kéo 4 cột xuống mức '0', bằng lệnh:
Code:
 for(i=0;i<4;i++)//quet cot(Lan luot keo 4 cot xuong thap)
    {
      P1OUT = (0xF0&&scan_code[i]);
Sau đó đọc về 4 hàng và so sánh với 4 trường hợp (Keyin)-Keyin là 4 trạng thái của 4 hàng(H0->H3 như hình trên ạ)
Code:
for(j=0;j<4;j++)//quet hang
      {
        if((read&&0x0F)==keyin[j])
Chỗ quét cột em được biến i, chỗ quét để đọc và so sánh với keyin em có được biến j nữa,..rồi em lấy biến i và j làm hai chỉ số để tham chiếu tới mảng 2 chiều chứa giá trị phím nhấn:-s
Code:
return key[r][c];
Giải thuật em là vậy đó, anh chị xem giúp em nó lỗi chỗ nào với ạ ~~:-(
 

tranhieu_hcmut

Cố Vấn CLB
Staff member
Nếu ban đầu e cho cả 4 cột ở mức cao thì dù e có nhấn phím hay không nhấn 4 bit thấp e đọc vào đều là mức 1. cho nên các lệnh trong if(read != 0x0F) //Neu co nut nhan
sẽ không bao giờ thực hiện. E hiểu ý a chứ :1cool_byebye:
 

lee_trieu

Gà con
Nếu ban đầu e cho cả 4 cột ở mức cao thì dù e có nhấn phím hay không nhấn 4 bit thấp e đọc vào đều là mức 1. cho nên các lệnh trong if(read != 0x0F) //Neu co nut nhan
sẽ không bao giờ thực hiện. E hiểu ý a chứ :1cool_byebye:
ah.....Em thấy chỗ này rồi, em cứ nghĩ là đầu tiên lôi cho nó lên cao sau đó lần lượt kéo từng bit xuống thấp chứ:-s Vậy mình bỏ luôn chỗ kéo 4bit lên cao hay sao anh?? Nếu bỏ thì để 4bit này luôn ở trạng thái như thế mới phải ạ???:-(
 

tranhieu_hcmut

Cố Vấn CLB
Staff member
Thì ban đầu e cho 4 cột xuống thấp, sau đó kiểm tra phím quét bằng cách cho từng cột xuống thấp. :2cool_after_boom:
 

lee_trieu

Gà con
Thì ban đầu e cho 4 cột xuống thấp, sau đó kiểm tra phím quét bằng cách cho từng cột xuống thấp. :2cool_after_boom:
Ủa anh !! Ban đầu mình cho 4 cột xuống thấp,rồi sao cho từng cột xuống thấp, nghĩa là cho mỗi lần 3 cột kia lên cao đúng không ạ>>??:-(Và anh ch em hỏi là
P1OUT = 0x00;

P1OUT |= 0x00;
khác nhau như thế nào ạ???:5cool_sweat:
 

tranhieu_hcmut

Cố Vấn CLB
Staff member
A nghĩ là e nên tìm hiểu lại các kiến thức cơ bản C & các ví dụ của clb rồi hãy quay lại làm cái này nhé.:DChúc e thành công!:5cool_beat_plaster:
 

lee_trieu

Gà con
A nghĩ là e nên tìm hiểu lại các kiến thức cơ bản C & các ví dụ của clb rồi hãy quay lại làm cái này nhé.:DChúc e thành công!:5cool_beat_plaster:
Em đang có ứng dụng cần phải làm cho xong cái bàn phím này trước:-s
do cũng mới học msp430 nên còn nhiều chỗ không rõ:-(có gì anh chị cứ chỉ dạy thêm, em chân thành cảm ơn !!!:5cool_sweat:
 

chung

Trứng gà
xem lại phần cứng và lệnh if(read != 0x0F) //Neu co nut nhan đi nhé bạn, có 1 sự xung đột giữa 2 thứ này đấy.
 

lee_trieu

Gà con
xem lại phần cứng và lệnh if(read != 0x0F) //Neu co nut nhan đi nhé bạn, có 1 sự xung đột giữa 2 thứ này đấy.
Em đã sửa lại phần cứng thế này:


Và code:
PHP:
#include "conf_lcd.c"
#include "msp430f2122.h"
#define read (P1IN & 0xF0)
 
 
int scan_code[4]={0x0E,0x0D,0x0B,0x07};
int keyin[4]={0xE0,0xD0,0xB0,0x70};
int key[4][4]={1,2,3,4,5,6,7,8,9,0,10,11,12,13,14,15};
 
int c=0,r=0,i,j,data;
int checkkey(void);
void conf_clock(void)
{
   if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  }
  BCSCTL1 = CALBC1_1MHZ; //calibration clock - (1MHz , 8MHz, 12MHz, or 16MHz)
  DCOCTL = CALDCO_1MHZ;   
  
}
//void push(void);
void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  conf_clock();
  conf_lcd(1);
  P1DIR |= 0x0F;
  P2DIR |= 0xff;
  P3DIR |= 0xff;
 
  while(1)
  {
  
  checkkey();
  lcd_number(data,0,0);
  lcd_clear();
  }
}
 
int checkkey()
{
 
      P1OUT = (0x0F&scan_code[0]);
      for(j=0;j<4;j++)//quet hang
      {
        if(read==(0xF0&keyin[j]))// Neu bang 
        {
        
         return data=key[0][j];
      
        }
      }
      P1OUT = (0x0F&scan_code[1]);
      for(j=0;j<4;j++)//quet hang
      {
        if(read==(0xF0&keyin[j]))// Neu bang 
        {
        
         return data=key[1][j];
      
        }
      }
      P1OUT = (0x0F&scan_code[2]);
      for(j=0;j<4;j++)//quet hang
      {
        if(read==(0xF0&keyin[j]))// Neu bang 
        {
        
         return data=key[2][j];
      
        }
      }
      P1OUT = (0x0F&scan_code[3]);
      for(j=0;j<4;j++)//quet hang
      {
        if(read==(0xF0&keyin[j]))// Neu bang 
        {
        
         return data=key[3][j];
      
        }
      }
      
   
 
 return data;
}
Kết quả ra như thế này:5cool_sweat:


Mọi người cho em hỏi là làm thế nào để cái số hiện trên LCD nó đứng yên ạ????:-sEm test thì thấy nó chạy đúng nhưng mà nó cứ nhấp nháy liên tục là sao ạ????:-(
 

chung

Trứng gà
vì bạn cứ liên tục clear rồi xuất dữ liệu ra LCD nên nó mới nháy, bỏ lệnh clear đi
 

chung

Trứng gà
up toàn bộ cái folder project lên đi chứ có biết cái file lcd của bạn chạy thế nào
 

lee_trieu

Gà con
up toàn bộ cái folder project lên đi chứ có biết cái file lcd của bạn chạy thế nào
Dạ...cái thư viện LCD là của câu lạc bộ đó anh. tại em sửa lại tên lệnh cho dễ nhớ ah=))
link project của em: https://dl.dropboxusercontent.com/u/23155150/Keypad Final - OK.rar

cứ ngồi nghịch đi e...một hồi cũng ra thôi à :gach:5cool_beat_plaster:
Em nghịch mấy LCD này nhiều rồi=))mà vẫn bị dính cái dụ không làm đứng yên được chuỗi hay số ra màn hình, nó cứ nháy hoại vậy á:-s
 

lee_trieu

Gà con
thêm 1 dòng lcd_gotoxy(0,0); trước dòng lcd_number(data,0,0); là đc chứ có gì đâu
Cảm ơn anh nhiều nha !!:)Nãy em có viết lcd_gotoxy(2,2); thử nhưng nó không chạy, giờ xoá luôn cái lệnh clear thì nó chạy ok hết rồi, cảm ơn mọi người nhiều !!:)
 
Top