Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F886 with a Matrix Switch

Status
Not open for further replies.

beeson76

New Member
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.
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.
 

Attachments

  • LCD-Microchip Schematic No Crystal Matrix Switch.pdf
    24.9 KB · Views: 231
Here is what I have programmed so far. I am simplifying it by using the IF statement. For right not I am keeping away from macros simply for it easier to follow for me.

Code:
#include <htc.h>
#include "lcd.h"

#define	COL_1	RB0
#define COL_2	RB1
#define	COL_3	RB7
#define	ROW_1	RB3
#define ROW_2	RB4
#define	ROW_3	RB5
#define	ROW_4	RB6
#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

__CONFIG (MCLREN & INTIO & WDTDIS & PWRTEN & BORDIS & LVPDIS & UNPROTECT);

main()
{
	
PORTA = 0x00;										//PORTA is cleared and set low

PORTB = 0x83; 					//(0b10000011 binary) (0x83 hex)--COLUMNS set to HIGH  
													//PORTB7:B0 is set to high,low,low,low,low,low,high,high
													//ROWS set to LOW
PORTC = 0x00;										//PORTC is cleared and set low
TRISA = 0x00;										//Set PORTA to outputs

TRISB = 0x7C;										//(0b01111100 binary) (0x7C hex)--COLUMNS set to INPUT
													//PORTB7:B0 is set to output,input,input,input,input,input,output,output,

TRISC = 0x00;										//Set PORTC to outputs
RBPU = 0;											//PORTB Weak Internal 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 LCD.C file and LCD.h

while (1)
	{
		COL_1 = 0;									//COLUMN 1 is set LOW
		if (ROW_1 = 0)								//If ROW 1 is low...
			{										//...
				lcd_clear();						//...
				lcd_goto(0);						//...
				lcd_puts("Switch 1");				//Display "Switch 1"
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(100);
			}
		if (ROW_2 = 0)								//if ROW 2 is low...
			{										//...
				lcd_clear();						//...		
				lcd_goto(0);						//...
				lcd_puts("Switch 4");				//Display "Switch 4"
				__delay_ms(150);			
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(100);
			}
		if (ROW_3 = 0)								//If ROW 3 is LOW
			{										//...
				lcd_clear();						//...
				lcd_goto(0);						//...
				lcd_puts("Switch 7");				//Display "Switch 7"
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(100);
			}
		if (ROW_4 = 0)								//if ROW 4 is LOW
			{										//...
				lcd_clear();						//...
				lcd_goto(0);						//...
				lcd_puts("Switch 10");				//Display "Switch 10"
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(150);
				__delay_ms(100);
			}
	}
}
 
Status
Not open for further replies.

Latest threads

Back
Top