Problem with interrupt INT and TMR0 crashing pic

General discussion on mikroC.
Post Reply
Author
Message
vineman
Posts: 2
Joined: 22 Nov 2007 06:18
Location: Mt Canobolas, Australia

Problem with interrupt INT and TMR0 crashing pic

#1 Post by vineman » 23 Apr 2008 10:58

I've got a problem with a pic 16F877A on an easypic4 board. Setting the TMR0 clock source to internal causes the pic to lock up when INT (RB0) is triggered.

It's a prototype for a triac phase control circuit. The zero crossing signal triggers INT which starts a variable hold-off timer on TMR1. When TMR1 overflows, an output is switched on, triggering the triac, and TMR0 is enabled. When TMR0 overflows, the trigger output is switched off. ADC is for set point.

Setting OPTION_REG.T0CS = 0 causes the following code to crash when INT is triggered. The easypic board has buttons pulled up to VCC and port B pulled down.

Sorry the code is a bit long, I'm ex-pascal :)
Can anyone see what the problem is?

Code: Select all

unsigned int temp_set;

void interrupt() {
if (INTCON.TMR0IF) {     // This is the triac trigger turn off.  It does not get reset.
  TMR0   = 235;
  INTCON.T0IE = 0;         // mask the interrupt
  INTCON.T0IF = 1;         // clear the flag
//  PORTC.F0 = 1;            // switch the triac trigger off
  }
  else if (INTCON.INTF) {    // zero crossing - Start the triac trigger delay
    INTCON.INTF = 0;           // clear the INTCON INTF bit
    PORTC = ~PORTC;
//    PIR1.TMR1ON = 1;       // Start the delay timer
  }
  else if (PIR1.TMR1IF) {    // delay after zero crossing
    PIR1.TMR1IF = 0;         // reset the interrupt flags
    PIR1.TMR1IE = 1;         // unmask the interrupt
    PIR1.TMR1ON = 0;
    TMR1H = 0x80;            // reload the start count
    TMR1L = 0x00;
//    PORTC.F0 = 0;             // fire the triac
                // start the triac turnoff counter
  }

}

void setup_ports() {
  ADCON1 = 0x80;                 // Configure analog inputs, all inputs, internal Vref
  ADCON1.ADFM = 1 ;           // Set ADC output to right justified
  TRISA  = 0x1F;              // PORTA is input, AD for pot and thermistors

  TRISB  = 0x01;              // PORTB supports zero cross RB0 and lcd RB2-7
  PORTB  = 0xFE;
  OPTION_REG.INTEDG = 0;      // Pin RB0 is interrupt, triggered on falling edge for zero crossing
  INTCON.GIE = 1;             // Enable General Interrupt Enable
  INTCON.INTE = 1;            // Enable RB0 Extrenal Interrupt Edge

  TRISC  = 0;                 // RC0 is triac trigger, serial comms and spi/i2c, initially used for testing leds
//  PORTC  = 0x1;               // set the triac trigger high
  PORTC = 0;

  TRISD  = 0;                 // PORTD is output, leds at the moment
  PORTD  = 0xFF;

  INTCON.PEIE = 1;            // Enable peripheral interrupts
  T1CON = 0;
  T1CON.T1CKPS1 = 0;          // Timer 1 is timer with 1:2 prescale
  T1CON.T1CKPS0 = 1;
  T1CON.T1OSCEN = 0;          // Timer 1 oscillator is off
  T1CON.TMR1CS = 0;           // Timer 1 internal oscillator
  TMR1H = 0x80;               // Load an initial value for the timer
  TMR1L = 0x00;
  T1CON.TMR1ON = 0;           // Disable the trigger delay timer

  OPTION_REG.NOT_RBPU = 1;    // Disable weak pull-ups
  OPTION_REG.T0CS = 0;        // Internal Clock  - setting to zero fails, rc0 is high
  OPTION_REG.T0SE = 0;
  OPTION_REG.PSA = 1;         // prescaler assigned to watchdog, ie no prescale
  OPTION_REG.PS2 = 0;
  OPTION_REG.PS1 = 0;
  OPTION_REG.PS0 = 0;
  TMR0  = 235;                // Timer0 initial value
  INTCON.T0IE = 1;            // Enable TMRO interrupt



}

void main() {
  setup_ports();
  do {
    temp_set = ADC_Read(0);   // Get 10-bit results of AD conversion
    PORTD = temp_set;         // Send lower 8 bits to PORTD    PORTB = temp_res >> 2;    // Send 2 most significant bits to RB7, RB6
    PORTB.F7 = ~PORTB.F7;     // run indicator
    Delay_ms(500);
  } while(1);
}
:lol: :lol:

vineman
Posts: 2
Joined: 22 Nov 2007 06:18
Location: Mt Canobolas, Australia

TMR2 works

#2 Post by vineman » 23 Apr 2008 12:35

I thought the problem was in the interrupt service routine.

Code: Select all

if (INTCON.TMR0IF) {     // This is the triac trigger turn off.  It does not get reset.
  TMR0   = 235;
  INTCON.T0IE = 0;         // mask the interrupt
  INTCON.T0IF = 1;         // clear the flag 
The interrupt gets masked, but not reset.

Should be INTCON.T0IF = 0;

but this did not help.

I've coded with TMR2 and that seems to work.

I would still like to know why TMR0 does not work.

cardedon
Posts: 5
Joined: 08 Nov 2010 15:49

Re: Problem with interrupt INT and TMR0 crashing pic

#3 Post by cardedon » 09 Nov 2010 21:12

Hi
I have the same issue.
I tryed this code

Code: Select all

void main() {

  ADCON1 = 0x0F;
  T0CON  = 0b10001000;
  INTCON = 0xA0;
  CMCON = 7;
  TMR0H = 0xFE;
  TMR0L = 0xFF;
  while (1)
  {
  Delay_10us;
  }
}
And still TMR0 doesn't work.
Any solution?

Post Reply

Return to “mikroC General”