• AVR Freaks

AnsweredHot!dsPIC30F3014 Simultaneous Interrupts issue

Page: 12 > Showing page 1 of 2
Author
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
2020/11/24 17:07:43 (permalink)
0

dsPIC30F3014 Simultaneous Interrupts issue

Hi everyone,
 
Though I've been consulting this forum for a while, this is my absolute first thread, so I apologize in advance if I haven't included some critical information needed to troubleshoot my issue. I've looked around here (and other online resources) for hours but I haven't seen anything that really describes my issue, so here goes:
 
Device: dsPIC30F4013, MPLAB X IDE v5.40, Compiler: XC 16, Programming device: PICkit3. OS: Windows 10
 
Functionality description: The program's main loop counts up the number of times a button is pressed (pin RFO[30]) and prints the current count to an LCD screen (this part works fine). I need to write 3 interrupt routines which will read 3 NPN inductive sensors, each of which shall print a unique alarm message to the screen. Only after the sensors are reset (they're "seeing" metal again) AND a Reset button programmed at pin RB1[3] is pushed (as an acknowledge button), should the program return to the main loop where it can count again.
 
The NPN sensors I'm using work at 12VDC, and I'm using 3 PC817 optocouplers to isolate this high voltage from the 5VDC I'm supplying to the dsPIC30F4013 (and the signals the optocouplers send). I have checked that these devices work properly and that they're only sending a signal when they're supposed to.
 
I programmed the 1st interrupt at pin INT0/RA11[18] and this worked as expected. I then copied most of this code (modifying the appropriate registers) and am now also using INT1/RD8 [23] as input for the 2nd interrupt routine. The program compiles with no errors, however, when I test this on my PCB, only one of the interrupts works. When I comment INT0, INT1 works as expected, and vice versa. They cannot work simultaneously. To clarify, I don't mean that I can't use nested interrupts (this isn't what I'm trying to do), but that when I energize the dsPIC, only 1 interrupt works at all. Note that the interrupt that works is always the same one (whichever was the most recent one to NOT be commented before I uncommented both interrupts).
 
For the sake of brevity, I've included my code in a .txt file for your consideration.
 
Thank you very much for any help you might be able to provide.
 
