I have a PIC16F886 and I want to control a 3 Column 4 Row Matrix Switch. I am completely new to electronics, so this is a learning experience. My biggest problem so far was getting this PIC correctly attached to an LCD display. But I have gotten the LCD initialized and it displays text by way of a simple program "Hello World", so I know the hardware is working correctly but now I think it is the programming for the Matrix Switch that is giving me problems now. I am using PORTB for my Matrix Switch. The schematic is included. I would like to use the internal pullups on PORTB. Also included is the main.c program for the switch.
Can someone please critique my program and tell me if something is wrong. It doesn't work.
Whenever I hit a button, that buttons name should be displayed on the LCD screen.
Can someone please critique my program and tell me if something is wrong. It doesn't work.
Code:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//This program controls a Matrix Switch. The Switch consists of 3 columns and 4 rows.
//Whenever a button is pushed, that button is displayed on an LCD Display.
//PIC16F886 Microcontroller from Microchip is being used.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <htc.h>
#include "lcd.h"
#define KEY_PORT PORTB //Defining PORTB as KEY_PORT
#define KEY_SET(bits) KEY_PORT |= (bits) //Defining KEY_SET as KEY_PORT = KEY_PORT | (bits)
#define KEY_CLR KEY_PORT &=~ (bits) //Defining Key_CLR as KEY_PORT = KEY_PORT &~ (bits)
#define KEY_FLP(bits) KEY_PORT ^= (bits) //Defining KEY_FLP as KEY_PORT = KEY_PORT ^ (bits)
#define KEY_IN(bits) TRISB |= (bits) //Defining KEY_IN as TRISB = TRISB | (bits)
#define KEY_OUT(bits) TRISB &=~ (bits) //Defining KEY_OUT as TRISB = TRISB &~ (bits)
#define KEY_COL 0b10000011 //Defining KEY_COL as high,low,low,low,low,low,high,high
#define KEY_ROW 0b01111000 //Defining KYE_ROW as low,high,high,high,high,low,low,low
#define DelayS(T) {unsigned char i; for (i = 0; i < T * 10; i++) __delay_ms(100);} //Delay Macro
#define _XTAL_FREQ 4000000 //Needs to be set for __delay_ms
/////CONFIGURATION FUSE//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Master Clear Reset enabled & Internal RC No Clock & Watchdog Timer Disable & Power Up Timer On & Brown Out Reset Disabled &
// Low Voltage Porgramming Disabled & Code Unprotect
//
__CONFIG (MCLREN & INTIO & WDTDIS & PWRTEN & BORDIS & LVPDIS & UNPROTECT);
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char key_read(unsigned char in_bits, unsigned char out_bits)
{
KEY_IN(in_bits);
KEY_SET(out_bits);
KEY_OUT(out_bits);
return KEY_PORT & in_bits;
}
/////key_detect Function/////////////////////////////////////////////////////////////////////////////////////////////////////////
//This function calls key_read function--which in turn........ It creates 2 local variables (tmp1 and tmp2) and stores results of scan of KEY_ROW
//and KEY_COL
unsigned char key_detect(void)
{
unsigned char tmp1, tmp2;
tmp2 = key_read(KEY_ROW, KEY_COL);
tmp1 = key_read(KEY_COL, KEY_ROW);
return tmp1 | tmp2;
} //
main ()
{
PORTA = 0x00; //PORTA is cleared and set low
PORTB = 0xFF; //PORTB is cleared and set high
PORTC = 0x00; //PORTA is cleared and set low
TRISA = 0x00; //Set PORTA to outputs
TRISB = 0xFF; //Set PORTB to inputs
TRISC = 0x00; //Set PORTC to outputs
//RBPU = 0; //Internal PORTB Pullups enabled
ANSEL = 0; //Initialize A/D Ports off
ANSELH = 0; //Initialize ........
CM1CON0 = 0; //Initialize Comparator 1 off
CM2CON0 = 0; //Initialize Comparator 2 off
OPTION = 0b01010101; //OPTION REG
//xbxxxxx101 1:64
//xbxxxx0xxx Prescaler set to Timer0
//xbxxx1xxxx (T0SE) set to Increment on high-to-low transition on T0CKI pin
//xbxx0xxxxx (T0CS) Internal instruction cycle clock
//xbx1xxxxxx (INTEDG) Interrupt on rising edge of INT pin
//xb0xxxxxxx (RBPU) PORTB pull-ups are enabled by individual PORT latch values
lcd_init(); //LCD Display is Initialized...See if LCD.C file
/////IGNORE THIS -- ONLY A TEST//////////////////////////////////////////////////////////////////////////////////////////////////
//Only a test to see if LCD is Initialized and Display Text
//while (1 == 1)
//{
//
// lcd_clear();
// lcd_goto(0);
// lcd_puts("Hello World");
// __delay_ms(150);
// lcd_goto(40);
// lcd_puts("LCD Iniatlized");
// __delay_ms(150);
//}
//} //Everything After this would be commented out
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
lcd_clear();
lcd_goto(0);
lcd_puts("PDDC Tester");
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
__delay_ms(150);
char key; //Creating a local Variable called "key" to hold value of key when pressed
while (key_detect() == 1) //Loops When Key is Pressed
continue;
{
key = key_detect(); //Referring to key_detect() function. Returns key pressed.
switch (key) //Switch Statement for "key"
{
case 0b00100001: //Column 1 Row 4--Switch 12
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 1");
//DelayS(1);
lcd_clear();
break;
case 0b01000001: //Column 1 Row 3--Switch 11
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 2");
//DelayS(1);
lcd_clear();
break;
case 0b00010001: //Column 1 Row 2--Switch 10
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 3");
//DelayS(1);
lcd_clear();
break;
case 0b00001001: //Column 1 Row 1--Switch 9
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 4");
//DelayS(1);
lcd_clear();
break;
case 0b00100010: //Column 2 Row 4--Switch 8
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 5");
//DelayS(1);
lcd_clear();
break;
case 0b01000010: //Column 2 Row 3--Switch 7
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 6");
//DelayS(1);
lcd_clear();
break;
case 0b00010010: //Column 2 Row 2--Switch 6
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 7");
//DelayS(1);
lcd_clear();
break;
case 0b00001010: //Column 2 Row 1--Switch 5
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 8");
//DelayS(1);
lcd_clear();
break;
case 0b10100000: //Column 3 Row 4--Switch 4
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 9");
//DelayS(1);
lcd_clear();
break;
case 0b11000000: //Column 3 Row 3--Switch 3
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 10");
//DelayS(1);
lcd_clear();
break;
case 0b10010000: //Column 3 Row 2--Switch 2
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 11");
//DelayS(1);
lcd_clear();
break;
case 0b10001000: //Column 3 Row 1--Switch 1
lcd_clear();
lcd_goto(0);
lcd_puts("Switch 12");
//DelayS(1);
lcd_clear();
break;
}
}
}
Whenever I hit a button, that buttons name should be displayed on the LCD screen.