PIC16F887 on/off help

Status
Not open for further replies.

LoyC

New Member
Hey guys, i've been working on my project which requires me to turn on/off four switches. Below is my code for doing it.

Code:
#include <pic.h>
#include <htc.h>

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS);

void main(void)
{	
	unsigned int A,B,ch=0,d;;	//variable A & B
	unsigned char segment[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
	ANSEL = 0x00;			//select all PORTs digital i/o
	ANSELH = 0x00;
	TRISA = 0xFF;			//select PORTA as input
	TRISB = 0x00;			//select PORTB as output
	TRISC= 0x00;			//PORTC SET AS OUTPUT
	A=0;					//pre-define A=0
	B=0;					//pre-define B=0
	PORTB=0x00;
	PORTC= segment[ch];					
	PORTA= 0x00;
	
	while(1)
	{
		//on/off funcion		
		if(PORTA==0x04)
		{	
			
			if(A==0)
			{	B=1;
				A=1;
			}
			else
			{	B=2;
				A=0;
			}
	
		}
		if(B==1)
			{	RB4=1;
				B=0;
			for(d=0;d<20000;d++){}
			}
	
		if(B==2)
			{	RB4=0;
				B=0;
			for(d=0;d<20000;d++){}	
			}
	
		


			if(PORTA==0x08)
		{	
			
			if(A==0)
			{	B=1;
				A=1;
			}
			else
			{	B=2;
				A=0;
			}	

		}
		if(B==1)
			{	RB5=1;
				B=0;
			for(d=0;d<20000;d++){}
			}
	
		if(B==2)
			{	RB5=0;
				B=0;
			for(d=0;d<20000;d++){}
			}
	



			if(PORTA==0x10)
		{	
			
			if(A==0)
			{	B=1;
				A=1;
			}
			else
			{	B=2;
				A=0;
			}

		}
		if(B==1)
			{	RB6=1;
				B=0;
			for(d=0;d<20000;d++){}
			}
	
		if(B==2)
			{	RB6=0;
				B=0;
			for(d=0;d<20000;d++){}	
			}

PORTA are all connected to pushbutton switch.When i press the switch of RA3, RB 4 will be turned on(giving a high state), another push will turn off RB 4(low state)
When i press the switch of RA4, RB 5 will be turned on(giving a high state), another push will turn off RB 5(low state). The same goes for the other two pins.

Now here's my problem, my i push push RA3, RB4 will goes into a high, then when i push RA4, RB 5 will be high as well. But to turn off RB4, i need to push the switch of RA3 twice.

Does anyone has any idea how to solve this. Many thanks.
 
I can't follow what your code is doing. Probably because I have no idea what you intend A & B to be.

The way I would do this is to detect rising edges on port A and then act on those.
Code:
#include <pic.h>
#include <htc.h>
 
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS);
 
void main(void)
{	
    unsigned char Previous,Keys,Edges;
    unsigned char segment[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
    ANSEL = 0x00;            //select all PORTs digital i/o
    ANSELH = 0x00;
    TRISA = 0xFF;            //select PORTA as input
    TRISB = 0x00;            //select PORTB as output
    TRISC= 0x00;            //PORTC SET AS OUTPUT
    PORTB=0x00;
    PORTA= 0x00;
    Previous=0;
    while(1){
        _delay(20000);      //debounce delay (assumed 4MHz Crystal)
        Keys=PORTA;         //read the port
        Edges=Keys^Previous;//Edges = keys that have changed
        Edges&=Keys;        //edges = key that went from 0 to 1.
        Previous=Keys;      //keep copy of new keys.
        if(Edges&0x08)      //RA3 Pressed?
            PORTB^=0x10;    //yes, so toggle RB4
        if(Edges&0x10)      //RA4 Pressed?
            PORTB^=0x20;    //yes, so toggle RB5

    }   
}

Mike.
 
This seems simple ... Make a FLAG variable to test against

Like:
Code:
#include <pic.h>
#include <htc.h>
 
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS);
 
unsigned char CurrentState = 0x00;
void main(void)
{
	unsigned int A,B,ch=0,d;;	//variable A & B
	unsigned char segment[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
	ANSEL = 0x00;			//select all PORTs digital i/o
	ANSELH = 0x00;
	TRISA = 0xFF;			//select PORTA as input
	TRISB = 0x00;			//select PORTB as output
	TRISC= 0x00;			//PORTC SET AS OUTPUT
	A=0;					//pre-define A=0
	B=0;					//pre-define B=0
	PORTB=0x00;
	PORTC= segment[ch];
	PORTA= 0x00;

	while(1)
	{
		//on/off funcion
		if(PORTA==0x04)
		{
                    if(CurrentState & 0x04)
                    {
                      RB4 = 0;
                      CurrentState &= ~(0x04);
                    }
                    else
                    {
                      RB4 = 1;
                      CurrentState |= 0x04;
                    }
                    for(d=0;d<20000;d++){}
		}
		if(PORTA==0x08)
		{
                    if(CurrentState & 0x08)
                    {
                      RB5 = 0;
                      CurrentState &= ~(0x08);
                    }
                    else
                    {
                      RB5 = 1;
                      CurrentState |= 0x08;
                    }
                    for(d=0;d<20000;d++){}
                }
		if(PORTA==0x10)
		{
                    if(CurrentState & 0x10)
                    {
                      RB6 = 0;
                      CurrentState &= ~(0x10);
                    }
                    else
                    {
                      RB6 = 1;
                      CurrentState |= 0x10;
                    }
                    for(d=0;d<20000;d++){}
                }
        }
}

EDIT: forgot to add your delay But fixed now
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…