• AVR Freaks

Hot!input capture

Author
horkesley
Super Member
  • Total Posts : 285
  • Reward points : 0
  • Joined: 2008/09/09 00:13:17
  • Location: Essex,UK
  • Status: offline
2020/03/28 12:35:53 (permalink)
0

input capture

Hi
I am trying to use inout capture to measure pulse width. Eventually 5 input for a quadcoptor application.
My code does not produce an interrupt.
Any idea where i am going wrong.
 
This is the initailization.
 
void init_input_capture(void)
 {
   __builtin_disable_interrupts();
   CNCONbits.ON=1;                  //configure capture unit on
   IC1CONbits.ON=1;                 //turn capture on
   CNENbits.CNEN1=1;                //port RD8, ic1
   //CNENbits.CNEN2=1;              //port RD9, ic2
   //CNENbits.CNEN3=1;              //port RD10, ic3    
   //CNENbits.CNEN4=1;              //port RD11, ic4
   //CNENbits.CNEN5=1;              //port RD12, ic5
   IC1CONbits.ICTMR=1;              //select timer 2
   IC1CONbits.FEDGE=1;              //Rising edge first
   IC1CONbits.ICI=0;                //Interrupt on every event
   IC1CONbits.ICM=0x001;            //capture every edge
   IPC6bits.CNIP=3;                 //priority 3
   IPC6bits.CNIS=2;                 //sub prioriy
   IC1CONbits.ICOV=0;               //Clear buffer overflow
   IFS1bits.CNIF=0;                 //clear interrupt flag
   IEC0bits.IC1IE = 1;              // "enable ic1"
   IEC1bits.CNIE=1;             //enable interrupt for cn1
    __builtin_enable_interrupts();         
 }
 
This is the interrupt.
volatile unsigned int oldB=0, oldF=0, newB=0, newF=0;
void __ISR(_CHANGE_NOTICE_VECTOR, IPL3SOFT) CNISR(void)
//void __ISR( _CHANGE_NOTICE_VECTOR,IPL3{AUTO|SOFT|SRS|SAVEALL)
{
    newB=PORTB;
    newF=PORTF;
    oldB=newB;
    oldF=newF;
    if(newB != oldB & newF != oldF)
    {
        return;
    }
    
    IFS1bits.CNIF=0;            //clear interrupt
    input_capture();            //deal with cn interrupt
}
The code never gets to the interrupt routine.
Sorry for the format.
Any help.
 
#1