Best regards,
Rob
#1
davea
Super Member
  • Total Posts : 585
  • Reward points : 0
  • Joined: 2016/01/28 13:12:13
  • Location: Tampa Bay FL USA
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 11:14:17 (permalink)
2 (1)
while(PORTAbits.RA11==1){ 
and
while(PORTDbits.RD8==1){
what do you expect to happen
while waiting waiting in 1 ISR
it cant do the other
restructure the code use flag bits 
and evaluate the bits in main
using delays in a ISR is bad thing to do..
#2
Jerry Messina
Super Member
  • Total Posts : 589
  • Reward points : 0
  • Joined: 2003/11/07 12:35:12
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 11:52:14 (permalink) ☄ Helpfulby rmz22 2020/11/25 12:43:56
0
using delays in a ISR is bad thing to do..

As is trying to write to an LCD... if it interrupts an ongoing LCD operation you're hosed.
#3
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 11:53:23 (permalink)
0
Hi davea,
 
First of all, thanks for reading my question and going through the code.
 
davea
while(PORTAbits.RA11==1){ 
and
while(PORTDbits.RD8==1){
what do you expect to happen



The reason why I'm using nested "while" loops inside the Interrupts to check RA11 and RD8 for "1" and "0" is because in order to come back from the ISR, 2 conditions must be true simultaneously, in either INT0/INT1, the sensor must detect the guard/wrench (RA11/RD8 == 0) AND the operator must click a "Reset/Acknowledge" button, to make sure a motor (I'm not handling this part of the code, which is on another device anyway) can't just go into operation as soon as a sensor is back in place. So if I reset the guard/remove the wrench, the LCD will display something like "Sensor OK, press Reset to return to Run mode" but, if at any time the sensor stops detecting, the LCD should go back to displaying the Alarm code, which is why I'm constantly polling these 2 bits.
 
davea
while waiting waiting in 1 ISR
it cant do the other



I don't mean to enable the activation of 2 ISRs simultaneously (I think these would be Nested Interrupts), what I mean by INT0 and INT1 not working "together" is that, when I start up the dsPIC, only INT0 works. Which one of the 2 interrupts I trigger first by manually triggering the sensors is irrelevant. In other words, if I turn on the circuit, I can go into INT0 just fine and come back from it after tending to the sensor and pressing the acknowledge button, but when I come back into the normal operation mode, even if I trigger the second sensor, the dsPIC doesn't go into INT1.
 
davea
restructure the code use flag bits 
and evaluate the bits in main
using delays in a ISR is bad thing to do..

 
I'll look into this, and thanks for pointing out the issue with delays in ISR, I knew this but unfortunately, this is the only way I currently know how to deal with LCD issues (if I don't include the delays, the LCD Screen will sometimes display symbols which it isn't supposed to). If you could mention any workarounds, I'd really appreciate it.
 
Thanks again,
Rob
#4
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 11:59:13 (permalink)
0
Jerry Messina
using delays in a ISR is bad thing to do..

As is trying to write to an LCD... if it interrupts an ongoing LCD operation you're hosed.



Hi Jerry,
 
Do you have any suggestions as to how I might print to an LCD screen without including said part of the code inside the ISR? We have a working example of the machine we're trying to reproduce and it operates the way I described. Normal operation-> Blinking alarm code -> Alarm code stops blinking when the triggering sensor has been tended to -> Reset button returns to Normal operation. So I suppose there has to be a better way to interact with the LCD screen?
 
Thanks,
Rob
#5
ric
Super Member
  • Total Posts : 29435
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:21:16 (permalink) ☼ Best Answerby rmz22 2020/11/25 12:43:26
4 (1)
As already stated, NEVER put blocking code inside an ISR.
This statement concerns me greatly

because in order to come back from the ISR, 2 conditions must be true simultaneously,

Any ISR should be written to exit as soon as possible. There should never be any condition holding you inside the ISR. Otherwise it's pointless using interrupts at all.

Do you have any suggestions as to how I might print to an LCD screen without including said part of the code inside the ISR? We have a working example of the machine we're trying to reproduce and it operates the way I described. Normal operation-> Blinking alarm code -> Alarm code stops blinking when the triggering sensor has been tended to -> Reset button returns to Normal operation. So I suppose there has to be a better way to interact with the LCD screen?

Restructure the code so all slow actions happen outside the ISR. You will need to learn how to code "state machines" to do this effectively.
 

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!
#6
Jerry Messina
Super Member
  • Total Posts : 589
  • Reward points : 0
  • Joined: 2003/11/07 12:35:12
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:32:12 (permalink)
0
What ric said.
 
Looking at the code, you could easily ditch the interrupts entirely and just poll the input pins.
As it stands, the isrs display messages and wait for a human operator to press a button... hardy something that requires an interrupt.
 
#7
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:35:33 (permalink)
0
Hi ric,
 
Thanks very much for your suggestions, what I gather from all answers is that I may be able to make this work with ISRs by using them to only set flag bits which will be linked to the different States of the State Machine you mention, whose "slow actions", to borrow from your comment, will include polling the necessary conditions to reestablish functions and printing to the screen, so I'll give that a go and come back to share my results.
 
Best regards,
Rob
#8
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:38:28 (permalink)
0
Hi Jerry,
 
Thank you, I'll give that a go. I wonder though, would it not be better practice (as the sensors are important safety features) to use the ISRs if only just to raise said flag bits that will then go into the States/Subroutines ric mentioned?
 
Best,
Rob
 
#9
ric
Super Member
  • Total Posts : 29435
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:43:51 (permalink) ☄ Helpfulby rmz22 2020/11/25 12:44:48
0
You only need to the interrupt to handle things that must happen with minimum latency.
e.g. If a power source must be shut down as soon as possible, you could flip a pin inside the ISR, but leave less critical actions, like updating an LCD, to later.
 

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
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 12:45:29 (permalink)
0
Understood, thank you both!
#11
dan1138
Super Member
  • Total Posts : 4157
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 15:23:02 (permalink) ☄ Helpfulby rmz22 2020/11/25 16:46:35
5 (1)
Here's template custom crafted for your project:
/*
 * File:     main.c
 * Target:   dsPIC30F3014
 * Author:   dan1138
 * Compiler: XC16 v1.60
 * IDE:      MPLABX v5.45
 *
 *                               dsPIC30F3014
 *                    +--------------:_:--------------+
 *          VPP ->  1 : MCLRn                    AVDD : 40 <- PWR
 *          LED <>  2 : RB0/AN0                  AVSS : 39 <- GND
 * RESET_BUTTON <>  3 : RB1/AN1               AN9/RB9 : 38 <>
 *              <>  4 : RB2/AN2             AN10/RB10 : 37 <>
 *              <>  5 : RB3/AN3             AN11/RB11 : 36 <>
 *              ->  6 : RB4/AN4             AN12/RB12 : 35 <>
 *              ->  7 : RB5/AN5              PGC2/RD0 : 34 <> LCD_D4
 *          PGC <>  8 : RB6/PGC/AN6          PGD2/RD1 : 33 <> LCD_D5
 *          PGD <>  9 : RB7/PGD/AN7               VDD : 32 <- PWR
 *              <> 10 : RB8/AN8                   VSS : 31 <- GND
 *          PWR -> 11 : VDD                       RF0 : 30 -> LCD_E
 *          GND -> 12 : VSS                       RF1 : 29 -> LCD_RS
 *              -> 13 : OSC1                  RX2/RF4 : 28 ->
 *              <- 14 : RC15/OSC2             TX2/RF5 : 27 ->
 *              <> 15 : RC13/PGD1/SOSCO       RX1/RF2 : 26 <- RXD
 *              <> 16 : RC14/PGC1/SOSCI  TX1/PGD3/RF3 : 25 -> TXD
 *      Sensor0 <> 17 : RA11/INT0            PGC3/RF6 : 24 <> LCD_R/W
 *      Sensor2 <> 18 : RD9/INT2             INT1/RD8 : 23 <> Sensor1
 *       LCD_D7 <> 19 : RD3                       RD2 : 22 <> LCD_D6
 *          GND -> 20 : VSS                       VDD : 21 <- PWR
 *                    +-------------------------------:
 *                                 DIP-40
 *
 *   LCD 4-bit connections:
 *   RD0  <> LCD_D4    Special note that the LCD module I am using is a
 *   RD1  <> LCD_D5    NOVATEK 7605. In 4-bit mode the NOVATEK 7605 is
 *   RD2  <> LCD_D6    not 100% compatible with the Hitachi HD44780.
 *   RD3  <> LCD_D7    The issue is that in 4-bit mode a status read
 *   RF0  -> LCD_E     returns the 4-bits in an order that is different
 *   RF1  -> LCD_RS    from the HD44780.
 *   RF6  -> LCD_R/W
 *
 * Created on November 25, 2020, 2:18 PM
 *
 */
// FOSC
#pragma config FOSFPR = FRC_PLL16       // Oscillator (FRC w/PLL 16x)
#pragma config FCKSMEN = CSW_ON_FSCM_OFF// Clock Switching and Monitor (Sw Enabled, Mon Disabled)

// FWDT
#pragma config FWPSB = WDTPSB_16        // WDT Prescaler B (1:16)
#pragma config FWPSA = WDTPSA_512       // WDT Prescaler A (1:512)
#pragma config WDT = WDT_OFF            // Watchdog Timer (Disabled)

// FBORPOR
#pragma config FPWRT = PWRT_OFF         // POR Timer Value (Timer Disabled)
#pragma config BODENV = BORV20          // Brown Out Voltage (Reserved)
#pragma config BOREN = PBOR_OFF         // PBOR Enable (Disabled)
#pragma config MCLRE = MCLR_EN          // Master Clear Enable (Enabled)

// FGS
#pragma config GWRP = GWRP_OFF          // General Code Segment Write Protect (Disabled)
#pragma config GCP = CODE_PROT_OFF      // General Segment Code Protection (Disabled)

// FICD
#pragma config ICS = ICS_PGD            // Comm Channel Select (Use PGC/EMUC and PGD/EMUD)
/*
 * Target specific include files
 */
#include <xc.h>
/*
 * Standard C library include files
 */
#include <stdio.h>
#include <stdbool.h>
/*
 * Application specific include files
 */
#include "init.h"
#include "lcd.h"
/*
 * Hook to send printf output to LCD
 */
int __attribute__((__section__(".libc.write"))) write(int handle, void *buffer, unsigned int len)
{
    unsigned int i;

    for (i = len; i; --i)
    {
        LCD_WriteData(*(unsigned char*)buffer++);
    }
    return(len);
}
/*
 * Global memory
 */
bool INT0_Event;
bool INT1_Event;
bool INT2_Event;
/*
 * Initialize this PIC
 */
void PIC_Init(void)
{
    __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
    
    IEC0 = 0;
    IEC1 = 0;
    IEC2 = 0;
    
    INTCON1bits.NSTDIS = 1; /* disable interrupt nesting */
    
    __builtin_disi(0x0000); /* enable interrupts */
    
    ADPCFG = 0x1FFF; /* Set for digital I/O */
}
/*
 * Guard sensor interrupt
 */
void INT0_Init(void)
{
    IEC0bits.INT0IE = 0;    //Disable interrupts
    TRISAbits.TRISA11 = 1;  //Make INT0 an input
    INTCON2bits.INT0EP = 0; //Interrupt on Positive Edge (When metal is not detected)
    IPC0bits.INT0IP = 5;    //Set interrupt priority
    IFS0bits.INT0IF = 0;    //External interrupt 0 flag status bit
    INT0_Event = 0;
    IEC0bits.INT0IE = 1;    //Enable interrupts
}
/*
 * INT0 handler
 */
void __attribute__((interrupt, auto_psv)) _INT0Interrupt(void)
{
    IFS0bits.INT0IF = 0; //Clear Raised Interrupt Flag
    INT0_Event = 1;     /* Set by handler cleared in process loop */
    /*
     * Perform emergency hardware dependent actions here.
     * DO NOT SPIN WAIT WITHIN AN INTERRUPT HANDLER,
     */
}
/*
 * Wrench sensor interrupt
 */
void INT1_Init(void)
{
    IEC1bits.INT1IE = 0;    //Disable interrupts
    TRISDbits.TRISD9 = 1;   //Make INT2 an input
    INTCON2bits.INT1EP = 0; //Interrupt on Positive Edge (When metal is detected)
    IPC4bits.INT1IP = 5;    //Set interrupt priority
    IFS1bits.INT1IF = 0;    //External interrupt 1 flag status bit
    INT1_Event = 0;
    IEC1bits.INT1IE = 1;    //Enable interrupts
}
/*
 * INT1 handler
 */
void __attribute__((interrupt, auto_psv)) _INT1Interrupt(void)
{
    IFS1bits.INT1IF = 0; //Clear Raised Interrupt Flag
    INT1_Event = 1;     /* Set by handler cleared in process loop */
    /*
     * Perform emergency hardware dependent actions here.
     * DO NOT SPIN WAIT WITHIN AN INTERRUPT HANDLER,
     */
}
/*
 * sensor2 interrupt
 */
void INT2_Init(void)
{
    IEC1bits.INT2IE = 0;    //Disable interrupts
    TRISDbits.TRISD8 = 1;   //Make INT1 an input
    INTCON2bits.INT2EP = 0; //Interrupt on Positive Edge (When metal is detected)
    IPC5bits.INT2IP = 5;    //Set interrupt priority
    IFS1bits.INT2IF = 0;    //External interrupt 1 flag status bit
    INT2_Event = 0;
    IEC1bits.INT2IE = 1;    //Enable interrupts
}
/*
 * INT2 handler
 */
void __attribute__((interrupt, auto_psv)) _INT2Interrupt(void)
{
    IFS1bits.INT2IF = 0; //Clear Raised Interrupt Flag
    INT2_Event = 1;     /* Set by handler cleared in process loop */
    /*
     * Perform emergency hardware dependent actions here.
     * DO NOT SPIN WAIT WITHIN AN INTERRUPT HANDLER,
     */
}
/*
 * Main application
 */
int main(void)
{
    /*
     * Application initialization
     */
    PIC_Init();
    LCD_Init();
    /*
     * User interface initialization
     */
    TRISBbits.TRISB0 = 0; // Make LED and output
    LATBbits.LATB0   = 0; // Set LED off
    TRISBbits.TRISB1 = 1; // Make RESET_BITTON an input
    /*
     * Show we are started
     */
    LCD_SetDDRamAddr(LINE_ONE);
    printf("dsPIC30F3014 Start");
    /*
     * Enable interrupts
     */
    INT0_Init();
    INT1_Init();
    INT2_Init();
    /*
     * Application process loop
     */
    for(;;)
    {
        /*
         * Implement state machines to show status to operator
         * and handle interactions with the operator.
         */
        if(INT0_Event)
        {
            Nop();
            INT0_Event = 0;     /* Set by handler cleared in process loop */
        }
        if(INT1_Event)
        {
            Nop();
            INT1_Event = 0;     /* Set by handler cleared in process loop */
        }
        if(INT2_Event)
        {
            Nop();
            INT2_Event = 0;     /* Set by handler cleared in process loop */
        }
    }
    return 0;
}

It's not likely to just drop in and run in your hardware.
But it works for me.
#12
davea
Super Member
  • Total Posts : 585
  • Reward points : 0
  • Joined: 2016/01/28 13:12:13
  • Location: Tampa Bay FL USA
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 16:10:54 (permalink) ☄ Helpfulby rmz22 2020/11/25 16:46:40
0
I would do what ric said and only use 1 ISR for the critical safety function
set a pin to shut off the motor NOW...
in the main use polling for the other 2 inputs
in the state machine you could use the shut down bit as a flag (LAT NOT PORT)
you only need to update the LCD as needed
ie: when count increments
or fault
and debounce the reset switch in the state machine, as you don't want noise to trigger a false reset
 
 
 
#13
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/11/25 16:50:47 (permalink)
0
dan1138
Here's template custom crafted for your project:[code]/*



Thank you Dan! That is most helpful, I will analyse what you did and give it my best shot to make it work with what I've got, really appreciate your template code!
 
davea
I would do what ric said and only use 1 ISR for the critical safety function
set a pin to shut off the motor NOW...
in the main use polling for the other 2 inputs
in the state machine you could use the shut down bit as a flag (LAT NOT PORT)



Thank you davea, I will make sure to keep that in mind when adapting Dan's code.
 
Regards to you both,
Rob
#14
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/02 13:42:29 (permalink)
0
Hi everyone,
 
I have implemented dan1138's template code with my modifications to fit my LCD and other needs. The code for each interrupt now lowers the interrupt flag that called it while raising an INTx_Event flag that will be polled in the main function, to address the issues with polling/checking conditios inside an ISR pointed out by davea & ric. After my first tests, however, the dsPIC behaved in the exact same way as before, INT0 continues to work but INT1 doesn't. I've checked all connections, as well as voltages being supplied by Optocouplers to the MC (the sensors operate with 12VDC) and they are all working as expected. I kept making small changes to no avail, referred back to the dsPIC30 Family reference manual and the XC16 compiler notes for my specific dsPIC to check if maybe I was configuring interrupts wrong but every register and bit seems to be set correctly. Today, however, I've discovered something that has baffled me, which I hope will resolve the issue when fixed:

I entered debug mode in MPLAB X IDE v5.40 with (in Simulator) to monitor the set and register bits, and I found that, although my configuration declares the Int1 pin as "TRISDbits.TRISD8 = 1" input, in the same way that I declare Int0 pin as one (TRISAbits.TRISA11 = 1, which works fine), when I set breakpoints and overwatch I/O Pins, INT1 is always in Dout mode, while INT0 is Din, as shown in the image. When I apply a Stimulus to RA11/Int0, the program works as expected, enters ISR0 and only comes out when I virtually reset the sensor and hit the reset button. However, when I apply a Stimulus to RD8/Int1, the flag associated to the bit is never raised, and thus the debugger never enters ISR1. I have checked my code line for line to see if I was mistakingly reassigning the RD8/Int1 pin as an output, both in my main file and the LCD library I'm using. It's not. There is only one assignment and it is as an input.
 
Has anyone faced this issue before? Any suggestions as to what I might do?
#15
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/02 13:43:29 (permalink)
4 (1)
Sorry, I don't know why the file sharing link isn't working. Here's the URL to the image:
https://postimg.cc/QFZcZQ57
 
Kind regards,
Rob
 
#16
ric
Super Member
  • Total Posts : 29435
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/02 14:25:56 (permalink) ☄ Helpfulby rmz22 2020/12/03 11:14:11
4.5 (2)
The most likely explanation is that a part of the code you are not showing us is setting TRISDbits.TRISD8 back to 0.
 

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!
#17
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/03 09:03:57 (permalink)
0
Hi ric,
 
I had that thought too, but I searched for a second TRISDbits.TRIDS8 assignment both visually and using the "Find" function in both the main.c and xlcd.c library source files (the only 2 currently in my project) and couldn't find another hit. The only assignment is as an input, as shown in the previous image, here's the full code for the main.c file. I omit sharing the xlcd.c code since it's over 500 lines, but I can assure you that there are no TRISD assignments there.
 

#include "config.h"
#include "reloj.h"    //Operating cycle frequency
#include <libpic30.h> //For delay functions
#include "xlcd.h"
#include <stdio.h>
#include <p30F4013.h>
#include <stdbool.h>
#define RESET_BUTTON PORTBbits.RB1
int count=0;
bool INT0_Event;
bool INT1_Event;
//bool INT2_Event;
char char_count[6];
int current_status = 0;

//Guard sensor interrupt
void INT0_Init(void){
    IEC0bits.INT0IE = 0; //Disable interrupts
    TRISAbits.TRISA11 = 1; // Configure RA11/INT0 as input
    INTCON2bits.INT0EP = 0;  //Interrupt on Positive Edge (When metal is not detected)
    IPC0bits.INT0IP = 5;  //Set interrupt priority
    IFS0bits.INT0IF = 0;  //External interrupt 0 flag status bit
    INT0_Event = 0;  //Lower INT0 Flag
    IEC0bits.INT0IE = 1;  //Enable interrupts
}
//INT0 Handler
void __attribute__((interrupt, auto_psv)) _INT0Interrupt(void){
    IFS0bits.INT0IF = 0; //Clear Raised Interrupt Flag
    INT0_Event = 1;     
}
//Wrench sensor interrupt
void INT1_Init(void){
    IEC1bits.INT1IE = 0; //Disable interrupts
    TRISDbits.TRISD8 = 1; //Configure RD8/INT1 as input
    INTCON2bits.INT1EP = 0;  //Interrupt on Positive Edge (When metal is detected)
    IPC4bits.INT1IP = 5;  //Set interrupt priority
    IFS1bits.INT1IF = 0;  //External interrupt 1 flag status bit
    INT1_Event = 0;  //Lower INT1 Flag
    IEC1bits.INT1IE = 1;  //Enable interrupts
}
//INT1 Handler
void __attribute__((interrupt, auto_psv)) _INT1Interrupt(void){
    IFS1bits.INT1IF = 0; //Clear Raised Interrupt Flag
    INT1_Event = 1;   
}

//Main application
int main(void){
    ADPCFG = 0x1FFF; //All inputs Digital
    //Test interrupts
    LATB = 0;
    TRISBbits.TRISB0 = 0; //Configure RB0 pin as output
    TRISBbits.TRISB1 = 1; //Configure RB1 (RESET_BUTTON) as input
    LATBbits.LATB1 = 0;
        
    //Initialize Interruptions
    INT0_Init();
    INT1_Init();
    //INT2_Init();
    
    TRISFbits.TRISF0=1; //Use as Input to Count-up
    XLCDInit();         //Initialize screen
    XLCDgotoXY(0,0);    //Place cursor
    putrsXLCD("dsPIC30F4013");  //Print out text
    __delay_ms(2000);           //2 sec delay
    WriteCmdXLCD(CLEAR_XLCD); //Clear screen
    
    while(1){   
        XLCDgotoXY(0,0);    //Place cursor
        putrsXLCD("No. of pulses: ");  //Print text
        LATBbits.LATB0 = 1; //Turn on RB0 LED, Sensor is detecting
        if(PORTFbits.RF0==0){   //Detect pulse in RF0
            __delay_ms(200);
            while(!PORTFbits.RF0);
            count+=1;
        }
        //Convert int to string
        XLCDgotoXY(1,0);
        sprintf(char_count, "%d", count);
        putrsXLCD(char_count);  //Print out conteo  
        
        //Alarm 1 Triggered: Guard sensor
        if(INT0_Event==1){
            __delay_ms(5);
            WriteCmdXLCD(CLEAR_XLCD); //Clear screen
            __delay_ms(5);
            LATBbits.LATB0 = 0; //Turn off RB0 LED, sensor has stopped detecting
            while(PORTAbits.RA11==1){   //Sensor stopped detecting metal
                    XLCDgotoXY(0,0);    //Place cursor
                    putrsXLCD("Alarm 1: Guard Sensor");  //Print text
                    __delay_ms(5);
                    if(PORTAbits.RA11==0){
                        __delay_ms(5);
                        WriteCmdXLCD(CLEAR_XLCD); //Clear screen
                        __delay_ms(5);
                    }
                    while(PORTAbits.RA11==0){  //Sensor detecting metal
                        XLCDgotoXY(0,0);    //Place cursor
                        putrsXLCD("Alarm Ready...");
                        __delay_ms(5);
                        if(RESET_BUTTON==1){
                            goto alarm1clear;
                        }
                    }
            }
        alarm1clear:
            WriteCmdXLCD(CLEAR_XLCD); //Clear screen
            __delay_ms(5);
            INT0_Event = 0;
        }
        
        //Alarm 2 triggered: Wrench sensor
        if(INT1_Event==1){
            __delay_ms(5);
            WriteCmdXLCD(CLEAR_XLCD); //Clear screen
            __delay_ms(5);
            LATBbits.LATB0 = 0; //Turn off RB0 LED, sensor has stopped detecting
            while(PORTDbits.RD8==1){   //Sensor stopped detecting metal
                    XLCDgotoXY(0,0);    //Place cursor
                    putrsXLCD("Alarm 2: Wrench Sensor");  //Print text
                    __delay_ms(5);
                    if(PORTDbits.RD8==0){
                        __delay_ms(5);
                        WriteCmdXLCD(CLEAR_XLCD); //Clear screen
                        __delay_ms(5);
                    }
                    while(PORTDbits.RD8==0){  //Sensor detecting metal
                        XLCDgotoXY(0,0);    //Place cursor
                        putrsXLCD("Alarm Ready...");
                        __delay_ms(5);
                        if(RESET_BUTTON==1){
                            goto alarm2clear;
                        }
                    }
            }
        alarm2clear:
            WriteCmdXLCD(CLEAR_XLCD); //Clear screen
            __delay_ms(5);
            INT1_Event = 0;
        }
        

    }
    return 0;
}

#18
dan1138
Super Member
  • Total Posts : 4157
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/03 10:38:18 (permalink)
0
@rms22,
 
Begin with how to debug code when using the simulator.
 
Set up a watch window that shows the value in the TRISD Special Function Register(SFR), all 16-bits.
 
Starting at the first statement in the main() function and do this:
 
1 - Observer the value of the TRISD register.
2 - Use the debug tool to execute that one line (step over)
3 - Repeat until the TRISD register bit 8 changes to zero.
 
After a Power-On-Reset TRISD bit 8 should be a one.
 
When you observe TRISD bit 8 change from one to zero is the statement that executed caused the change.
 
I expect that statement to be one of the functions you are calling from the XLCD code.
 
Take what ric said in post#17 to heart. He knows what he is talking about.
post edited by dan1138 - 2020/12/03 10:44:48
#19
rmz22
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2020/11/18 15:30:35
  • Location: 0
  • Status: offline
Re: dsPIC30F3014 Simultaneous Interrupts issue 2020/12/03 10:42:56 (permalink)
0
I think I've finally spotted the problem. I checked the header files for the LCD screen in the project and, as it turns out, there's a definition of both TRISD and PORTD as follows:
 

#define DATA_PORT      PORTD
#define TRIS_DATA_PORT TRISD

 
Which, in turn, are manipulated in the xlcd.c file, but since I had only checked the .c source file and there's no explicit mention of TRISD, I had missed this, so ric was right. I guess that's the price I pay for using an external library. I will now attempt to overwrite the TRISDbits.TRISD8 as input in the xlcd.c file without modifying the whole port, if that fails I'll look for a new library (DATA_PORT and TRIS_DATA_PORT appear so many times in the xlcd.c code that I think it'd be more troublesome to attempt to modify it all).
 
Thanks again, ric!
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2021 APG vNext Commercial Version 4.5