PIC Programming help

Thread Starter

Yoopercamp23

Joined Jan 30, 2014
7
Hello,
I am learning basic PIC programming and am trying to control a seven segment display to turn on segements A,B,C,D,E,F in that order to make the display look like it rotating. The LED's turn on in 100ms increments and keep looping.
I am using a PIC16F1823 controller and a LTS4801JR common anode display.
I am also using a push button to control the direction of the rotation.
I am using MPLAB IDE to program the controller and have it hooked up according to the datasheet.

To get the 100ms timing, I am using the internal frequency set to 500kHz, and have prescaled it to 256. I loaded the prescaler to 207 to get the 100ms timing.

To change to led's, I used a case/switch for each segment.
When I build and then program, there are no errors but segment A-F are all on and unchanging. I believe the controller is locked up due to an error. Can someone look over my code and point me in the right direction. Thanks!


Rich (BB code):
#include <htc.h>
__CONFIG(0x09A4); // Set Config1 register
__CONFIG(0x1CFF); // Set Config2 register
 void main (void)

{
  
    
    int flag;    //100ms flag to count
    int Pb;    //Pushbutton input
    PORTA=0x00;    //Clear Port A
    LATA=0x00;    //Clear Latch A
    //BANKSEL PORTC;
    PORTC=0x00; //Clear Port C
    LATC=0x00;    //Clear Latch C
    ANSELA=0x00; //all I/O
    ANSELC=0x00; //all I/O
    TRISA=0x08; //RA 3 as input.    RA0,RA1,RA2,RA4,RA5 as Outputs
    TRISC=0x00; //RC ports outputs
    OSCCON=0x38; //set internal oscillator to 500kHz
    OPTION_REG=0xC7; //set prescalar to 1:256
    TMR0=0xCF; //load Timer0 to 207 for 100ms timing
    T0IF=0; //clear flag
    flag = 0;

    

    while(1)
        {
            while (T0IF==0);   //wait for flag to change
        
            flag++;        //Increase flag by one
            T0IF=0;        //Reset Interrupt flag to 0
        
            
            if ((RA3 == 1) && (flag==!0)) //look for high on push button and flag not 0
            {
            switch(flag)
                {
                    case '1':
                        LATA0=0; //turn on segment A
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;
                    
                    case '2':
                        LATA0=1;
                        LATA1=0; //turn on segment B
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '3':
                        LATA0=1;
                        LATA1=1;
                        LATA2=0;  //turn on segment C
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '4':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=0;  //turn on segment D
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '5':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=0; //turn on segment E
                        LATC0=1;
                    break;

                    case '6':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=0;  //turn on segment F

                    break;
                        
                }
                if (flag==7)
                    {
                        T0IF=0;    //set flag back to 0
                        flag = 0; //reset flag to 0
                    
                        TMR0=0xCF; //load Timer0 to 207CF
                    }
            }
        
            
                        
        if ((RA3 == 0) && (flag==!0))  //if pushbutton is pressed, active low
            {
            switch(flag)
                {
                    case '1':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=0; //turn on segment F
                    break;

                    case '2':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=0; //turn on segment E
                        LATC0=1;
                    break;

                    case '3':
                        LATA0=1;
                        LATA1=1;
                        LATA2=1;
                        LATA4=0; //turn on segment D
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '4':
                        LATA0=1;
                        LATA1=1;
                        LATA2=0;  //turn on segment C
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '5':
                        LATA0=1;
                        LATA1=0;  //turn on segment B
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;

                    case '6':
                        LATA0=0;  //turn on segment A
                        LATA1=1;
                        LATA2=1;
                        LATA4=1;
                        LATA5=1;
                        LATC0=1;
                    break;
                        
                }
                if (flag==7)
                    {
                        T0IF=0;    //set flag back to 0
                        flag = 0; //reset flag to 0
                        TMR0=0xCF; //load Timer0 to 201CF
                    }
            }
    }    
                                    

    
}
 
Last edited by a moderator:

Thread Starter

Yoopercamp23

Joined Jan 30, 2014
7
I just ran my PICkit3 as a debugger and animated the program. It seems to have the correct 100ms cycle but is not increasing my int flag and going into the switch.
 

tshuck

Joined Oct 18, 2012
3,534
You should do the timing in an interrupt, but that isn't necessary at the moment.

