PIC14: Difficulty with interrupts or PORTA?

Mac Cody
2006-11-02
2013-03-12
  • Mac Cody

    Mac Cody - 2006-11-02

    I'm having confusion with the following SDCC version: 
    SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.6.1 #4415 (Oct 20 2006) (UNIX)

    The first program, InterruptFlasher1.c compiles and works properly (the LED flashes). The second program, InterruptFlasher2.c compiles correctly but does not flash the LED. By running the assembled code on GPSIM, it does appear to toggle the Port A pin. What am I missing? Is this an SDCC bug or a "cockpit error"? Thanks!

    ----------- Begin source for InterruptFlasher1.c ---
    #define __16f628
    #include "pic/pic16f628.h"

    // Set the __CONFIG word:
    typedef unsigned int word;
    word at 0x2007 __CONFIG = 0x3D90;

    void Intr(void) interrupt 0 {
      // Clear the Timer 0 interrupt.
      T0IF = 0;
      // Toggle the state of the LSB of the port bits
      PORTA++;
    }

    void main(void) {
      // All Port A latch outputs are enabled.
      TRISA = 0x00;
      // Disable comparators.
      CMCON = 0x07;
      // Clear to enable timer mode.
      T0CS = 0;
      // Clear to assign prescaler to Timer 0.
      PSA = 0;
      // Set up prescaler to 1:256.
      PS2 = 1;
      PS1 = 1;
      PS0 = 1;
      // Clear interrupt flag bits.
      INTCON = 0;
      // Enable all interrupts.
      GIE = 1;
      // Set Timer 0 to 0.
      T0IE = 1;
      // Enable peripheral interrupts.
      TMR0 = 0;
      // Loop forever.
      while(1) {
      }
    }
    ----------- End source for InterruptFlasher2.c ---
    ----------- Compiler command line for InterruptFlasher2.c
    sdcc -mpic14 -p16f628 -V --debug -I/home/mcody/distributions/PIC/tests/ -c InterruptFlasher1.c
    sdcc -mpic14 -p16f628 -V --debug -Wl-c -o InterruptFlasher1.hex InterruptFlasher1.o

    ---------- Begin source for InterruptFlasher1.c ---
    #define __16f628
    #include "pic/pic16f628.h"

    // Set the __CONFIG word:
    typedef unsigned int word;
    word at 0x2007 __CONFIG = 0x3D90;

    unsigned char port_bits;

    void Intr(void) interrupt 0 {
      // Clear the Timer 0 interrupt.
      T0IF = 0;
      // Toggle the state of the LSB of the port bits
      port_bits = port_bits ^ 0x01;
    }

    void main(void) {
      port_bits = 0;
      // All Port A latch outputs are enabled.
      TRISA = 0x00;
      // Disable comparators.
      CMCON = 0x07;
      // Clear to enable timer mode.
      T0CS = 0;
      // Clear to assign prescaler to Timer 0.
      PSA = 0;
      // Set up prescaler to 1:256.
      PS2 = 1;
      PS1 = 1;
      PS0 = 1;
      // Clear interrupt flag bits.
      INTCON = 0;
      // Enable all interrupts.
      GIE = 1;
      // Set Timer 0 to 0.
      T0IE = 1;
      // Enable peripheral interrupts.
      TMR0 = 0;
      // Loop forever.
      while(1) {
        // The next line is done to overcome code simplification that
        // occurs otherwise PORTA = port_bits => clrf _PORTA
        port_bits = port_bits;
        // Write current value of port bits out to Port A.
        PORTA = port_bits;
      }
    }
    ----------- End source for InterruptFlasher2.c ---

    ----------- Compiler command line for InterruptFlasher2.c
    sdcc -mpic14 -p16f628 -V --debug -I/home/mcody/distributions/PIC/tests/ -c InterruptFlasher2.c
    sdcc -mpic14 -p16f628 -V --debug -Wl-c -o InterruptFlasher2.hex InterruptFlasher2.o

     
    • Steven Borley

      Steven Borley - 2006-11-02

      In the second example port_bits needs to be declared volatile.

           volatile unsigned char port_bits;

      Otherwise the while loop gets optimised away.

      Steven

       
    • Mac Cody

      Mac Cody - 2006-11-02

      I will try declaring port_bits as volatile, but I wonder if this will fix the problem.  As I stated above, when running the code for the second program under GPSIM, the Port A bit does toggle.  The code just doesn't toggle the pin on the PIC16F628 device.  I know that there is nothing wrong with the PIC device, as I can load in the code for the first program and the LED does flash.

      I looked at the assembly output for the second program.  The while loop is not "optimized away".  That is why I made the comment in the second program listing about adding the line "port_bits = port_bits;".  If that line is left out, the following line, "PORTA = port_bits;", is compiled to the assembly code "clrf _PORTA".  I think this happens because of the line "port_bits = 0;" on the first line of the main routine and the "copy propagation" optimization of SDCC.  In fact, if any while loop should be "optimized away", it would be the while loop in the first program.  I looked at the assembly for the first program and the while loop is in place.  It is just a "goto" that loops back on itself.

      I will still try declaring port_bits as volatile and see what happens.  Maybe I'll be surprised.

      Mac

       
    • Steven Borley

      Steven Borley - 2006-11-03

      Sorry, just seemed likely, but you do seem to have covered that point and I didn't read your post well enough.

      Couple more thoughts...

      If the PORTA bits are being toggled in GSIM, did you look at the TRISA bits. Are they correct?  I cannot see why they would not be correct, but that's all I can think of.

      In the second version, can the LED be illuminated in the initialisation part of main, before the interrupt fires.  Just thinking that this might give you some way to find when the LED stops working.

      Steven

       
    • Mac Cody

      Mac Cody - 2006-11-03

      The answer is: COCKPIT ERROR!  I had the LED wired on pin 18 (RA1) of the 16F628.  It should have been on pin 17 (RA0).  The first program increments the Port A register so all of the bits (RA0 - RA4, that is) are eventually toggled on the output lines.  The second program only toggles RA0 (pin 17).  I feel like a dope! <blush> Thanks for the help anyway!  It allowed me to focus on other possible causes of the problem.

      Mac

       
    • Steven Borley

      Steven Borley - 2006-11-03

      Oops. I know that feeling.
      Good luck, Mac, for the rest of the project.
      Steven

       

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks