Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Hi T,It sounds like you're beginning to get it.
Interrupts are asynchronous events that can occur at any time. When you get an interrupt, you stop executing the main loop of your program and it branches to the interrupt handler code. When that's done you return to the main loop right where you left off.
This can occur right in the middle of some main loop statement, so it can change the timing of things in your main loop. It's also why you have to watch out for things like accessing the same hardware in the main loop and interrupt code (such as an SPI or I2C transaction), shared variables, or timing-related code like a software UART.
Trying to simulate something like that usually doesn't work very well, so a sim is pretty much useless in most situations once you have interrupts involved.
I'm using most of the above, except I2C. As for shared variables, my mate has tidied the CODE up with PROCEDURES, INCLUDES and FUNCTIONS, but sometimes, to his horror, I have to put them back in line, and use my own individual variables, just so that I can read it.It's also why you have to watch out for things like accessing the same hardware in the main loop and interrupt code (such as an SPI or I2C transaction), shared variables, or timing-related code like a software UART.
On High Interrupt
Save System
'OVERRUN ERROR
If PIE1.RCIE = 1 Then 'EUSART Receive Interrupt Enable bit
If RCSTA.OERR = 1 Then
Gosub irqinitbuf 're-init buffer, discard bad sentence
Goto RXIRQdone 'done, wait for next character
Endif 'OERR
'FRAMING ERROR
If RCSTA.FERR = 1 Then
dumpchar = RCREG 'Read char to clear RCIF and FERR
Gosub irqinitbuf 'Re-init buffer, discard bad sentence
Goto RXIRQdone 'wait for next
Endif 'FERR
'No UART errors, process character
If PIR1.RCIF = 1 Then
RXIRQchar = RCREG 'read the received char, clears RCIF
'Look for $, start/restart filling buf when found
If RXIRQchar = "$" Then 'Start (re)filling buf on any $
Gosub irqinitbuf 'init buffer, index and flags@
gnrmc_buf(gnrmcpsn) = RXIRQchar 'store $ $ ADDED instead of RXIRQchar, because no $ was being stored
gnrmc_buf_filling = 1 'start storing the sentence
Goto RXIRQdone 'done with this character
Endif 'char was $
'no UART errors and character was not $
'If $ was found previously, process character looking for W and no buffer overflow.
'If haven't found $ yet, just ignore character.
If gnrmc_buf_filling = 1 Then 'if filling buffer, see if there is room in buf
Break '<<<<<<<<<<<,
If gnrmcpsn >= (rxbufsize - 1) Then 'last char was at end of buf - buffer overflow so..
Gosub irqinitbuf 'restart buffer, discard sentence
RXerr = 1 'let main know that the buffer overflowed and is restarting
Goto RXIRQdone 'done, resume looking for next $
Endif 'buffer overflow
gnrmcpsn = gnrmcpsn + 1 'else, there's room in buf so bump index and store character, might be W
gnrmc_buf(gnrmcpsn) = RXIRQchar
If RXIRQchar = "W" Then 'if end of sentence..
RCSTA.CREN = 0 'shut down UART
PIE1.RCIE = 0 'Enable off
gnrmc_buf_filling = 0
gnrmc_buf_full = 1
Goto RXIRQdone 'and bye!
Endif 'RXIRQchar was W
Endif 'If gnrmc_buf_filling = 1
Endif 'RCIF=1
Endif 'RCIE=1
'Exit point for each RXinterrupt. Process timers
RXIRQdone:
Resume
Hi D,The project is too extensive and the forum, not being in my language, makes it difficult for me to help with such extensive projects. What I can tell you when talking about my professional projects is that I always leave the pins involved in the ICSP free to use them later for debugging and I even usually leave an RS232 TTL port also for the same thing. In this way you can send information from several cards or even from several microcontrollers on the same card with certain information as appropriate for the developer and therefore to facilitate debugging.
Hi D,It's quite challenging to explain a method. After nearly 20 years of developing and manufacturing microcontroller-based automation systems, I've created a sort of 'mini operating system.' Everything is based on interrupts and the distribution of time across functions. For example, if there's a function waiting for data, you must always include an exit route in case the data doesn't arrive. The programming and debugging methods are skills that come with experience and are also very personal. My programs aren't entirely linear; they are based on distributing time among functions as much as possible. Anyway, the concept of a program being 'blocked' is quite relative. It might just be that a module of the microcontroller got stuck for some reason, but that doesn’t mean it stopped working entirely. It was just that a function or part of the code was waiting for something, and if the code is too linear, everything else stops functioning.
Hi D,For instance, I once wrote an article for an electronics magazine about the 555 timer. In the article, I stated, 'The 555 is an integrated circuit that could fill an entire book on its own.' The editors of the publication added in parentheses, '(In fact, such a book has already been written).' The same can be said for the various methods and approaches to debugging software; the methodology is truly extensive. Just as the 555 timer has inspired numerous discussions and publications due to its versatility and broad application in electronics, debugging techniques in programming are vast and diverse. Each strategy can be deeply explored, reflecting the complexity and nuances of software development. These methods evolve with technology, continuously requiring new literature and expert insights to address emerging challenges in the field.