Hi everyone,

I've a very weird problem with my program. Here is the source code:

Code:
' Varidrive "Lite" firmware V2011.00 by DR Electronics
' PIC initialization
DEFINE OSC 40      
DEFINE LCD_DREG PORTD
DEFINE LCD_EREG PORTB
DEFINE LCD_RSREG PORTB
DEFINE LCD_EBIT 6
DEFINE LCD_RSBIT 7
DEFINE ADC_BITS 10
DEFINE HSER_RCSTA 90h 
DEFINE HSER_TXSTA 24h 
DEFINE HSER_BAUD 19200
DEFINE HSER_SPBRG 129




' BAS includes
INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"
INCLUDE "Sine_table.bas"




' ADC registers configuration
ADCON0=%11101
ADCON1=%10000    
ADCON2=%10000110
ADCON3=%10000  
ANSEL0=%00001111
ANSEL1=%0




' PCPWM registers configuration
PTCON0=%10        
PTCON1=%10000000  
PWMCON1=%1
DTCON=%11




' Inverter variables
ustep var BYTE
vstep var BYTE
wstep var BYTE
uduty var WORD
vduty var WORD
wduty var WORD
freq VAR WORD
amp var WORD
copy VAR WORD
rld VAR WORD
stor var word
dum VAR WORD
dum1 VAR WORD
dum2 VAR WORD
bl var BIT
flag var BIT
flag1 VAR BIT
flag2 VAR BIT
flag3 var BIT
flag4 var BIT
flag5 var BIT
flag6 var BIT
flag7 var BIT
flag8 var bit
flag9 var bit
a var BYTE
b var BYTE
c var word
d var word
e var bit
f var bit
run VAR BIT
rot var BIT
menu var BIT
mpos VAR BYTE
isense VAR WORD
usense VAR WORD
tsense VAR WORD
psense var WORD
idisp var BYTE
udisp var WORD
tdisp var BYTE
maxf var WORD
minf var WORD
imax var BYTE
pwmf var BYTE
res var BYTE
flt var BYTE
lastf var BYTE




' Default variables definition
dum1=5600   
dum2=100      
mpos=1
a=0
b=0
flag=%1
flag3=%1        
run=%0           
flt=%0
      


' Reading EEPROM
read 0,rot              
read 1,maxf.HIGHBYTE  
read 2,maxf.LOWBYTE    
read 3,minf.HIGHBYTE  
read 4,minf.LOWBYTE    
read 5,imax              
read 6,pwmf            
read 7,bl
read 8,lastf              




' Initial GOSUBs
GOSUB pwmsub
GOSUB blsub 




' Inverter startup
pause 1000
HIGH PORTD.5
Hserout ["Varidrive V2011.00|19200 8n1|Maxfreq:",DEC4 maxf,"|Minfreq:",dec4 minf,"|Itrip:",dec3 imax,"|PWMfreq:",dec1 pwmf,"|Backlight:",dec1 bl,"|Lastfault:",dec1 lastf]  




' Turn LCD on and write custom characters to CGRAM
LCDOUT $fe,$40,$0,$4,$e,$15,$4,$4,$4,$0
LCDOUT $fe,$48,$0,$4,$4,$4,$15,$e,$4,$0
LCDOUT $fe,1 




' Create interrupt processors 
ASM
INT_LIST MACRO  
         INT_Handler TMR1_INT,_pwmint,PBP,yes
         INT_Handler INT0_INT,_ocint,PBP,yes    
         INT_Handler INT2_INT,_stopint,PBP,yes
         ENDM
         INT_CREATE
ENDASM




' Interrupts and timer enable
@ INT_ENABLE TMR1_INT
@ INT_ENABLE INT0_INT
@ INT_ENABLE INT2_INT
T1CON=%10001




' Main program loop
lp:


' Start ADC conversion
ADCON0.1=%1       
WHILE ADCON0.1=%1:WEND


' Store ADC results   
isense.HIGHBYTE=ADRESH 
isense.LOWBYTE=ADRESL
usense.HIGHBYTE=ADRESH 
usense.LOWBYTE=ADRESL
tsense.HIGHBYTE=ADRESH 
tsense.LOWBYTE=ADRESL
psense.HIGHBYTE=ADRESH 
psense.LOWBYTE=ADRESL 


