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.

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.

Latest threads

New Articles From Microcontroller Tips

Back
Top