PIC Programming help

Discussion in 'Homework Help' started by Yoopercamp23, Jan 30, 2014.

  1. Yoopercamp23

    Thread Starter New Member

    Jan 30, 2014
    7
    0
    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!


    Code ( (Unknown Language)):
    1.  
    2. #include <htc.h>
    3. __CONFIG(0x09A4); // Set Config1 register
    4. __CONFIG(0x1CFF); // Set Config2 register
    5.  void main (void)
    6.  
    7. {
    8.  
    9.    
    10.     int flag;    //100ms flag to count
    11.     int Pb;    //Pushbutton input
    12.     PORTA=0x00;    //Clear Port A
    13.     LATA=0x00;    //Clear Latch A
    14.     //BANKSEL PORTC;
    15.     PORTC=0x00; //Clear Port C
    16.     LATC=0x00;    //Clear Latch C
    17.     ANSELA=0x00; //all I/O
    18.     ANSELC=0x00; //all I/O
    19.     TRISA=0x08; //RA 3 as input.    RA0,RA1,RA2,RA4,RA5 as Outputs
    20.     TRISC=0x00; //RC ports outputs
    21.     OSCCON=0x38; //set internal oscillator to 500kHz
    22.     OPTION_REG=0xC7; //set prescalar to 1:256
    23.     TMR0=0xCF; //load Timer0 to 207 for 100ms timing
    24.     T0IF=0; //clear flag
    25.     flag = 0;
    26.  
    27.    
    28.  
    29.     while(1)
    30.         {
    31.             while (T0IF==0);   //wait for flag to change
    32.        
    33.             flag++;        //Increase flag by one
    34.             T0IF=0;        //Reset Interrupt flag to 0
    35.        
    36.            
    37.             if ((RA3 == 1) && (flag==!0)) //look for high on push button and flag not 0
    38.             {
    39.             switch(flag)
    40.                 {
    41.                     case '1':
    42.                         LATA0=0; //turn on segment A
    43.                         LATA1=1;
    44.                         LATA2=1;
    45.                         LATA4=1;
    46.                         LATA5=1;
    47.                         LATC0=1;
    48.                     break;
    49.                    
    50.                     case '2':
    51.                         LATA0=1;
    52.                         LATA1=0; //turn on segment B
    53.                         LATA2=1;
    54.                         LATA4=1;
    55.                         LATA5=1;
    56.                         LATC0=1;
    57.                     break;
    58.  
    59.                     case '3':
    60.                         LATA0=1;
    61.                         LATA1=1;
    62.                         LATA2=0;  //turn on segment C
    63.                         LATA4=1;
    64.                         LATA5=1;
    65.                         LATC0=1;
    66.                     break;
    67.  
    68.                     case '4':
    69.                         LATA0=1;
    70.                         LATA1=1;
    71.                         LATA2=1;
    72.                         LATA4=0;  //turn on segment D
    73.                         LATA5=1;
    74.                         LATC0=1;
    75.                     break;
    76.  
    77.                     case '5':
    78.                         LATA0=1;
    79.                         LATA1=1;
    80.                         LATA2=1;
    81.                         LATA4=1;
    82.                         LATA5=0; //turn on segment E
    83.                         LATC0=1;
    84.                     break;
    85.  
    86.                     case '6':
    87.                         LATA0=1;
    88.                         LATA1=1;
    89.                         LATA2=1;
    90.                         LATA4=1;
    91.                         LATA5=1;
    92.                         LATC0=0;  //turn on segment F
    93.  
    94.                     break;
    95.                        
    96.                 }
    97.                 if (flag==7)
    98.                     {
    99.                         T0IF=0;    //set flag back to 0
    100.                         flag = 0; //reset flag to 0
    101.                    
    102.                         TMR0=0xCF; //load Timer0 to 207CF
    103.                     }
    104.             }
    105.        
    106.            
    107.                        
    108.         if ((RA3 == 0) && (flag==!0))  //if pushbutton is pressed, active low
    109.             {
    110.             switch(flag)
    111.                 {
    112.                     case '1':
    113.                         LATA0=1;
    114.                         LATA1=1;
    115.                         LATA2=1;
    116.                         LATA4=1;
    117.                         LATA5=1;
    118.                         LATC0=0; //turn on segment F
    119.                     break;
    120.  
    121.                     case '2':
    122.                         LATA0=1;
    123.                         LATA1=1;
    124.                         LATA2=1;
    125.                         LATA4=1;
    126.                         LATA5=0; //turn on segment E
    127.                         LATC0=1;
    128.                     break;
    129.  
    130.                     case '3':
    131.                         LATA0=1;
    132.                         LATA1=1;
    133.                         LATA2=1;
    134.                         LATA4=0; //turn on segment D
    135.                         LATA5=1;
    136.                         LATC0=1;
    137.                     break;
    138.  
    139.                     case '4':
    140.                         LATA0=1;
    141.                         LATA1=1;
    142.                         LATA2=0;  //turn on segment C
    143.                         LATA4=1;
    144.                         LATA5=1;
    145.                         LATC0=1;
    146.                     break;
    147.  
    148.                     case '5':
    149.                         LATA0=1;
    150.                         LATA1=0;  //turn on segment B
    151.                         LATA2=1;
    152.                         LATA4=1;
    153.                         LATA5=1;
    154.                         LATC0=1;
    155.                     break;
    156.  
    157.                     case '6':
    158.                         LATA0=0;  //turn on segment A
    159.                         LATA1=1;
    160.                         LATA2=1;
    161.                         LATA4=1;
    162.                         LATA5=1;
    163.                         LATC0=1;
    164.                     break;
    165.                        
    166.                 }
    167.                 if (flag==7)
    168.                     {
    169.                         T0IF=0;    //set flag back to 0
    170.                         flag = 0; //reset flag to 0
    171.                         TMR0=0xCF; //load Timer0 to 201CF
    172.                     }
    173.             }
    174.     }    
    175.                                    
    176.  
    177.    
    178. }
    179.  
     
    Last edited by a moderator: Jan 31, 2014
  2. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Hmm.... have you done any debugging http://forum.allaboutcircuits.com/showthread.php?t=44852 first post
    As for the delays maybe it is more easy at this stage to use the __delay_ms() function. It is well described in the manual. Look in your docs folder in the compiler install directory. The latter directory is not the same as the MPLAB install folder
     
  3. Yoopercamp23

    Thread Starter New Member

    Jan 30, 2014
    7
    0
    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.
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Do you use series resistors on each LED segment?
     
  5. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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?
     
  6. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005

    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.
     
  7. jjw

    Member

    Dec 24, 2013
    173
    31
    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.
     
  8. Yoopercamp23

    Thread Starter New Member

    Jan 30, 2014
    7
    0
    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!
     
  9. jjw

    Member

    Dec 24, 2013
    173
    31
    You are right about the timing.
    I forgot that the timer input is Fosc/4 :)
     
  10. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    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.
     
  11. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    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.
     
  12. jjw

    Member

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

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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))
     
  14. jjw

    Member

    Dec 24, 2013
    173
    31
    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 )
     
  15. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005

    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.
     
  16. jjw

    Member

    Dec 24, 2013
    173
    31
    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:
    Code ( (Unknown Language)):
    1. char i;
    2. main()
    3. {   /* wrong */
    4.     printf(" wrong way");
    5.     for ( i=0;i<5;i++)
    6.         if ( i==!0)
    7.             printf("\n not zero %d\n",i);
    8.            
    9.     /* right */
    10.     printf("\n right way");
    11.     for ( i=0;i<5;i++)
    12.         if ( i!=0)
    13.             printf("\n not zero %d",i);
    14. }
    15.  
    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: Feb 2, 2014
Loading...