4x4 Keypad Interfacing with ATmega32 Microcontroller
Trong hướng dẫn này, chúng ta sẽ giao diện bàn phím 4x4 (16 phím) với vi điều khiển ATMEGA32A. Chúng ta biết rằng bàn phím là một trong những thiết bị đầu vào quan trọng nhất được sử dụng trong các dự án điện tử. Bàn phím là một trong những cách dễ nhất để đưa ra lệnh hoặc hướng dẫn cho hệ thống điện tử.
Components Required
Hardware: ATMEGA32, power supply (5v), AVR-ISP PROGRAMMER, JHD_162ALCD (16*2LCD), 100uF capacitor, 100nF capacitor, 10KΩ resistor (8 pieces).
Software: Atmel studio 6.1 or Atmel studio 6.2, progisp or flash magic.
Circuit Diagram and Working Explanation
Trong mạch PORTB của ATMEGA32 được kết nối với màn hình LCD cổng dữ liệu. Ở đây, người ta nên nhớ vô hiệu hóa giao tiếp JTAG trong PORTC ot ATMEGA bằng cách thay đổi các byte cầu chì, nếu người ta muốn sử dụng PORTC như một cổng giao tiếp thông thường. Trong LCD 16x2 có 16 chân trên tất cả nếu có đèn nền, nếu không có đèn nền sẽ có 14 chân. Người ta có thể cấp nguồn hoặc để lại các chân đèn phía sau. Bây giờ trong 14 chân có 8 chân dữ liệu (7-14 hoặc D0-D7), 2 chân cấp nguồn (1 & 2 hoặc VSS & VDD hoặc gnd & + 5v), chân thứ 3 để điều khiển độ tương phản (VEE-điều khiển độ dày của các ký tự sẽ được hiển thị ), và 3 chân điều khiển (RS & RW & E).
Trong mạch, bạn có thể quan sát thấy tôi chỉ lấy hai chân điều khiển, điều này tạo ra sự linh hoạt, bit tương phản và READ / WRITE không thường xuyên được sử dụng nên có thể bị nối đất. Điều này đặt màn hình LCD ở chế độ đọc và độ tương phản cao nhất. Chúng ta chỉ cần điều khiển các chân ENABLE và RS để gửi các ký tự và dữ liệu cho phù hợp.
Các kết nối được thực hiện cho LCD được đưa ra dưới đây:
PIN1 hoặc VSS để nối đất
PIN2 hoặc VDD hoặc VCC đến nguồn + 5v
PIN3 hoặc VEE nối đất (mang lại độ tương phản tối đa tốt nhất cho người mới bắt đầu)
PIN4 hoặc RS (Lựa chọn đăng ký) đến PD6 của uC
PIN5 hoặc RW (Đọc / Ghi) nối đất (đặt màn hình LCD ở chế độ đọc giúp giảm bớt giao tiếp cho người dùng)
PIN6 hoặc E (Bật) đến PD5 của uC
PIN7 hoặc D0 đến PB0 của uC
PIN8 hoặc D1 đến PB1 của uC
PIN9 hoặc D2 đến PB2 của uC
PIN10 hoặc D3 đến PB3 của uC
PIN11 hoặc D4 đến PB4 của uC
PIN12 hoặc D5 đến PB5 của uC
PIN13 hoặc D6 đến PB6 của uC
PIN14 hoặc D7 đến PB7 của uC
Trong mạch các bạn có thể thấy chúng ta đã sử dụng giao tiếp 8bit (D0-D7) tuy nhiên đây không phải là điều bắt buộc, chúng ta có thể sử dụng giao tiếp 4bit (D4-D7) nhưng với giao tiếp 4 bit chương trình trở nên hơi phức tạp. Vì vậy, từ quan sát bảng trên, chúng ta đang kết nối 10 chân của LCD với bộ điều khiển trong đó 8 chân là chân dữ liệu và 2 chân để điều khiển.
Bây giờ hãy nói về bàn phím, bàn phím không là gì khác ngoài các phím ghép lại. Các nút được kết nối dưới dạng ghép kênh để giảm mức sử dụng pin của hệ thống điều khiển.
Hãy xem xét chúng ta có một bàn phím 4x4, trong bàn phím này chúng ta có 16 nút, trong trường hợp bình thường, chúng ta cần 16 chân điều khiển để giao diện 16 nút, nhưng điều này không tốt trong quan điểm hệ thống điều khiển. Việc sử dụng pin này có thể được giảm bớt bằng cách kết nối các nút ở dạng ghép kênh.
Ví dụ: hãy xem xét chúng ta có 16 nút và chúng ta muốn gắn nó vào bộ điều khiển để tạo thành bàn phím, các phím này được sắp xếp như trong hình:
CODE :
#include <avr/io.h>
//header to enable data flow control over pins
#define F_CPU 1000000
//telling controller crystal frequency attached
#include <util/delay.h>
//header to enable delay function in program
#define E 5
//giving name “enable” to 5th pin of PORTD, since it Is connected to LCD enable pin
#define RS 6
//giving name “registerselection” to 6th pin of PORTD, since is connected to LCD RS pin
void send_a_command(unsigned char command);
void send_a_character(unsigned char character);
void send_a_string(char *string_of_characters);
int main(void)
{
DDRB = 0xFF;
//putting portB and portD as output pins
DDRD = 0xFF;
_delay_ms(50);//giving delay of 50ms
int key=0;//allocating integer to reset the LCD once it reaches its display limit
int keypressed=0;//integer for storing matrix value
send_a_command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(50);
send_a_command(0x38);//telling lcd we are using 8bit command /data mode
_delay_ms(50);
send_a_command(0b00001111);//LCD SCREEN ON and courser blinking
send_a_string("PRESS A KEY");//displaying a string
send_a_command(0x80 + 0x40 +0);// moving courser to second line of LCD
DDRA=0xF0;//taking column pins as input and row pins as output
_delay_ms(1);
PORTA=0x0F;// powering the row ins
_delay_ms(1);
while(1)
{
if (PINA!=0b11110000)//in any of column pins goes high execute the loop
{
_delay_ms(5);
keypressed = PINA;//taking the column value into integer
DDRA ^=0b11111111;//making rows as inputs and columns as ouput
_delay_ms(1);
PORTA ^= 0b11111111;//powering columns
_delay_ms(1);
keypressed |=PINA;taking row value and OR ing it to column value
if (keypressed==0b00010001)
{
send_a_string("1");//if row1 and column1 is high show “1”
key++;
}
if (keypressed==0b00010010)
{
send_a_string("4");// if row1 and column2 is high show “4”
key++;
}
if (keypressed==0b00010100)
{
send_a_string("7");// if row1 and column3 is high show “7”
key++;
}
if (keypressed==0b00011000)
{
send_a_string("*");//if row1 and column4 is high show “*”
key++;
}
if (keypressed==0b00100001)
{
send_a_string("2");// if row2 and column1 is high show “2”
key++;
}
if (keypressed==0b00100010)
{
send_a_string("5");// if row2 and column2 is high show “5”
key++;
}
if (keypressed==0b00100100)
{
send_a_string("8");// if row2 and column3 is high show “8”
key++;
}
if (keypressed==0b00101000)
{
send_a_string("0");// if row2 and column4 is high show “0”
key++;
}
if (keypressed==0b01000001)
{
send_a_string("3");
key++;
}
if (keypressed==0b01000010)
{
send_a_string("6");
key++;
}
if (keypressed==0b01000100)
{
send_a_string("9");
key++;
}
if (keypressed==0b01001000)
{
send_a_string("#");
key++;
}
if (keypressed==0b10000001)
{
send_a_string("A");
key++;
}
if (keypressed==0b10000010)
{
send_a_string("B");
key++;
}
if (keypressed==0b10000100)
{
send_a_string("C");
key++;
}
if (keypressed==0b10001000)
{
send_a_string("D");
key++;
}
keypressed=0;//after showing integer erasing the row column memory
DDRA ^=0b11111111;//shifting input and power port
_delay_ms(1);
PORTA ^= 0b11111111;//powering row pins of keypad
_delay_ms(220);
}
if (key==16)//if 16 characters are shown on LCD
{
send_a_command(0x01);//clear lcd
send_a_string("PRESS A KEY");//display string
send_a_command(0x80 + 0x40 +0);//move courser to second line.
key=0;
}
}
}
void send_a_command(unsigned char command)
{
PORTA = command;
PORTD &= ~ (1<<RS); //putting 0 in RS to tell lcd we are sending command
PORTD |= 1<<E; //telling lcd to receive command /data at the port
_delay_ms(50);
PORTD &= ~1<<E;//telling lcd we completed sending data
PORTA= 0;
}
void send_a_character(unsigned char character)
{
PORTA= character;
PORTD |= 1<<RS;//telling LCD we are sending data not commands
PORTD |= 1<<E;//telling LCD to start receiving command/data
_delay_ms(50);
PORTD &= ~1<<E;//telling lcd we completed sending data/command
PORTA = 0;
}
void send_a_string(char *string_of_characters)
{
while(*string_of_characters > 0)
{
send_a_character(*string_of_characters++);
}
}