You may need to declare the flag variable as a volatile int to prevent it from being optimized, though I would find it hard to believe it wood get optimized out, given its context.

Is it reaching the line that increments it?
 

spinnaker

Joined Oct 29, 2009
7,830
I just ran my PICkit3 as a debugger and animated the program. It seems to have the correct 100ms cycle but is not increasing my int flag and going into the switch.

Do not animate. That will tell you next to nothing. Set a breakpoint at flag++ ,
run your code and see if your code gets to that line. Step through the code and see what it does.
 

jjw

Joined Dec 24, 2013
823
I think the timing is wrong: 500kHz/256/(256—207)~ 40Hz-> 25ms
It is too fast to see the segments separately.
The timer0 should be loaded with 61 decimal for 100ms timing.
 

Thread Starter

Yoopercamp23

Joined Jan 30, 2014
7
I noticed my code is not switching flag. So yeah i dont believe it is being incremented correctly. The timing is correct, I calculated it manually and also used a calculator online to verify what to preload TMR0 with and it shows 207. I am looking through it again and will set a breakpoint to see if flag increments correctly. Thanks!
 

MrChips

Joined Oct 2, 2009
30,806
When you don't have access to an oscilloscope to see fast signals changing it is a good idea to slow things down so that the eye can see things working.
 

Markd77

Joined Sep 7, 2009
2,806
I don't really understand C but it looks at first glance that the test for flag == 7 might be in the wrong place, maybe flag can get higher than 7 which might cause problems.
 

jjw

Joined Dec 24, 2013
823
Shouldn't this: (flag==!0)) be flag !=0
In the first you are comparing flag with 0b11111111 and flag never gets there
 

t06afre

Joined May 11, 2009
5,934
As mentioned breakpoints is important. But then debugging adding watches is also on the same footing. The (flag==!0) I am quite sure will only look at the LSB the rest of the bits in flag will be cleared. So the expression may be true then the LSB in flag is 1. if ((RA3 == 0) && (flag==!0)) could probably be written as if ((RA3 == 0) && (flagg))
 

jjw

Joined Dec 24, 2013
823
As mentioned breakpoints is important. But then debugging adding watches is also on the same footing. The (flag==!0) I am quite sure will only look at the LSB the rest of the bits in flag will be cleared. So the expression may be true then the LSB in flag is 1. if ((RA3 == 0) && (flag==!0)) could probably be written as if ((RA3 == 0) && (flagg))
Ok, if !0 is 1 then he is comparing flag to 1 when he intends to test that flag is not zero.
if ((RA3 == 0) && (flag)) is the right way test that flag is not zero.
Anyway if ( x==!0 ) is not the same as if (x!=0 )
 

spinnaker

Joined Oct 29, 2009
7,830
Ok, if !0 is 1 then he is comparing flag to 1 when he intends to test that flag is not zero.
if ((RA3 == 0) && (flag)) is the right way test that flag is not zero.
Anyway if ( x==!0 ) is not the same as if (x!=0 )

OP is not comparing to 1 OP is comparing to not zero. It is a really confusing way to do it. You mentioned it above flag != 0. FAR more understandable.
 

jjw

Joined Dec 24, 2013
823
OP is not comparing to 1 OP is comparing to not zero. It is a really confusing way to do it. You mentioned it above flag != 0. FAR more understandable.
I was not clear enough.
It is not only a confusing way, it is a wrong way to detect if flag is not zero.
! is a logical operator which gives a value, either 0 or 1,
so statement ( flag==!0 ) compares flag with 1
I made a short test program in C:
Rich (BB code):
char i;
main()
{ 	/* wrong */
	printf(" wrong way");
	for ( i=0;i<5;i++)
		if ( i==!0)
			printf("\n not zero %d\n",i);
			
	/* right */
	printf("\n right way");
	for ( i=0;i<5;i++)
		if ( i!=0)
			printf("\n not zero %d",i);
}
It outputs:

C:\Program Files\tcc\tcc>tcc -run notzero.c

wrong way
not zero 1

right way
not zero 1
not zero 2
not zero 3
not zero 4

C:\Program Files\tcc\tcc>

OP:s program visits ( if it is working otherwise ) the select-case block only when flag is 1
 
Last edited:
Top