' Security fault verifications
IF isense**40000>imax THEN flt=1
IF usense>880 THEN flt=2
IF tsense>880 THEN flt=3


' Security fault tripping
IF flt>0 THEN GOTO fltsub


' Brake/surge resistor control
IF usense>800 then
   if run=%1 then high PORTD.7
else
    LOW PORTD.7
endif
                                                                                                      
' Frequency reference control by potentiometer
psense=((psense<<6)**maxf)+10
IF psense<>freq+10 THEN freq=psense:flag=%1


' Frequency limits
IF freq<minf THEN freq=minf
IF freq>maxf THEN freq=maxf


' Recalculations
IF flag=%1 THEN


   ' Reload timer calculation
   dum=dum1*dum2
   stor=DIV32 freq
   rld=(65535-stor)+8


   ' U/F calculation
   IF freq<=500 THEN
      amp=(freq*131)+35
   ELSE
       amp=65535
   ENDIF


  flag=%0
ENDIF


' Run
IF run=%1 THEN 
   IF flag1=%0 THEN PWMCON0.6=%1:HIGH PORTD.6:flag1=%1
ENDIF


' Stop
IF run=%0 THEN
   IF flag1=%0 THEN PWMCON0=%0:LOW PORTD.6:flag1=%1
ENDIF


' FWD rotation
IF rot=%1 THEN
   IF flag2=%0 THEN ustep=89:vstep=59:wstep=29:write 0,rot:flag2=%1
ENDIF


' RWD rotation
IF rot=%0 THEN
   IF flag2=%0 THEN ustep=29:vstep=59:wstep=89:write 0,rot:flag2=%1
ENDIF


' - button
IF PORTE.0=%1 then
   if flag8=%0 then
      IF menu=%0 THEN mpos=mpos-1:d=1200:E=%0:F=%0
   ENDIF
   flag8=%1
endif


' + button
IF PORTE.1=%1 then
   if flag9=%0 then
      IF menu=%0 THEN mpos=mpos+1:d=1200:E=%0:F=%0
   endif
   flag9=%1
endif


' Run/stop button
IF PORTC.0=%1 THEN
   IF run=%0 AND mpos<6 AND flag3=%0 THEN run=%1:flag1=%0:flag3=%1:f=%0
   IF run=%1 AND flag3=%0 THEN run=%0:flag1=%0:flag3=%1:f=%0
ENDIF


' FWD/RWD button
IF PORTC.1=%1 THEN
   IF rot=%0 AND run=%0 AND flag4=%0 THEN rot=%1:flag2=%0:flag4=%1
   IF rot=%1 AND run=%0 AND flag4=%0 THEN rot=%0:flag2=%0:flag4=%1
ENDIF


' Menu/OK button
IF PORTC.2=%1 THEN
   IF menu=%0 AND run=%0 AND mpos>5 AND flag5=%0 THEN menu=%1:flag5=%1
   IF menu=%1 AND flag5=%0 THEN menu=%0:flag5=%1
ENDIF


' Buttons released state
IF PORTC.0=%0 THEN flag3=%0
IF PORTC.1=%0 THEN flag4=%0
IF PORTC.2=%0 THEN flag5=%0
IF PORTE.0=%0 THEN flag8=%0
IF PORTE.1=%0 THEN flag9=%0


' LCD first line writing
c=c+1
if c>800 then
   IF rot=%1 THEN LCDOUT $fe,$2,"+" 
   IF rot=%0 THEN LCDOUT $fe,$2,"-"
   LCDOUT DEC freq DIG 3,DEC freq DIG 2,DEC freq DIG 1,".",DEC freq DIG 0,"Hz"
   IF run=%1 THEN LCDOUT REP 32\5,"RUN"
   IF run=%0 THEN LCDOUT REP 32\4,"STOP"
   c=0
endif


' Inverter menu (LCD second line writing)
SELECT CASE mpos


' Menu limits
IF mpos<1 THEN mpos=1
IF mpos>11 THEN mpos=11
IF run=%1 THEN
   IF mpos>5 THEN mpos=5
ENDIF


' Current sensing submenu
CASE 1
d=d+1
if d>1200 then
   idisp=isense**40000
   lcdout $fe,$c0,$1,$20,"1 ISENS: ",DEC idisp DIG 2,DEC idisp DIG 1,".",DEC idisp DIG 0,"A"
   d=0
