Lập trình bàn phím 4×4 với vi điều khiển PIC16F877

Bài viết này sẽ hướng dẫn các bạn quét bàn phím (keypad) 4×4 và hiển thị ký tự được ấn lên LCD 16×2, vi điều khiển mình sử dụng là PIC16F877 và IDE sử dụng là PIC C Compiler 5.048. Sơ đồ mạch các bạn xem ở hình dưới.

Sơ đồ mạch nguyên lý trên Proteus

Code PIC16F877

/**
   @uthor https://nvtienanh.info
   @brief Demo Keypad and LCD PIC16F877
*/
#include <16f877.h>
#device *=16 adc=10 
#fuses hs, nowdt, noprotect, nolvp, put, brownout
#use delay(clock=20000000)
#include <lcd.h>
#include <Keypad.h>
#include <function_lcd.c>
#include <Keypad.c>

// 4-Bits Interface
void main()
{
  unsigned char line1[16], line2[16];
  char Key = 'n';       // Variable to store pressed key value
  InitKeypad();       // Initialize Keypad pins
  LCD_Init();
  delay_ms(10);
  sprintf(line1," DEMO KEYPAD   ");
  sprintf(line2," nvtienanh.com ");
  LCD_Gotoxy(0,0);
  LCD_Puts(line1);
  LCD_Gotoxy(1,0);
  LCD_Puts(line2);
 while(TRUE)
 {
     Key = GetKey();
     LCD_Clear();
     LCD_Gotoxy(0,0);
     LCD_PutChar(Key);
     LCD_Gotoxy(1,0);
     LCD_Puts(line2);
     //delay_ms(500);
 }  
}
#define _LCD_

#define LCD_RS PIN_D1                        
#define LCD_RW PIN_D2
#define LCD_EN PIN_D0
#define LCD_D4 PIN_D4                 
#define LCD_D5 PIN_D5
#define LCD_D6 PIN_D6
#define LCD_D7 PIN_D7 

#endif
#ifndef __KEYPAD_H
#define __KEYPAD_H


// Define pins
#define RowA      PIN_B0
#define RowB      PIN_B1
#define RowC      PIN_B2
#define RowD      PIN_B3
#define C1        PIN_B4
#define C2        PIN_B5
#define C3        PIN_B6
#define C4        PIN_B7

#define Keypad_PORT         PORTB
#define Keypad_PORT_Dir      TRISB

// Function declarations
void InitKeypad(void);
char GetKey(void);

#endif
/**
   @uthor https://nvtienanh.info
   @brief LCD functions
*/
 void LCD_Enable(void)
{
 output_high(LCD_EN);
 delay_us(3);
 output_low(LCD_EN);
 delay_us(50); 
}

//Ham Gui 4 Bit Du Lieu Ra LCD
 void LCD_Send4Bit( unsigned char Data )
{
 output_bit(LCD_D4,Data&0x01);
 output_bit(LCD_D5,(Data>>1)&1);
 output_bit(LCD_D6,(Data>>2)&1);
 output_bit(LCD_D7,(Data>>3)&1);
}

// Ham Gui 1 Lenh Cho LCD
 void LCD_SendCommand (unsigned char command )
{
LCD_Send4Bit  ( command >>4 );/* Gui 4 bit cao */
LCD_Enable () ;
LCD_Send4Bit  ( command  );   /* Gui 4 bit thap*/
LCD_Enable () ;
}

void LCD_Init (void)
{

output_low(LCD_RS);
output_low(LCD_RW);
delay_ms(20);


LCD_Send4Bit(0x03);
LCD_Enable();
delay_ms(10);

LCD_Send4Bit(0x03);
LCD_Enable();
delay_ms(10);

LCD_Send4Bit(0x03);
LCD_Enable();
delay_ms(10);

LCD_Send4Bit(0x02);
LCD_Enable();
delay_ms(10);


LCD_SendCommand( 0x28 );      // giao thuc 4 bit, hien thi 2 hang, ki tu 5x8   
                                 //Function Set: 8-bit, 1 Line, 5x7 Dots   0x30
                                 //Function Set: 8-bit, 2 Line, 5x7 Dots   0x38
                                 //Function Set: 4-bit, 1 Line, 5x7 Dots   0x20
                                 //Function Set: 4-bit, 2 Line, 5x7 Dots   0x28

LCD_SendCommand( 0x0C);    //Display on Cursor on: 0x0E   0x0F 
                               //Display on Cursor off: 0x0C
                               //Display on Cursor blinking: 0x0F
LCD_SendCommand( 0x06 );   // tang ID, khong dich khung hinh         Entry Mode

LCD_SendCommand( 0x01 );   //  Clear Display  (also clear DDRAM content)

}
 
