Near Disaster with Interrupt Handling ISRRX
Posted: Mon Sep 12, 2016 4:52 am
I designed a great battery test system using PIC18F87K22 driving Power Op Amps, capable of charge, discharge up to 12V 1A of battery under test. After the long development of that I then added the last part, the RS485 link that was meant to monitor and control it (many of them in fact) from a distance.
At that point I found that no matter how I tried to rearrange the interrupt call (ISRRX.bas and OnData() as per example in manual), which was doing simple string concatenation to determine a command, it would randomly crash the ADC part of the battery loop. I tried every kind of save/restore I could think of. Then I read Davids comment "dont use interrupt function for very much" but it was too late. In the end I rewrote the entire software and the host PC software using polling and no interrupt function at all.
I traced the problem to my GetVolts function where I combine ADRESH and and ADRESL from the PIC ADC, then scale into a floating point number.
If the interrupt is not called this function returns the processed ADC reading into GetVolts reliably for hours, if the interrupt is called I get occasional random values in the ADCReading (word). I had same problem with a device reading NEMA data at 4800BD using ISRRX and Ondata(). My boat navigation system randomly crashed due to the interrupt occasionally reading the incoming NMEA data and solved it them same way, I went to polling and no interrupt.
The interrupt is a really good valuable feature, is there an easy way to guarantee it can be used without crashing the loop its interrupting? Maybe a list of every single register to save, even if its a long list!?
Advice appreciated!
At that point I found that no matter how I tried to rearrange the interrupt call (ISRRX.bas and OnData() as per example in manual), which was doing simple string concatenation to determine a command, it would randomly crash the ADC part of the battery loop. I tried every kind of save/restore I could think of. Then I read Davids comment "dont use interrupt function for very much" but it was too late. In the end I rewrote the entire software and the host PC software using polling and no interrupt function at all.
I traced the problem to my GetVolts function where I combine ADRESH and and ADRESL from the PIC ADC, then scale into a floating point number.
Code: Select all
ADCReading = ADRESH << 8
ADCReading = ADCReading Or ADRESL
GetVolts = (ADCReading*gain) + zero
The interrupt is a really good valuable feature, is there an easy way to guarantee it can be used without crashing the loop its interrupting? Maybe a list of every single register to save, even if its a long list!?
Advice appreciated!