Divide by Zero Error or Overflow in Math Code with PIC18 MCU(solved) - Page 1
Forum section: electronics / general

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 13, 2015, 10:04:27 pm
content: The Answer: nada..no problema, my bad, was actually an interrupt dependent delay problem.What would be the effect of a divide by zero error or overflow/underflow of a floating point or normal calculation in C-code using the math functions available( but this not about an array index overflow problem, I know that can crash a MCU.)?The result of the calculation would no doubt be in error, but would the MCU crash?Something like below which is an insane mix of char, unsigned and signed int, float and long float vars. The other routines called have been tested and were added just to spice up the pi. Math() is a test, not a routine that finds the mass of black hole. The whole banana compiles without error. BlinkaLed() has been tested to blink a LED, not the problem, it uses only it's own private vars.#include<Math.h>#include <htc.h>#include <string.h>#include <stdio.h>#include <P18F25K22.h>//not included here are the var declarations, function prototypes, CONFIG(all defaults except BOREN, WDT are both disabled) stuff, etc,. which has already been tested and works//There are no interrupt routines, no interrupts have been enabled, no functions, nor structures and only two pointers are used to point to a char array to work with a display routine in this program.Main(){TRISIC=0;TRISCB=0;TRISC=0; //PORTs used to blink the LEDStart:BlinkaLed();Math();goto Start;}void Math(void){Kp=Ki*(Kp*(Kd*1560)/Kd);Kp=Kp*DispMode/ttemp;if(Kp>Kd+Mode){ Ki=Ki*Kp/.020404295492;Kp=Kp*3.1428159;Terr=Kp*Ki*Kd+14;}if( (Kp/5829)>Ki/Kp){ Kp=DispMode;Ki=TensMode;Kd=IsSlow;}if(TachUpdate>Ki){ Kd=Kd*IsSlow/Ki;Terr=Kd;Ki=Kp/TensMode;Kd=Kp/Ki/Kp+4;Terr=Kd;Mode=Ki;Ki=50920230929+Kd/52002.23299;Kp=Ki*Ki/.002523;if(Ki>Kp/Kd) Terr=Kd;ttemp=40+ttemp*Kp-Ki*Ki/.002523;Terr=Kp-Terr+Ki+Kd;Kp=Kd-50920230929+Kd/52002.23299;Kp=0;Px=Kp/Ki*Kd;if(Px>0) Terr=Kd-50920230929+Kd/5200;if(Terr>Ki/12+Ki/Perr) Kp=Ki*Kp;}if(Kd+Terr/Ki/Perr+2>.090920){ Kp=Ki/12+(Ki/Perr);Kp=Ki*Kp*4;}if(Kd<Terr)TachUpdate=2;ttemp=Ki*5e09+Kd/52002.23299;}OMG ..the LED doesn't blink anymore! (but there could have been a programming code into the MCU problem.)

author: oPossum
author_rank: Super Contributor
timestamp: June 14, 2015, 12:03:12 am
content: Quote from: SuzyC on June 13, 2015, 10:04:27 pmNaNNot a Numberhttps://en.wikipedia.org/?title=NaN

author: Dragon88
author_rank: Regular Contributor
timestamp: June 14, 2015, 12:44:58 am
content: I made a PIC based 4 banger calculator in assembly one time for fun. I wrote the code a section at a time and tested along the way, and always tried out divide by zero before I had code to prevent it. I think the PIC was doing this internally when it happened ->.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 14, 2015, 12:51:51 am
content: But would a PIC MCU lock up, crash, go zombie town?

author: hamster_nz
author_rank: Super Contributor
timestamp: June 14, 2015, 02:10:27 am
content: Why not just try it and see what happens!At least for integers on PIC it raises an interrupt - accordind to documentation I found on the web. For floating point it may do the same, or just return a NaN (not a number) depending on runtime library and setting. Given the fact that your code has no loops I would guess an interrupt has been raised.But as a more general question , why make the code you post as an example so complicated, and then leave the bits out that are of great importance (e.g. your variable declarations)?Nobody else has any idea of the variable types and values, so can't really offer any detailed advice or recreate the problem themselves without guessing.....Why not replace math() with what you really want to test....

author: Dragon88
author_rank: Regular Contributor
timestamp: June 14, 2015, 02:19:07 am
content: Quote from: SuzyC on June 14, 2015, 12:51:51 amIn my case it locked up solid. But I was programming a 16F series device in assembly, so I didn't have the protection of more modern C libraries until I wrote it in myself.

author: miguelvp
author_rank: Super Contributor
timestamp: June 14, 2015, 02:35:53 am
content: I didn't look in depth but as I recall the PIC18 doesn't even have an integer divide opcode or native floating point for that matter, so it's all software independent and I doubt the library implementation will halt the processor, maybe it does, but the source code should be available somewhere to see what it does. It should return a Nan at least,or maybe even throw an exception but it would be done by code.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 15, 2015, 02:17:01 pm
content: I know it compiles OK, like with many other false promises, Hi-Tech PRO 9.80. OK, it's not perfect, lotsa warnings about implicit conversions between var types, but hey, it's primary operation in the first few lines of a small loop in Main() is to blink a LED. Should be not so hard for one to blink at any pin, PORTA, PORTB,PORTC are TRIS'd to 0, so every I/O pin should flirt with a LED, they are all set to dance together, en mass.I would appreciate if anyone has a second or two and a vacationing PIC18Fx5X22 just waiting for a challenge, to burn the attached masterpiece all served up in one Intel .hex file, just to see if'n it will blink.Note: Operation is with Vdd =5.0V, but that doesn't matter. No BOREN to bother with, no doggy WDT to bite your bits.The crystal is an external 20MHz jewel of metal and quartz and I can see with my scope's eyes that its singing like a canary.Yet there is light side to this story, the LED doth go on without a blink.Yes, this .hex is inspired by The Simpsons.