void LCD_PutChar ( unsigned char Data )
{
 output_high(LCD_RS);
 LCD_SendCommand( Data );
 output_low(LCD_RS);
}

void LCD_Puts (char *s)
{
   while (*s)
   {
      LCD_PutChar(*s);
      s++;
   }
}
void LCD_Clear()
{
  LCD_SendCommand(0x01);  
  delay_ms(10);
}
void LCD_Gotoxy(unsigned char row, unsigned char col)
{
  unsigned char address;
  if(!row)
  address = (0x80 + col);
  else
  address = (0xC0 + col);
  delay_us(500);
  LCD_SendCommand(address);
  delay_us(50);
}
#include "Keypad.h"

// Function name: InitKeypad
void InitKeypad(void)
{
   output_b(0x00);   // Set Keypad port pin values zero
   set_tris_b(0xF0);   // Last 4 pins input, First 4 pins output
   port_b_pullups (0x7F);// Enable weak internal pull up on input pins
}



// Function name: READ_SWITCHES
// Scan all the keypad keys to detect any pressed key.
char READ_SWITCHES(void)   
{   
   output_low(RowA); output_high(RowB); output_high(RowC); output_high(RowD);    //Test Row A

   if (input_state(C1) == 0) { delay_ms(250); while (input_state(C1)==0); return '7'; }
   if (input_state(C2) == 0) { delay_ms(250); while (input_state(C2)==0); return '8'; }
   if (input_state(C3) == 0) { delay_ms(250); while (input_state(C3)==0); return '9'; }
   if (input_state(C4) == 0) { delay_ms(250); while (input_state(C4)==0); return '/'; }

   //RowA = 1; RowB = 0; RowC = 1; RowD = 1;    //Test Row B
   output_high(RowA); output_low(RowB); output_high(RowC); output_high(RowD);

   if (input_state(C1) == 0) { delay_ms(250); while (input_state(C1)==0); return '4'; }
   if (input_state(C2) == 0) { delay_ms(250); while (input_state(C2)==0); return '5'; }
   if (input_state(C3) == 0) { delay_ms(250); while (input_state(C3)==0); return '6'; }
   if (input_state(C4) == 0) { delay_ms(250); while (input_state(C4)==0); return 'x'; }
   
  // RowA = 1; RowB = 1; RowC = 0; RowD = 1;    //Test Row C
   output_high(RowA); output_high(RowB); output_low(RowC); output_high(RowD);

   if (input_state(C1) == 0) { delay_ms(250); while (input_state(C1)==0); return '1'; }
   if (input_state(C2) == 0) { delay_ms(250); while (input_state(C2)==0); return '2'; }
   if (input_state(C3) == 0) { delay_ms(250); while (input_state(C3)==0); return '3'; }
   if (input_state(C4) == 0) { delay_ms(250); while (input_state(C4)==0); return '-'; }
   
   //RowA = 1; RowB = 1; RowC = 1; RowD = 0;    //Test Row D
   output_high(RowA); output_high(RowB); output_high(RowC); output_low(RowD);

   if (input_state(C1) == 0) { delay_ms(250); while (input_state(C1)==0); return 'C'; }
   if (input_state(C2) == 0) { delay_ms(250); while (input_state(C2)==0); return '0'; }
   if (input_state(C3) == 0) { delay_ms(250); while (input_state(C3)==0); return '='; }
   if (input_state(C4) == 0) { delay_ms(250); while (input_state(C4)==0); return '+'; }

   return 'n';              // Means no key has been pressed
}


// Function name: GetKey
// Read pressed key value from keypad and return its value
char GetKey(void)               // Get key from user
{
   char key = 'n';              // Assume no key pressed

   while(key=='n')              // Wait untill a key is pressed
      key = READ_SWITCHES();   // Scan the keys again and again

   return key;                  //when key pressed then return its value
}

Project Proteus 8.4

Video demo

Share

You may also like...

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *