Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help with PIC18F2455, Comparator interrupt

Status
Not open for further replies.

tzh0013

New Member
I'm using a PIC18F2455 microcontroller, I want the MCU detect a square wave and begins to send a signal for 0.5 seconds, and when the square wave stops, it can send another signal from another port for 0.5 seconds, The code complies but just doesn't function properly. (Works sometimes but fail in others )
could somebody help me with this , thanks


Code:
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include <p18f2455.h>
#pragma config FOSC = HS // Oscillator Selection:External oscillator
#pragma config WDT = OFF	// Watchdog Timer
#pragma config LVP = OFF	// Low Voltage ICSP(PIN 6):Disabled



unsigned int intr;
unsigned int state;

void InterruptHandlerHigh (void);
void main(void)
{
     
        state = 0;
        intr = 0;
        TRISC = 0;
        PIE2bits.CMIE = 1;
        TRISAbits.TRISA0 = 1;
        TRISAbits.TRISA1 = 0;
        TRISAbits.TRISA2 = 0;
        TRISAbits.TRISA3 = 1;
        TRISAbits.TRISA4 = 0;
        TRISAbits.TRISA5 = 0;
        TRISC = 0;
    	INTCONbits.PEIE = 1 ;
        INTCONbits.GIE = 1;
        CMCON = 0b00000001;
        
   
        while (1)
            switch (state)
            { case (0):
                    PORTAbits.RA5 = 0;
                    PORTCbits.RC0 = 0;
                    Delay10KTCYx(20);
                if ( intr)
                { state = 1;
                  intr = 0;
                }
                else {state = 0;}
                break;
              
                case (1):
                   PORTAbits.RA5 = 0;
                    PORTCbits.RC0 =1;
                    Delay10KTCYx(100);
                    state = 2;
                    intr = 0;
                    break;
                case (2):
                    PORTAbits.RA5 = 0;
                PORTCbits.RC0 =0;
                Delay10KTCYx(20);
                if (intr)
                    {             
                
                intr = 0;
                state = 2 ;}
                    else {
          
                    intr=0;
                    state = 3;
                   }
                      break;
                case (3):
                      PORTAbits.RA5 = 0;
                      PORTCbits.RC0 =0;
                     Delay10KTCYx(20);
                     if (intr)
                     { 
                     intr = 0;
                     state = 2;}
                     else {state = 4;
                     intr = 0;
                     }
                     break;
                  case (4):
                      PORTAbits.RA5 = 1;
                PORTCbits.RC0 =0;
                    Delay10KTCYx(100);
                    state = 0;
                    intr = 0;
                    break;
                    default:
                    PORTAbits.RA5 = 0;
                    PORTCbits.RC0 = 0;
                        state = 0;
                       break;}
        
            }

//**BEGIN INTERRUPT CONTROL**
#pragma code InterruptVectorHigh = 0x08		//interrupt pointer address (0x08 high priority)
void InterruptVectorHigh (void)
{
        _asm						//assembly code starts
        goto InterruptHandlerHigh	//interrupt control
        _endasm						//assembly code ends
}
#pragma code
#pragma interrupt InterruptHandlerHigh		//end interrupt control
void InterruptHandlerHigh()		// Declaration of InterruptHandler
{
        if(PIR2bits.CMIF){
                        intr = 1;
			PIR2bits.CMIF = 0;	//Clear Flag
        }
    INTCONbits.GIE = 1;
    PIE2bits.CMIE = 1;  //Re-enable all interrupts
return;
}

[MODNOTE]Please use Code Tags The "#" symbol[/MODNOTE]
 
Last edited by a moderator:
You need to share your variable "intr" between main and your ISR.... You can make it volatile so they can both access it...

There is a mechanism in place to do this correctly..
Sharing Temporary Data Sections Between ISR Functions And Non-ISR Functions
The tmpdata pragma may be used to share temporary data between interrupt service routines and non-interrupt functions. In the following example, the compiler temporary variables for the interrupt service routine isr and the non-interrupt function increment are both placed in the udata section isr_tmp.

void increment (int counter);
void isr (void);
#pragma interrupt isr nosave=section(".tmpdata")
void isr (void)
{
static int foo = 0;
...
increment (foo);
...
}
#pragma tmpdata isr_tmp
void increment (int counter)
{
...
}
#pragma tmpdata

Note: When the compiler preserves context for an ISR, the compiler will automatically save the default temporary data section, .tmpdata, even if the tmpdata pragma specifies a different temporary data section for the ISR-called functions. In order to tell the compiler not to add the context saving overhead for the .tmpdata section, the nosave= clause of the interrupt pragma is used

This is from the C18 documentation..
 
I did, but it doesn't changes anything. The circuit is acting wired, it works fine in the room but acting redicules outside of the room.
I'm checking the other parts of the circuit and see if there's problem eslewhere, still thank you for your information .I'll let you know what's wrong after I find out.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top