rmz22
New Member
- Total Posts : 20
- Reward points : 0
- Joined: 2020/11/18 15:30:35
- Location: 0
- Status: offline
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
|
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)
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..
|
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
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.
|
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)
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
|
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)
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
|
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
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.
To get a useful answer, always state which PIC you are using!
|
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)
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.
|
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)
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
|
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)
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
|
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
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.
To get a useful answer, always state which PIC you are using!
|
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)
Understood, thank you both!
|
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
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.
|
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
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
|
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)
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
|
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)
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?
|
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)
|
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
The most likely explanation is that a part of the code you are not showing us is setting TRISDbits.TRISD8 back to 0.
To get a useful answer, always state which PIC you are using!
|
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)
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; }
|
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)
@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
|
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)
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!
|