LCD freezing problem with interrupts


Closed Thread
Results 1 to 10 of 10
  1. #1

    Question LCD freezing problem with interrupts

    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?

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    EDIT

    Corrected program part:

    Code:
    ' Menu limits
    IF mpos<1 THEN mpos=1
    IF mpos>5 THEN mpos=5
    Still doesn't works.

  3. #3


    Did you find this post helpful? Yes | No

    Exclamation Re: LCD freezing problem with interrupts

    Nothing? I've also tried to remove serial commands and CGRAM custom-made characters, same problem.

  4. #4
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    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.
    Do you get the fault indication? I suspect, you are getting into the FltSub when you say the LCD is frozen.

    You can possibly disable the ocint and the stopint for checking this possibility. Does the LCD still freeze?

  5. #5
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    OSC is defined as 40Mhz, where is the config settings?
    which pic is this?
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    Completely unrelated to your problem, or perhaps not but anyway.....
    Does these constructs really work? Do they even compile:
    Code:
    ' 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

    I think you need an ENDIF for each of those IF statements.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    Quote Originally Posted by Jerson View Post
    Do you get the fault indication? I suspect, you are getting into the FltSub when you say the LCD is frozen.

    You can possibly disable the ocint and the stopint for checking this possibility. Does the LCD still freeze?
    Actually I'm not at home so I will try to remove ocint and stopint next friday.

    And no, I'm not getting into Fltsub when my LCD is frozen: in reality, the menu is reseted to the very first position (1: ISENS).

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    Quote Originally Posted by HenrikOlsson View Post
    Completely unrelated to your problem, or perhaps not but anyway.....
    Does these constructs really work? Do they even compile:
    Code:
    ' 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

    I think you need an ENDIF for each of those IF statements.
    I've no problems with that (but I've modified this part to something like that):

    if rot=%0 then
    if run=%0 then
    if flag4=%0 then
    rot=%1
    flag2=%0
    flag4=%1
    endif
    endif
    endif

    Yeah, not very readable but take less program space than AND operator. And it works good.

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    Quote Originally Posted by sayzer View Post
    OSC is defined as 40Mhz, where is the config settings?
    which pic is this?
    A special PIC for motor control, it's the PIC18F4431, 10MHz quartz with PLL enabled (so 4*10=40MHz).

  10. #10
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default Re: LCD freezing problem with interrupts

    So, while LCDOUT command is being executed, an interrupt is occuring.

    To "test" this, you can disable all interrupts before lcdout command and enable them right after.
    This is just to see.
    But this will definitely effect your motor. It can give you a point anyway.
    Last edited by sayzer; - 6th December 2011 at 22:37.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts