Chào mừng đến với Câu Lạc Bộ Sáng Tạo
Chia sẻ kinh nghiệm
Kết nối đam mê
Đang cập nhật thời gian...
BÀI VIẾT NỔI BẬT
Xin chào! Tôi là Ếch Sáng Tạo :-)
Chia sẻ trang




Chuyên mục
Bài mới
Xem nhiều
Thống kê
    Đang tải..
Bài viết
Bài 15: Lập trình quét phím matrix 4x4 hiển thị lên LCD 16x2 - SangTaoClub.Net
Bài 15: Lập trình quét phím matrix 4x4 hiển thị lên LCD 16x2
Đăng bởi: Vũ Văn Thái - Thời gian: 20-11-2014, 08:57
Chuyên mục: Học lập trình 8051 - Lượt xem: 34.055

Lập trình quét phím matrix 4x4 hiển thị lên LCD 16x2

       Chào các bạn, ở các bài trước chúng ta đã tìm hiểu về quét nút nhấn đơn thì hôm nay mình sẽ hướng dẫn các bạn lập trình với matrix nút nhấn 4x4 - có thể mở rộng lên tùy thích. Quét ma trận phím hơi phức tạp hơn so với kiểm tra logic của chân MCU như ở các bài trước cụ thể nguyên lý như sau: Khi ta cấp logic 0 ra all hàng để chờ sự kiện nút được nhấn, nếu nút được nhấn thì ta mới cấp lần lượt mức logic 0 ra từng hàng (VD cấp cho hàng 1 logic 0 thì các hàng khác phải lên login 1) sau đó kiểm tra cột xem nó ở cột thứ bao nhiêu, nếu trùng cột và hàng cùng logic 0 thì ta sẽ xác định được vị trí nút được nhấn.

1. Sơ đồ phần cứng ma trận nút nhấn 4x4:

2. Code lập trình: Áp dụng cho mọi vi điều khiển, khai báo lại để tương thích với trình biên dịch

unsigned char check_but(){ //Kiểm tra nút nhấn
        row0=row1=row2=row3=0; //Xuất logic 0 ra các hàng để kiểm tra
        if(!col0 || !col1 || !col2 || !col3 )return 1; //OK có nút được nhấn
        return 0; //Bỏ qua, không có nút nào được nhấn
}
void scan_row(unsigned char r){ //Quét hàng
        row0=row1=row2=row3=1;
        if(r==0)row0=0;
        else if(r==1)row1=0;
        else if(r==2)row2=0;
        else if(r==3)row3=0;
}
unsigned char check_col(){ //Kiểm tra cột
        unsigned char c=0;
        if(!col0)c=1; 
        else if(!col1)c=2;
        else if(!col2)c=3;
        else if(!col3)c=4;
        return c; //Trả về vị trí cột
}
unsigned char get_key(){ //Hàm trả về vị trí nút nhấn 1-16, bằng 0 là không nhấn
        unsigned char row,col;
        if(check_but()){ //Kiểm tra xem có nút nào được nhấn không
                delay_ms(5); //Chống rung phím do tiếp xúc kém
                if(check_but()){ //Nếu đúng là nút đang nhấn không phải do rung phím
                        for(row=0;row<4;row++){
                                scan_row(row); // Quét hàng
                                col=check_col(); //Lấy vị trí cột
                                if(col>0)return ((row*4)+col); //Trả về hàm vị trí nút nhấn
                        }
                }
        }
        return 0; //Không có nút nào được nhấn hoặc đã nhả nút
}

3. Mạch mô phỏng trên proteus:

** Các bạn tải code đầy đủ về trong file đính kèm............

Chúc các bạn học tốt!


