Ý tưởng bài toán ?
Tạo 1 mạch khóa số đơn giản dùng ma trận phím 4×3 để nhập mật khẩu và hiển thị LCD. Khi người dùng nhập đúng mật khẩu sẽ cho phép mở cửa, sai mật khẩu báo lỗi và sai 3 lần thì phát ra tín hiệu cảnh báo.
1. Đọc Ma Trận Phím 4×3
Ma trận phím 4×3 gồm 12 nút bấm được sắp xếp theo ma trận 4 hàng 3 cột. Các nút bấm trong cùng 1 hàng và 1 cột được nối với nhau, vì vậy có tổng cộng 7 ngõ ra.
Sơ đồ nguyên lý
Để tiện cho việc mô phỏng ta dùng KEYPAD-PHONE trong proteus
- Ma trận phím 4×3 cho phép các bạn nhập các chữ số, chữ cái, kí hiệu vào bộ điều khiển qua đó dùng để điều khiển một thiết bị ngoại vi nào đó.
Để giao tiếp được với ma trận phím 4×3, dùng phương pháp quét theo cột để kiểm tra xem nút nào được bấm cụ thể như sau:
- Các hàng Row 1 => Row 4 được dùng làm các chân INPUT (giá trị ban đầu cho = 1), các cột Col 1 =>Col 3 là các chân OUTPUT.
- Lần lượt cho từng cột = 0 các cột còn lại = 1 (cho số 0 chạy như kỹ thuật quét Led trong bài Led ma trận) và đọc giá trị của các hàng. Hàng nào bị kéo xuống 0 chứng tỏ nút được bấm. Dựa vào vị trí cột = 0 và hàng = 0 ta xác định được giá trị nút bấm.
- Giả sử nút số 9 được bấm
- Cho Col 1=0, kiểm tra trạng thái của các hàng.
Khi đó giá trị của các Rows bằng bao nhiêu?
- Cho Col 2=0 (Col 1 3=1), kiểm tra các hàng.
Khi đó giá trị của các Rows bằng bao nhiêu?
- Cho Col 3=0, kiểm tra các hàng.
Khi đó giá trị của các Rows bằng bao nhiêu?
Ta xây dựng ma trận (2 chiều) cho phím:
keypad[4][3]={‘1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,’*’,’0′,’#’};
như ví dụ trên ta xác định được có phím bấm trên hàng 3 cột 3, tra mã keypad[3][3]= 9 từ đó vi điều khiển hiểu được phím 9 vừa được bấm. Hàm quét phím tham khảo code bên dưới.
2. Mạch mô phỏng Khóa Số
//CODE:
#include <REGX51.H>
//Khai bao LCD------------------
sbit LCD_RS = P2^7;
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^5;
sbit LCD_D4 = P2^4;
sbit LCD_D5 = P2^3;
sbit LCD_D6 = P2^2;
sbit LCD_D7 = P2^1;
//-----------------------------------
sbit Relay = P3^6;
sbit Buzz =P3^7;
unsigned char code keypad[4][3]={'1','2','3','4','5','6','7','8','9','*','0','#'};
unsigned char pass[6]={'1','1','1','1','1','1'};
unsigned char check[6];
//----------------------------------------------------------------------------------
void Delay_ms(unsigned int t)
{
unsigned int x,y;
for(x=0;x<t;x++)
{
for(y=0;y<123;y++);
}
}
void Delay_us(unsigned int t)
{
while(t--);
}
void LCD_Enable(void)
{
LCD_EN =1;
Delay_us(3);
LCD_EN=0;
Delay_us(50);
}
void LCD_Send4Bit(unsigned char Data)
{
LCD_D4=Data & 0x01;
LCD_D5=(Data>>1)&1;
LCD_D6=(Data>>2)&1;
LCD_D7=(Data>>3)&1;
}
void LCD_SendCommand(unsigned char command)
{
LCD_Send4Bit(command >>4);
LCD_Enable();
LCD_Send4Bit(command);
LCD_Enable();
}
void LCD_Clear()
{
LCD_SendCommand(0x01);
Delay_us(10);
}
void LCD_Init()
{
LCD_Send4Bit(0x00);
Delay_ms(20);
LCD_RS=0;
LCD_RW=0;
LCD_Send4Bit(0x03);
LCD_Enable();
Delay_ms(5);
LCD_Enable();
Delay_us(100);
LCD_Enable();
LCD_Send4Bit(0x02);
LCD_Enable();
LCD_SendCommand(0x28);
LCD_SendCommand(0x0c);
LCD_SendCommand(0x06);
LCD_SendCommand(0x01);
}
void LCD_Gotoxy(unsigned char x, unsigned char y)
{
unsigned char address;
if(!y) address=(0x80+x);
else address=(0xc0+x);
Delay_us(1000);
LCD_SendCommand(address);
Delay_us(50);
}
void LCD_PutChar(unsigned char Data)
{
LCD_RS=1;
LCD_SendCommand(Data);
LCD_RS=0 ;
}
void LCD_Puts(char *s)
{
while (*s){
LCD_PutChar(*s);
s++;
}
}
void warning()
{
unsigned char count = 10;
while(count--)
{
Buzz= 1;
Delay_ms(200);
Buzz =0;
Delay_ms(200);
}
}
unsigned char quetphim()
{
unsigned char c, r;
P1=0x0F;
Delay_us(2);
if(P1!=0x0F) //Điều kiện này có nghĩa gì?
{
for(c=0;c<3;c++) //Tiến hành quét từng cột
{
P1=~(0x01<<(4+c));
Delay_ms(1);
for(r=0;r<4;r++) //Tiến hành kiểm tra từng hàng
{
if((P1&(0x01<<r))==0)
{
while((P1&(0x01<<r))==0) {};
return keypad[r][c]; //Hàm này làm gì?
}
}
}
}
return 0;
}
unsigned char sosanh(unsigned char a[], unsigned char b[])
{
unsigned char i;
for(i=0;i<6;i++)
{
if(a[i]!=b[i]) return 0;
}
return 1;
}
void main()
{
unsigned char key=0,i=0,j=0;
LCD_Init();
Relay=0;
Buzz = 0;
while(1)
{
LCD_Clear();
LCD_Gotoxy(0,0);
LCD_Puts("ENTER PASSWORD:");
LCD_Gotoxy(0,1);
i=0;
while(i<6)
{
key=quetphim();
if(key)
{
LCD_Gotoxy(i,1);
LCD_PutChar(key);
check[i]=key;
key=0;
i++;
}
}
if(sosanh(pass,check))
{
LCD_Gotoxy(0,1);
LCD_Puts("Load...");
Relay=1;
Delay_ms(3000);
Relay=0;
j=0;
}
else
{
j++;
if(j>=3)
{
LCD_Gotoxy(0,1);
LCD_Puts("Warning...");
warning();
j=0;
}
else
{
LCD_Gotoxy(0,1);
LCD_Puts("Error...");
Delay_ms(500);
}
}
}
}
Sử dụng phương pháp quét matran phím 4×3 và hiển thị LCD