endif


' Voltage sensing submenu
CASE 2
d=d+1
if d>1200 then
   udisp=usense**29600
   lcdout $fe,$c0,$1,$0,"2 USENS: ",DEC3 udisp,"V",32
   d=0
endif


' Temperature sensing submenu
CASE 3
d=d+1
if d>1200 then
     tdisp=(tsense-280)/8
     lcdout $fe,$c0,$1,$0,"3 TEMP: ",DEC tdisp DIG 1,DEC tdisp DIG 0,$df,"C",REP $20\2
     d=0
endif


' Last fault reading submenu
CASE 4
if e=%0 then
   lcdout $fe,$c0,$1,$0,"4 LASTFAULT: ",DEC1 lastf
   e=%1
endif


' Firmware version reading submenu
CASE 5
IF f=%0 then
      lcdout $fe,$c0,$1,$20,"5 FW: V2011.00"
      f=%1
ENDIF


END SELECT


GOTO lp




' PWM update interrupt (timer 1) 
pwmint:


' Timer management
T1CON.0=%0                          
copy.HIGHBYTE=TMR1H                
copy.LOWBYTE=TMR1L 
copy=copy+rld 
TMR1H=copy.HIGHBYTE                
TMR1L=copy.LOWBYTE
T1CON.0=%1  
                               
' PWM U phase calculation
uduty=sine[ustep]
uduty=(uduty<<res)**amp


' PWM V phase calculation
vduty=sine[vstep]
vduty=(vduty<<res)**amp


' PWM W phase calculation
wduty=sine[wstep]
wduty=(wduty<<res)**amp


' PWM U, V and W update
PDC0H=uduty.HIGHBYTE
PDC0L=uduty.LOWBYTE
PDC1H=vduty.HIGHBYTE
PDC1L=vduty.LOWBYTE
PDC2H=wduty.HIGHBYTE
PDC2L=wduty.LOWBYTE


' Phase angle calculation
@ decf _ustep,1
@ decf _vstep,1
@ decf _wstep,1


' Phase angle reinitialization
IF ustep=0 THEN ustep=89
IF vstep=0 THEN vstep=89
IF wstep=0 THEN wstep=89


@ INT_RETURN




' PWM carrier frequency configuration subroutine
pwmsub:
 
IF pwmf=1 THEN PTPERH=$f:PTPERL=$ff:res=6
IF pwmf=2 THEN PTPERH=$7:PTPERL=$ff:res=5
IF pwmf=3 THEN PTPERH=$3:PTPERL=$ff:res=4
IF pwmf=4 THEN PTPERH=$1:PTPERL=$ff:res=3


RETURN




' LCD backlight subroutine
blsub:
 
if BL=%1 then
    HIGH PORTD.4
ELSE
    low PORTD.4
ENDIF


RETURN




' Over current interrupt
ocint:


flt=4
GOTO fltsub


@ INT_RETURN




' Emergency stop interrupt
stopint:


flt=5
GOTO fltsub


@ INT_RETURN




' Inverter fault subroutine
fltsub:


' Emergency stop of the inverter
PWMCON0=%0
T1CON.0=%0
LOW PORTD.5
LOW PORTD.6
LOW PORTD.7


' Disable interrupts
@ INT_DISABLE TMR1_INT
@ INT_DISABLE INT0_INT
@ INT_DISABLE INT2_INT


' Fault information
lcdout $fe,$1
lcdout $fe,$2,"FAULT!",REP $20\10
lcdout $fe,$c0,"CODE: ",DEC flt,REP $20\9
Hserout ["Fault|Code:",DEC1 flt]
write 8,flt 


' Fault LED ON
HIGH PORTE.2
end
This program control a 3-phase AC motor inverter. On my control board I got a HD44780 LCD and buttons, so I can navigate between menus when my motor is running or not. With that I can monitor DC bus current, DC bus voltage, IGBT module temperature, etc. Very useful. All of these things are working right.

But sometimes when I navigate into this menu (when the AC motor is either on or off), and very randomly, the LCD is "freezing" and after 2 seconds the display is reseted. The 3-phase PWM outputs are not affected at all.

Now, if I remove only the interrupts (TMR1_INT, INT0, INT2) of my program, this problem doesn't occur.

So what's the problem?