PIC 16F690 Switch Press to Turn Leds On

Thread Starter

lmartinez

Joined Mar 8, 2009
224
Hello everyone,

I wrote the program shown below to be utilized with the PICkit 2 demo board. The intent of the written code is to light up the LEDs connected to RC0 and RC1 when the switch connected to RA3 is not pressed. However, when RA3 is pressed, RC0 and RC1 should go off. Once the switch is pressed twice then RC2 should turn on. Unfortunately, what I have described is not happening. All of the leds are on at all time. Please help!!!

/*
PIC16F690 Configuration
*/
__CONFIG (INTIO & WDTDIS & PWRTEN & MCLRDIS & BORDIS & UNPROTECT & IESODIS & FCMDIS ); //Internal clock, Watchdog off, MCLR off, Code Unprotected


main()
{
ANSEL = 0; // Intialize A/D ports off
CM1CON0 = 0; // Initialize Comparator 1 off
CM2CON0 = 0; // Initialize Comparator 2 off

PORTC = 0x00; //Clear PortC port
TRISC = 0x00; //All PortC I/O outputs
TRISA = 0xFF; //All PortA I/O inputs

unsigned char count = 0; // Initialize count equal to zero


while(1==1) //loop forever
{



if (RA3 == 1) // Test RA3 port
{

RC0 = 1; // If SW1 not pressed, turn on RC0 LED
RC1 = 1; //If SW1 not pressed, turn on RC01 LED
}

else if (count == 2 ) //Check count to be equal to two
{

RC2= 1; //Turn on RC2 when SW1 is pressed twice
}


else
{
count = count + 1; //Increment count by one
RC0 = 0; // If SW1 pressed, turn off RC1/DS2 LED
RC1 = 0;

}




} //End while
} //end main
 

mik3

Joined Feb 4, 2008
4,843
The correct way to connect the switch is:

Connect the 1K resistor between Vcc and RA3 and the switch between RA3 and ground.
 

AlexR

Joined Jan 16, 2008
732
First up you can change count back to a unsigned character. You don't really need to reserve 2 bytes of RAM just to count up to 2!

I think you will find that your problem is switch contact bounce which causes the count to exceed 2 the first time that the switch is pressed. The .pdf document that you cite has a good section on both hardware and software switch debouncing.

I don't know which C compiler you are using but most do have built-in delay routines that can be used in debouncing functions.
 

Thread Starter

lmartinez

Joined Mar 8, 2009
224
Thank you for your feedback. I believe as well that it has something to do with the bouncing of the switch or MPLAB software. To compile the c written code I am using HighTech C embedded with the MPLAB software.
 

AlexR

Joined Jan 16, 2008
732
One thought that just struck me is that while you are looking for a switch press you are not looking for its release. This means that you can cycle through your loop many times while the switch is pressed and each cycle will count as a new press. What you need to do is put a loop to wait for the switch release in the area of code that increments the count. Of course both the switch press and switch release will need to be debounced.
 

Thread Starter

lmartinez

Joined Mar 8, 2009
224
I have made a few changes to the c code. RC0 and RC1 turn on and once the push button is pressed twice, the RC2 turns on. So far so good!. However, then after, the RC0 and RC1 should go off when the push button is pressed (count is greater than 2) , but it is not happening. They stay on regardless of the status of the push button. I hope some of you might shine some light on me to figure out what I missing. Thank you

#include <pic.h>


/*
PIC16F690 Configuration
*/
__CONFIG (INTIO & WDTDIS & PWRTEN & MCLRDIS & BORDIS & UNPROTECT & IESODIS & FCMDIS ); //Internal clock, Watchdog off, MCLR off, Code Unprotected

// Using Internal Clock of 8 Mhz
#define FOSC 8000000L

// Delay Function
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }

void _delay_ms(unsigned int ms)
{
unsigned char i;
do {
i = 4;
do {
_delay_us(164);
} while(--i);
} while(--ms);
}





main()
{
ANSEL = 0; // Intialize A/D ports off
CM1CON0 = 0; // Initialize Comparator 1 off
CM2CON0 = 0; // Initialize Comparator 2 off

PORTC = 0x00; //Clear PortC port
TRISC = 0x00; //All PortC I/O outputs
TRISA = 0xFF; //All PortA I/O inputs

unsigned char count = 0; // Initialize count equal to zero


while(1==1) //loop forever
{



if (RA3 == 1) // Test RA3 port
{

RC0 = 1; // If SW1 not pressed, turn on RC0 LED
RC1 = 1; //If SW1 not pressed, turn on RC01 LED
}

else if (count == 2 ) //Check count to be equal to two
{

RC2= 1; //Turn on RC2 when SW1 is pressed twice



}


else
{
count = count + 1; //Increment count by one
RC0 = 0; // If SW1 pressed, turn off RC0
RC1 = 0; // If SW1 pressed, turn off RC1


while (!RA3); // Hold here until switch is released
_delay_ms(10); // Delay 10 milliseconds and check again
while (!RA3); // For simple debounce of switch
}


} //End while
} //end main
 

Thread Starter

lmartinez

Joined Mar 8, 2009
224
After debugging the "C" program, I was able to figured it out. The correction was in the "if else" statement where I needed to include an increment for the "count". That modification and the debounce of the switch code added brough it to a success. Thank you all for your help
 

Thread Starter

lmartinez

Joined Mar 8, 2009
224
When RA3 is pressed and held down, does RC0 and RC1 go off? If this does not happen then it has nothing to do with any switch debounce!
Everything in the C-program works fine up to the point where "count" is equal to 2(RA3 pressed twice). As you may notice, in the "else if (count ==2)" statement there is no increment for "count" hence it will continue to stay withing that loop. As a result RCO and RC1, do not go off. Thank you
 
Top