Tải về đính kèm:
quet_phim_4x4_1416448673.zip
Kích thước: 33.51 KB


  • Bạn chưa đăng nhập, không thể viết bình luận!
    Bấm vào đây để Đăng nhập hoặc Đăng ký!
  • hdjdjdjjdjdzzz lúc 27-07-2023, 12:38
    File đính kèm ở đâu v thầy
  • kiuhai lúc 17-04-2021, 18:59
    ĐỀ:Viết chương trình nhập pass từ bàn phím Keypad 4x3
    - Pass là số có 4 chữ số.
    - Nhấn # nếu muốn kiểm tra pass có đúng không?
    Đúng thì hiển thị “RIGHT!”
    Sai thì hiển thị “WRONG!”
    #include<LiquidCrystal.h>
    #include<Keypad.h>
    #include<EEPROM.h>
    #define led A3
    #define buzzer A4
    char password[4];
    char pass,pass1[4];
    int i;
    char key=0;
    const byte hang=4;
    const byte cot=3;
    byte pin_hang[4]={10,11,12,13};
    byte pin_cot[3]={7,8,9};
    byte ma_banphim[4][3]={{'1','2','3'},
                            {'4','5','6'},
                            {'7','8','9'},
                            {'*','0','#'}};
    Keypad AKey=Keypad(makeKeymap(ma_banphim),pin_hang,pin_cot,hang,cot);
    LiquidCrystal lcd(5,4,3,2,1,0);
    void setup() {
       lcd.begin(16,2);
       pinMode(led,OUTPUT);
       pinMode(buzzer,OUTPUT);
       pinMode(1,OUTPUT);
       lcd.print("Electronic");
       lcd.setCursor(0,1);
       lcd.print("Keypad Lock");
       delay(2000);
       lcd.clear();
       lcd.print("Enter ur Passkey:");
       lcd.setCursor(0,1);
       for(int j=0;j<4;j++)
       EEPROM.write(j,j+74);
       for(int j=0;j<4;j++)
       pass[j]=EEPROM.read(j);
    }
    void loop() {
       AKey=AKeypad.getKey();
       if(key=='*123#')
        change();
       if(key){
        password[i++]=key;
        lcd.print(key);
        beep();
       }
       if(i==4)
       {
        delay(200);
        for(int j=0;j<4;j++)
        pass[j]=EEPROM.read(j);
        if(!(strncmp(password,pass,4))){
           digitalWrite(1,HIGH);
           digitalWrite(led,HIGH);
           beep();
           lcd.clear();
           lcd.print("Pass Accepted");
           delay(2000);
           lcd.setCursor(0,1);
           lcd.print("*123#.Change Passkey";
           delay(2000);
           lcd.clear();
           lcd.print("Enter Passkey");
           lcd.setCursor(0,1);
           i=0:
           digitalWrite(led,LOW);
           digitalWrite(1,LOW);
        }
        else
        {
           digitalWrite(buzzer,HIGH);
           lcd.clear();
           lcd.print("Access Denied...");
           lcd.setCursor(0,1);
           lcd.print("*123#.Change Passkey");
           delay(2000);
           lcd.clear();
           lcd.print("Enter Passkey");
           lcd.setCursor(0,1);
           i=0;
           digitalWrite(buzzer,LOW);}}
        }
        void change()
        {
          int j=0;
          lcd.clear();
          lcd.print("UR Current Passkey");
          lcd.setCursor(0,1);
          while(j<4)
          {
           char SKey=AKeypad.getKey();
           if(Skey)
           {
             pass1[j++]=SKey;
             lcd.print(SKey);
             beep();
           }
           SKey=0;
          }
          delay(500);
          if((strncmp(pass1,pass,4)))
          {
           lcd.clear();
           lcd.print("Wrong Passkey");
           lcd.setCursor(0,1);
           lcd.print("Better Luck Again");
           delay(1000);
          }
          else
          {
           j=0
           lcd.clear();
           lcd.print("Enter New Passkey");
           lcd.setCursor(0,1);
           while(j<4)
           {
             char Skey=AKeypad.getKey();
             if(SKey)
             {
              pass[j]=SKey;
              lcd.print(Skey);
              EEPROM.write(j,SKey);
              j++;
              beep();
             }
           }
           lcd.print("Done.....");
           delay(1000);
          }
          lcd.clear();
          lcd.print("Enter Ur Passkey");
          lcd.setCursor(0,1);
          AKey=0;
           }
        void beep()
        {
           digitalWrite(buzzer,HIGH);
           delay(200);
           digitalWrite(buzzer,LOW);
        }
    Xem giúp em code bị lỗi gì ạ
  • canhvktech lúc 13-03-2017, 03:53
    thanks
    thank you for comming and sharing with me!
  • Vũ Văn Thái lúc 07-08-2015, 07:56
    Bạn sai ở chỗ hàm gửi ký tự, code bạn viết là gửi một ký tự chứ không phải chuỗi, trong trình biên dịch nó hiểu dấu nháy kép là gửi chuỗi còn nháy đơn là gửi một ký tự ascii, bạn sửa lại là được.
  • congdanh lúc 06-08-2015, 08:48
    Viết bình luận xem hộ em cái code sao nó cứ báo lỗi"lệnh"vậy
    #include <AT89x51.H>
    #include <string.h>
    sbit RS=P3^0;
    sbit RW=P3^1;
    sbit EN=P3^2;
    sbit BF=P2^7;
    void delay(int time){
    while(time--);
    }
    void ban(){
    P2=0xff;
    RS=0;
    RW=1;
    while(BF){
    delay(100);
    EN=1;
    delay(100);
    EN=0;
    }
    }
    void dulieu(unsigned char a){
    ban();
    RS=1;
    RW=0;
    P2=a;
    delay(100);
    EN=0;
    delay(100);
    EN=1;
    }
    void kitu(unsigned char x){
    ban();
    RS=0;
    RW=0;
    P2=x;
    delay(100);
    EN=0;
    delay(100);
    EN=1;
    }
    void khoitao()
    {
                lenh(0x38);//2 dong va ma tran 5x7
                lenh(0x0e);//bat man hinh, bat con tro
                lenh(0x01);//xoa man hinh
          }
    void chuoi(unsigned char *s){
    int i,l;
    l=strlen(s);
    for(i=0;i<l;i ){
    kitu(s[i]);
    delay(500);
    }
    }

        void main(){
    lenh();
       kitu("A");
       while(1);
        }
  • Vũ Văn Thái lúc 13-01-2015, 17:23
    K phải đâu nha, viết trên keilc cho 8051
  • zinedine lúc 13-01-2015, 15:23
    void scan_row(unsigned char r){ //Quét hàng
    Dòng này nếu viết trên arduino thì phải làm sao vậy A Thái?
  • Vũ Văn Thái lúc 21-12-2014, 05:56
    MCU là tên tiếng anh viết tắt của vi điều khiển. Trở kéo là để tạo logic khi chân đó bị hở tức ở trạng thái cao trở và không có tác dụng chống rung phím. Vì sao lại dùng trở 10K là vì với điện trở trên khi ta để hở chân mcu và một đầu trở nối lên vcc ta sẽ được logic cao, khi ta nối chân mcu xuống mass ta sẽ được mức 0 điện trở lúc này có nhiệm vụ phân áp. điện trở càng cao thì dòng vào tạo logic 0 càng nhỏ, vd nếu dùng trở 1K thì để kéo chân này xuống 0 sẽ cao hơn là dùng trở 4,7K với 10K, nếu bạn chọn điện trở quá cao thì nó sẽ trở về trạng thái cao trở như ban đầu...
  • xuanhai lúc 20-12-2014, 20:25
    hj anh ơi ! chân MCU LÀ gì ạ ?anh cho em hỏi luôn một câu .dùng điện trở treo thường là chông rung phím đúng ko ạ ,nhưng lám sao mà mình lại lấy điện trở treo 10k
  • Vũ Văn Thái lúc 20-12-2014, 06:41
    Do mức 1 của chân MCU thường là dùng trở câu lên vcc cho lên người ta tận dụng luôn trở câu này tạo logic 1 và dùng mức 0 để quét phím, xuất led.... dòng ra của mức 0 cao hơn dòng của mức 1 lên nếu mắc led sẽ sáng hơn...
  • Trang 1/2: 12Sau

    Bài viết cùng chuyên mục
    Điều khiển tốc độ động cơ Motor DC sử dụng PWM Điều khiển tốc độ động cơ Motor DC sử dụng PWM
    Đăng bởi: kienvuce - Thời gian: 04-11-2021, 22:40
    Chuyên mục: Học lập trình 8051 - Lượt xem: 3.786
    Chia sẻ bộ thư viện Driver chuẩn cho LCD Gphone và Home Phone Chia sẻ bộ thư viện Driver chuẩn cho LCD Gphone và Home Phone
    Đăng bởi: Vũ Văn Thái - Thời gian: 22-02-2017, 14:54
    Chuyên mục: Học lập trình 8051 - Lượt xem: 7.016
    Led 7 thanh 4 số điều khiển bằng nút bấm Led 7 thanh 4 số điều khiển bằng nút bấm
    Đăng bởi: HoangQuan69 - Thời gian: 09-10-2016, 15:08
    Chuyên mục: Học lập trình 8051 - Lượt xem: 6.626
    Chia sẻ Code đồng hồ số hiển thị trên LED 7 đoạn dùng 89S52 và DS1307 Chia sẻ Code đồng hồ số hiển thị trên LED 7 đoạn dùng 89S52 và DS1307
    Đăng bởi: Vũ Văn Thái - Thời gian: 13-05-2015, 09:00
    Chuyên mục: Học lập trình 8051 - Lượt xem: 29.978
    [Share] Code giao tiếp Graphic LCD 12864 SPI của máy GPHONE ZTE [Share] Code giao tiếp Graphic LCD 12864 SPI của máy GPHONE ZTE
    Đăng bởi: Vũ Văn Thái - Thời gian: 12-11-2014, 22:06
    Chuyên mục: Học lập trình 8051 - Lượt xem: 20.179
    [Share] Code C đo nhiệt độ dùng DS18B20 hiển thị lên LED 7 thanh [Share] Code C đo nhiệt độ dùng DS18B20 hiển thị lên LED 7 thanh
    Đăng bởi: Vũ Văn Thái - Thời gian: 12-11-2014, 09:02
    Chuyên mục: Học lập trình 8051 - Lượt xem: 20.508
    Bài 14: Đo nhiệt độ dùng cảm biến DS18B20 với 8051 Bài 14: Đo nhiệt độ dùng cảm biến DS18B20 với 8051
    Đăng bởi: Vũ Văn Thái - Thời gian: 19-10-2014, 10:11
    Chuyên mục: Học lập trình 8051 - Lượt xem: 26.480
    Bài 13: Đo nhiệt độ dùng LM35 kết hợp IC ADC0808 với 8051 Bài 13: Đo nhiệt độ dùng LM35 kết hợp IC ADC0808 với 8051
    Đăng bởi: Vũ Văn Thái - Thời gian: 22-08-2014, 22:18
    Chuyên mục: Học lập trình 8051 - Lượt xem: 47.425
    Bài 12: Tạo xung PWM dùng ngắt timer 8051 Bài 12: Tạo xung PWM dùng ngắt timer 8051
    Đăng bởi: Vũ Văn Thái - Thời gian: 02-03-2014, 20:45
    Chuyên mục: Học lập trình 8051 - Lượt xem: 25.272
    Bài 11: Lập trình quét LED 7 đoạn và nút nhấn Bài 11: Lập trình quét LED 7 đoạn và nút nhấn
    Đăng bởi: Vũ Văn Thái - Thời gian: 19-12-2013, 11:02
    Chuyên mục: Học lập trình 8051 - Lượt xem: 54.668
    Chào mừng kkkk06 đã tham gia câu lạc bộ sáng tạo!
    Vũ Văn Thái - vuthai
    Hôm nay là sinh nhật của nkocvipvodoi, vietduy, nguyenkhachuy, dohoainhu94, phamtieuvi, hoavci36, nguyenkhachuy53ddt, teotetua, HaVan_93, huybean2609, vuthanh1971, thientubatpham, aq_codientu, Kiatythep, hocuongz95, haisonitu, boysontay, haisonwmn, thongvn_95, vietbmw1986, ← Gửi tin nhắn chúc mừng
    Múi giờ: UTC+07:00 - Asia/Ho Chi Minh ***** IP của bạn: 18.223.195.30 ***** Status: Cache Update thành công!