C problem regarding PIC programming

Thread Starter

San_Dendlek

Joined Mar 24, 2010
11
Hi I have a problem I am doing a program which changes the patterns. The following is the program.

Rich (BB code):
#include <pic.h>
#include <htc.h>
#include "delay.c"	
#include "delay.h"	

#define XTAL_FREQ 4MHZ 

__CONFIG (WDTDIS & XT & UNPROTECT & PWRTEN);

void init(void)
{
// port directions: 1=input, 0=output
 PORTA=0xFF;	
 //PORTA=0x00;	
 PORTB=0x00;
 //PORTB=0xFF
 TRISA=0xFF;
 //TRISA=0x00;
 TRISB=0x00; 
 //TRISB=0xFF; 
}


void main(void)
{
	init();
	while (1)
	{
		int check = PORTA;

		if(check == 0b00001)
		{
			goto start;
		}
		
		if(check == 0b00010)
		{
			goto start1;
		}
		
		if(check == 0b00100)
		{
			goto start2;
		}

		if(check == 0b01000)
		{
			goto start3;
		}

	    start:
		do
		{
			PORTB=0b11000000;
			DelayMs(100);
			for(int x=0; x<5; x++)
			{
				PORTB=PORTB>>1;
				DelayMs(300);
			}
		
			PORTB=0b00000011;
			DelayMs(100);
			for (int y=0; y<5; y++)
			{
				PORTB=PORTB<<1;
				DelayMs(300);
			}
		}
		while(check!=0b00010 && check!=0b00100 && check!=0b01000);
	
		start1:
		do
		{
			PORTB=0b00000001;
			DelayMs(200);
			PORTB=0b00000011;
			DelayMs(200);
			PORTB=0b00000111;
			DelayMs(200);
			PORTB=0b00001111;
			DelayMs(200);
			PORTB=0b00011111;
			DelayMs(200);
			PORTB=0b00111111;
			DelayMs(200);
			PORTB=0b01111111;
			DelayMs(200);
			PORTB=0b11111111;
			DelayMs(200);
		}
		while(check!=0b00001 && check!=0b00100 && check!=0b01000);
	
		start2:
		do
		{
			PORTB=rand();
			DelayMs(300);
		}
		while(check!=0b00001 && check!=0b00010 && check!=0b01000);
	
	
		start3:
		do
		{
			for(int x=0; x<256; x++)
			{
				PORTB=x;
				DelayMs(30);
			}
		}
		while(check!=0b00001 && check!=0b00010 && check!=0b00100);
	}
}
Now can anyone help me I want the program that when I press a switch I want it to continue it`s respective pattern until another switch is pressed
and then does the pattern according to that switch. an so on and so forth

any help is appreciated thanks a lot the PIC I am programming in 16F84A
 

jase951

Joined Jan 19, 2009
1
Without looking at it all.

I gather all your switches are connected to PORTA and all lights/whatever are connected to PORTB.

First of all, would it not have been easier to use a switch() for checking which button is pressed and you can do away with all the conditional statements by putting the 'actions' within the switch().

Are these momentary switches? If so, store the button # that has been pressed in a variable and use this as a check for which button has been last pressed in the switch(), therefore unless this variable has been changed the action upon each forever while loop will be the same.

Jase
 

John P

Joined Oct 14, 2008
2,026
Take a good look at this loop:
Rich (BB code):
  do
  {
      // ...a bunch of stuff that doesn't involve changing "check"
  }
  while(check!=0b00001 && check!=0b00100 && check!=0b01000);
You seem to be waiting for something to change the variable "check" but nothing inside this loop will ever do so.

Switches are conventionally connected to Gnd, but yours must pull high when the switch is pressed, with pulldown resistors. Have you wired them that way?

And do you intend that if the program could ever leave the loop at start1, it would fall into the loop at start2, and when it left that, it would fall into start3?
 

Harrington

Joined Dec 19, 2009
85
Johns got a good point here the loop that you are writing never ever picks up on switch change It might be better if you handled your switches through hardware interrupts or a timer interrupt perhaps

I also notice that you are not using the

Rich (BB code):
switch(check)

{
 case 4: 

// code for this case 

 case 2:

// code for this case 

default : 

// code for this case 



}
Further down in this statement you can improve the way that you do this quite considerably

Rich (BB code):
start1: // Your code is left shifting one place and then "Bit-wise  OR " 1 to the port 
          // your doing this 8 times 

        // your example as follows
        do
        {
            PORTB=0b00000001;
            DelayMs(200);
            PORTB=0b00000011;
            DelayMs(200);
            // and so on and so on for each line 

            
        }

      /************ Far better way of achieving this below ********/

    unsigned char mask = 0x01 ;
    portb = 0x01 ;

    for (int i = 0 ; i < 7 ; i ++ )
    
    {
    
    portb = portb << 1 ; // left shift by one place 

   // bitwise OR Portb with mask after shifting you wont see this happen 
    portb = portb | mask ;
    delay_us(200);
    } // end for loop
Much better than all those lines of code
 
Top