10 Replies Related Threads

    horkesley
    Super Member
    • Total Posts : 285
    • Reward points : 0
    • Joined: 2008/09/09 00:13:17
    • Location: Essex,UK
    • Status: offline
    Re: input capture 2020/03/28 12:36:54 (permalink)
    0
    Sorry input capture
     
    #2
    ric
    Super Member
    • Total Posts : 28390
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: input capture 2020/03/28 16:51:01 (permalink)
    0
    Which PIC are you using?
    Is the input pin on that PIC, analog capable?
    If yes, you have to switch it to digital mode.
     

    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!
    #3
    andersm
    Super Member
    • Total Posts : 2840
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: input capture 2020/03/28 17:07:08 (permalink)
    0
    There's a couple of things wrong with this if statement:
    newB=PORTB;
        newF=PORTF;
        oldB=newB;
        oldF=newF;
        if(newB != oldB & newF != oldF)
        {
            return;
        }

    1. You are using the bitwise and operator (&), but probably mean logical and (&&).
    2. Since you are setting oldB = newB and oldF = newF before testing, the condition can never be true, and is therefore completely redundant. Though I'm not sure what its purpose is anyway.
     
    Also, never use bit fields to write to self-modifying registers like IFSx. Use the IFSxCLR registers instead.
    #4
    horkesley
    Super Member
    • Total Posts : 285
    • Reward points : 0
    • Joined: 2008/09/09 00:13:17
    • Location: Essex,UK
    • Status: offline
    Re: input capture 2020/03/30 06:43:08 (permalink)
    0
    Thanks for your replies.
    Hi Ric, appoligise for the lack details.
    MPLAB v5.35
    PIC32 starter kit
    PIC32MX360F512L
    iMAC Catalina 10.15.4
    XC32 v2.40
    I don't believe it's a problem with a ADC conflict.
    Andersm, the bit of code, newB, oldB etc. I don't believe it's required, but i read somewhare that if the ports changed it could cause an interrupt, but i can't find any evidence of this, so it's removed.
    I don't understand your comment about self-modifying registers.
    Does IFSxCLR clear all bits in the register, but i want to clear or set individual bits, hence IFS1bits.CNIF=0;.
    Is my thinking incorrect.
    In example code on the Microchip site there are many instanses of what i have done. Are these bad practice.
    If i single step the code i can see RD8 change state in 'view peripheral' so the hardware is correct.
    Code still not working so any comments appreiated.
    Regards
     
    #5
    TJvV
    Starting Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2014/05/21 01:27:05
    • Location: 0
    • Status: offline
    Re: input capture 2020/03/30 07:37:57 (permalink)
    0
    Hi,
     
    Did you enable multi-vector interrupts (MVEC bit in INTCON)?
    If you didn't, interrupts will cause the CPU to jump to a different vector than you're expecting (i.e. not _CHANGE_NOTICE_VECTOR).
     
    Basic sanity check: can you trigger your interrupt by manually setting the CNIF bit?
     
     
    #6
    horkesley
    Super Member
    • Total Posts : 285
    • Reward points : 0
    • Joined: 2008/09/09 00:13:17
    • Location: Essex,UK
    • Status: offline
    Re: input capture 2020/03/30 08:37:15 (permalink)
    0
    Hi TJvV,
    Thanks for the comments. I have enabled multi vector interrupts.
    Your sanity check works, the code jumps to the correct place.
    But level change on RD8 does not cause interrupt. I still have something missing.
    Any ideas.
    void init_input_capture(void)
     {
       __builtin_disable_interrupts();
       CNCONbits.ON=1;                 //configure capture unit on
       IC1CONbits.ON=1;                 //turn capture on bit 15
       CNENbits.CNEN1=1;                //port RD8, ic1 bit 1
       //CNENbits.CNEN2=1;              //port RD9, ic2
       //CNENbits.CNEN3=1;              //port RD10, ic3    
       //CNENbits.CNEN4=1;              //port RD11, ic4
       //CNENbits.CNEN5=1;              //port RD12, ic5
       IC1CONbits.ICTMR=1;              //select timer 2 bit 7
       IC1CONbits.FEDGE=1;              //Rising edge first bit 9
       IC1CONbits.ICI=0;                //Interrupt on every event bits 5,6
       IC1CONbits.ICM=0x001;            //capture every edge bit 0,1,2
       IPC6bits.CNIP=3;                 //priority 3
       IPC6bits.CNIS=2;                 //sub prioriy bit 1
       IC1CONbits.ICOV=0;               //Clear buffer overflow
       IFS1bits.CNIF=0;                 //clear interrupt flag
       IEC0bits.IC1IE = 1;              // "enable ic1"
       IEC1bits.CNIE=1;                 //enable interrupt for cn1 bit 1
       INTCONbits.MVEC = 1;             //Enable multi vector interrupts
       __builtin_enable_interrupts();
       
         //IFS1bits.CNIF=1;      //cause interrupt, this works, otherwise
                               //code does not interrupt.
     }
     
    #7
    ric
    Super Member
    • Total Posts : 28390
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: input capture 2020/03/30 12:17:37 (permalink)
    +1 (1)
    horkesley
    Does IFSxCLR clear all bits in the register,

    No, only the bits you tell it to.
    Any "1" bit in the parameter clears the corresponding bit in the register.
    This is all clearly documented in the datasheet.

    but i want to clear or set individual bits, hence IFS1bits.CNIF=0;.

    and as already mentioned, that is the WRONG way to do it.
    The compiler has to generate code to read the register into temporary storage, modify the copy, then write that back to the IFS1 register. If some other interrupt tries to clear a different bit in the same register, this value will now be corrupted. That is WHY the xxxCLR register exists.

    Is my thinking incorrect.

    Yes
     

    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!
    #8
    TechnoGilles
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2011/08/02 11:44:46
    • Location: 0
    • Status: offline
    Re: input capture 2020/03/31 18:04:34 (permalink)
    0
    Hi,
    I did not do a thorough investigation of your code but I see that you have two separate modules at play here and I am not sure I understand why. First, you use the Input Capture IC1 for pin 68 of your device (RTCC/IC1/RD8) which seems ok. But I see you also enable the Change Notice CN1 which is pin 73 of your device (SOSCI/CN1/RC13) and as you can see is associated with bit 13 of Port C. In order to get the Change Notice interrupt, that pin would need to toggle. My guess, but I may be wrong, is that you are confusing the two functionalities. From what I understand, you do not need the CN module, only the IC.
    post edited by TechnoGilles - 2020/03/31 18:09:26
    #9
    horkesley
    Super Member
    • Total Posts : 285
    • Reward points : 0
    • Joined: 2008/09/09 00:13:17
    • Location: Essex,UK
    • Status: offline
    Re: input capture 2020/04/01 06:19:31 (permalink)
    0
    Hi, I think you are correct about my confusion. All I want to do is measure the time between a rising and falling edge.
    The pulses are 1000uS to 2000uS wide with a resolution of 1uS,. at a rate of 250Hz.
    I think IC will do this.
    Thanks for comments.
     
    #10
    horkesley
    Super Member
    • Total Posts : 285
    • Reward points : 0
    • Joined: 2008/09/09 00:13:17
    • Location: Essex,UK
    • Status: offline
    Re: input capture 2020/04/03 07:13:40 (permalink)
    0
    I have made the changes as suggested, but still no interrupt. I have still got something wrong!!!
    Here's the code. Any idea, please.
     
    void init_input_capture(void)
     {
        
         __builtin_disable_interrupts();
       //CNCON.CN=1;
       IC1CONSET=0x8000; //turn input capture on bit15
       CNENSET=0x01; //port RD8, ic1 bit 1 ok
       //CNENbits.CNEN2=1; //port RD9, ic2
       //CNENbits.CNEN3=1; //port RD10, ic3
       //CNENbits.CNEN4=1; //port RD11, ic4
       //CNENbits.CNEN5=1; //port RD12, ic5
        
       IC1CONSET=0x1000; //First rising edge bit 9 ok
       IC1CONCLR=0x0060; //Interrupt on every event bits 5,6
       IC1CONCLR=0x0001; //capture every edge bit 0,1,2 bit 1 ok
       IPC6SET=0x00140000; //priority 5 ok bits 20-19-18 0x101
       IPC6SET=0x0001; //sub prioriy bit 1
      
       IEC0SET=0x20; // "enable ic1" interrupts bit 5 ok
       IEC1SET=0x0001; //enable interrupt for cn1 bit 1 ok
       INTCONSET=0x01000; //Enable multi vector interrupts bit 12 ok
       __builtin_enable_interrupts();
       
         //IFS1bits.CNIF=1; //Sanity check, causes interrupt, this works
                                    //otherwise code does not interrupt.
     }

    void __ISR(_TIMER_1_VECTOR, ipl5SOFT)_Timer1Handler(void)
    //void Timer1_interrupt() iv IVT_Timer_1 iLevel 7 ics ICS_SRS
      {
        IFS0bits.T1IF=0; //clear interrupt
        
        LED1_LAT ^=1; //toggle led see interrupt
    }

    void __ISR(_CHANGE_NOTICE_VECTOR, IPL5SOFT) CNISR(void)
    //void __ISR( _CHANGE_NOTICE_VECTOR,IPL3{AUTO|SOFT|SRS|SAVEALL)
    {
        int a;
        a=PORTD;
       
        IFS1CLR=0x0001; //clear interrupt
        input_capture(); //deal with cn interrupt
    }

    #11
    Jump to:
    © 2020 APG vNext Commercial Version 4.5