• AVR Freaks

Hot!Problem using interrupt using pic18f4550

Author
GuillaumeV
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2020/04/06 01:32:11
  • Location: Strasbourg, France
  • Status: offline
2020/04/07 06:30:32 (permalink)
0

Problem using interrupt using pic18f4550

Hello,
I ve got a problem using interrupts. I want to create an interrupt whenever INT0 = 1.
I use a pic 18f4550
As soon as my program has executed the interrupt setting function, it goes directly to the interrupt routine and keeps running the routine.
I used the simulator and I saw that the setting function set RB0 to 1. I don't understand why.
I use this code to initialise interrupt and PBADEN is OFF in my config. I also use AN0, I ve read it might create problem but I don't understand why.
TRISBbits.TRISB0=1;  /* Make INT0 pin as an input pin*/

/* Also make PBADEN off in Configuration file or
clear ADON in ADCON0 so as to set analog pin as digital*/

INTCON2=0x00; /* Set Interrupt on falling Edge*/
INTCONbits.INT0IF=0; /* Clear INT0IF flag*/
INTCONbits.INT0IE=1; /* Enable INT0 external interrupt*/
INTCONbits.GIE=1;
Do you have an idea where the problem comes from?

Thank you !
Guillaume
#1

13 Replies Related Threads

    ric
    Super Member
    • Total Posts : 26942
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/09 18:51:36 (permalink)
    +1 (1)
    GuillaumeV
    clear ADON in ADCON0 so as to set analog pin as digital*/

    That has nothing to do with setting pins to digital.
    Setting PBADEN should have done that for you, otherwise you do it by writing 0x0F to ADCON1
     
    You did not show the code for your interrupt service routine, which is where it sounds like you are not doing the right thing.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 08:02:21 (permalink)
    0
    Hello,
    I post the code.

     
    #include <xc.h>
    #include "adc.h"
    #include "config.h"
    #include "ldc_disp.h"
    #include <plib.h>
    #include <plib/delays.h>
    #include <plib/xlcd.h>
    #include <stdio.h>
    #include <stdlib.h>
    //#include "Interrupt.h"
    #define LED LATCbits.LATC0 //bits.RC0
    #define LED1 LATCbits.LATC1
    void MSdelay(unsigned int);
    void External_Interrupt_Init();
    void interrupt ISR();
     
    void main(void)
    {
        OSCCON=0x72;
       TRISCbits.TRISC1=0;
       TRISCbits.TRISC0=0;
        init_CAN ();
        init_XLCD();
        putrsXLCD("ADC");          //Display "Hello World"
        SetDDRamAddr(0x40);            //shift cursor to beginning of second line
        putrsXLCD("Display Voltage");      //Display "LCD display"
        for (int x = 0; x<=20; x++)  __delay_ms(50);
        WriteCmdXLCD(0x01);
        External_Interrupt_Init();
        //LED1=1;
        while(1)
        {
          
         voltage_read();   
         LED1 = ~LED1;
         MSdelay(500);
        
        }
        return;
    }
    void External_Interrupt_Init()
    {
        TRISBbits.TRISB0=1;        //make INT0 pin as an input pin
       // PORTBbits.INT0=0;
        //also make PBADEN off in Configuration file so as to set analog pin as digital
       
        INTCONbits.GIE=1;          //Enable Global Interrupt
        INTCONbits.INT0IE=1;       //Enable INT0 external interrupt
        INTCONbits.INT0IF=0;
        INTCON2bits.INTEDG0=1;
                     //Set Interrupt detection on rising Edge rb0
    }
    void interrupt ISR()
    {  //INTCONbits.GIE=0;
        if(INTCONbits.INT0IF=1)
        {
          do{
        LED = ~(LED);              //Toggle LED on interrupt
        MSdelay(500);
        voltage_read();
            }while(PORTBbits.INT0);
        }
        INTCONbits.INT0IF=0;
    }
    void MSdelay(unsigned int val)
    {
        unsigned int i,j;
        for(i=0;i<val;i++)
        {
            for(j=0;j<165;j++);
        }
    }
     
     
    If I use the code and I disable the lcd and adc parts it works.
    The program goes to the ISR only when rb0 is set to 1 and it goes out when rbo is set to 0. 
    I simulate it on proteus.
     Thank you for your feed back!
    Guillaume
    #3
    pcbbc
    Super Member
    • Total Posts : 1687
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 08:32:18 (permalink)
    +1 (1)
    This is totally the wrong way to use interrupts.
    You should never wait for things to happen or call delay routines in an ISR.
    Thats why your routine “keeps running”. It’s because you’ve programmed it to do that.
     
    Where‘s you code for voltage_read?
     
    #4
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 10:18:08 (permalink)
    0
    Ok but how I  can blink the LED if there is not a delay ?
    I want the led blinks while RB0 is high.
     
    this is the code for voltage_read but I removed it from the ISR, it was just for a test.

    void voltage_read (void)
    {
    unsigned int ADCResult=0;
    float voltage0, voltage1;
    unsigned char ResultString0[10],ResultString1[10];
         SelChanConvADC(ADC_CH0);
         while(BusyADC());
         ADCResult = ReadADC();
         voltage0 = (ADCResult*5.0)/1024;
        
         ADCResult=0;
         SelChanConvADC(ADC_CH1);
         while(BusyADC());
         ADCResult = ReadADC();
         voltage1 = (ADCResult*5.0)/1024;
        
         putrsXLCD("Voltage0 = ");
         sprintf(ResultString0, "%.3g", voltage0);
         putrsXLCD(ResultString0);
         putrsXLCD("V");
         putrsXLCD(" ");
         //WriteCmdXLCD(0x02);
        
         SetDDRamAddr(0x40);
         putrsXLCD("Voltage1 = ");
         sprintf(ResultString1, "%.3g", voltage1);
         putrsXLCD(ResultString1);
         putrsXLCD("V");
         putrsXLCD(" ");
         WriteCmdXLCD(0x02);
    }
     
    thanks
    #5
    pcbbc
    Super Member
    • Total Posts : 1687
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 10:28:56 (permalink)
    +1 (1)
    Use a timer interrupt to give yourself a regular “tick”.
    When you get the tick interrupt (or multiple of it), and PB0 is high, toggle the LED.
    No need for the pin interrupt at all.
    #6
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 14:16:04 (permalink)
    0
    Actually, this program is for training.
    I work on a project where I will have to launch interrupt when I reach voltage value.
    To simulate that I use proteus. I have a comparator and when I reach the value rb0 is set to 1.
    That s why I would like to understand what happen in this case.

    Thank you for your feed back
    #7
    pcbbc
    Super Member
    • Total Posts : 1687
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/10 14:42:29 (permalink)
    +1 (1)
    Okay then, you can still use the interrupt on RB0, but use that to start the timer.
    Then when the timer ticks (or a multiple thereof), toggle the led.
    Until RB0 changes state again, at which point disable the timer interrupt.
     
    Notice NO waiting in the ISR.
    #8
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 02:08:40 (permalink)
    0
    Hi,
    Ok, I removed the delay in the ISR so now it only toggles the LED.
    I found that the problem comes from the function voltage_read.
    If in this function, I disable this part which is suppose to wait until the and of the adc conversion and write the value in a variable it works.
     
         while(BusyADC()){}   
         ADCResult = ReadADC();
     
    I use XC8 compiler v1.34 because it has a Library for lcd display.
    Do you have an idea where is the connection between these functions and interrupts?
     
    Thank you very much for your help,
    Guillaume
    #9
    ric
    Super Member
    • Total Posts : 26942
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 02:59:33 (permalink)
    +1 (1)
    Again, you should NOT be waiting for something to happen inside an ISR.
    You should start the conversion in one ISR, and read the result in another one.
    Again, NEVER wait inside an ISR for something to happen.
    You may have to access the ADC hardware directly rather than using library functions. That's actually not very hard. The hardware is documented better than the library functions.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #10
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 04:11:45 (permalink)
    0
    Actually, the reading of the adc is independant from the ISR. I just read a value and I display it on a lcd in the main program.
    The ISR toggles a LED when RB0 is set to 1.

    Thanks
    Guillaume
    #11
    pcbbc
    Super Member
    • Total Posts : 1687
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 04:20:08 (permalink)
    +2 (2)
    But your original code was reading it in the ISR as well.
    Have you removed that?
    Post ALL of your new code if you want help.
    #12
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 06:56:05 (permalink)
    0
    Yes, I removed almost everything in the ISR.
    It remains only the led which toggles.
     
    I ve uploaded the code.
     
    Thank you very much!
    #13
    GuillaumeV
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2020/04/06 01:32:11
    • Location: Strasbourg, France
    • Status: offline
    Re: Problem using interrupt using pic18f4550 2020/04/11 10:11:31 (permalink)
    +1 (1)
    I just found the problem.
    In the openADC, I ve enabled interrupts that's why the program Always went to the ISR.
     
    Thank you very much for your help!
    Guillaume
    #14
    Jump to:
    © 2020 APG vNext Commercial Version 4.5