'**************************************************************** '* Name : Inverter.BAS * '* Author : Sougata Das * '* Notice : Copyright (c) 2005 The Andig Technologies * '* : All Rights Reserved * '* Date : 30-07-2005 * '* Version : 1.0 * '* Notes : Uses a PIC18F452. Outputs MOSFET DRIVE THROUGH * '* ' HWPM + CD4081 FOR CHANNEL CONTROL. * '* ' LOOKUP TABLE FOR SINE * '* ' INTERRUPT FOR 1)CURRENT LIMIT,2)MOS-DRIVE,3) UPS MODE '* : * '**************************************************************** ' DEFINE OSC 40 'USES A 10MHz CRYSTAL IN x4 PLL MODE FOR 40MHz CLOCK DEFINE USE_LFSR 1 'Makes some code shorter '******************************************************************************* ' Define interrupt handler ' DEFINE INTHAND myint ' ' '********* LCD PORT DEFINITIONS ************************************************ DEFINE LCD_DREG PORTD ' Set LCD Data port PORTD DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus i.e, PortD.0-PORTD.3 DEFINE LCD_RSREG PORTC ' Set LCD Register Select PORTC DEFINE LCD_RSBIT 5 ' Set LCD Register Select bit i.e, PORTC.5 DEFINE LCD_EREG PORTC ' Set LCD Enable port DEFINE LCD_EBIT 4 ' Set LCD Enable bit i.e, PORTC.4 DEFINE LCD_BITS 4 ' Set LCD bus size to 8 bits DEFINE LCD_LINES 2 ' Set number of lines on LCD to 4 Lines DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us DEFINE LCD_DATAUS 50 ' Set data delay time in us 'Variables for saving state in interrupt handler ******************************* wsave VAR BYTE bankA system ' Saves W ssave VAR BYTE bankA system ' Saves STATUS fsave VAR WORD bankA system ' Saves FSR0 '/////////////////////////////////////////////////////////////////////////////// DEAD VAR BIT bankA system ' SET FOR DEAD TIME SETTING CLEARED EVERY ZERO-CROSS TIM0INT VAR BIT bankA system ' TIMER0 INTERRUPT CLEARED WHEN IT OCCURS SYNCOK VAR BIT bankA system ' SET WHEN SYNCHRONIZED TO MAIN AC VAR BIT bankA system ' SET WHEN AC IS AVAILABLE PHASE VAR BIT bankA system ' DRIVE PHASE (DETERMINE WHICH CYCLE) OVERCURRENT VAR BIT bankA system ' SET WHEN AN OVERLOAD INTERRUPT OCCURS ADCINT VAR BIT bankA system ' SET WHEN AD CONVERSION HAS FINISHED (RESET AT INT) INTVAL VAR WORD bankA system ' PWM UPDATE INTERRUPT (ADJUSTED TO LOCK TO AC) INDEX VAR BYTE bankA system ' SINE-TABLE INDEX POINTER PWMVAL VAR BYTE bankA system ' PWMVALUE FOR FIRING TEMP VAR WORD ' TEMPORARY VARIABLE MOS1 VAR PORTC.0 ' MOSFET CHANNEL-1 GATE DRIVE MOS2 VAR PORTC.1 ' MOSFET CHANNEL-2 GATE DRIVE PULSE VAR PORTC.2 ' MODULATING PWM OUTPUT (32KHz, SINE-TABLED) LCDLAMP VAR PORTC.3 ' CONTROLS THE LCD BACKLIGHT - 0=ON,1=OFF RELAY VAR PORTD.4 ' TRANSFER RELAY + INDICATION BUZZER VAR PORTD.5 ' AUDIO ANNUNCIATION FAULT VAR PORTD.6 ' FAULT INDICATION LOCKED VAR PORTD.7 ' SYNC-LOCK TO AC INDICATION OVERLOAD VAR PORTB.0 ' MOSFET OVERLAOD INPUT / IMMEDIATE SHUTDOWN FAIL VAR PORTB.1 ' AC-FAIL INPUT (FROM16F676) SYNC VAR PORTB.2 ' AC-MAINS SYNC INPUT STANDBY VAR PORTB.3 ' STANDBY/OFF SWITCH (INVERTER-MODE) TRICKLE VAR PORTB.4 ' SWITCHES-OFF THE BATTERY CHARGER MENU VAR PORTB.5 ' MENU-BUTTON INCR VAR PORTB.6 ' INCREASE-BUTTON DECR VAR PORTB.7 ' DECREASE-BUTTON TP1 VAR PORTE.0 ' TEST POINT 1 FOR OSCILLOSCOPE CHECK TP2 VAR PORTE.1 ' TEST POINT 2 FOR OSCILLOSCOPE CHECK HEARTBEAT VAR PORTE.2 ' HEART-BEAT LED '******PORT DATA DIRECTIONS **************************************************** LATC = 0 ' CLEAR THE PORTC DATA LATCHES TRISC = %10000000 ' SET PORTC DIRECTIONS PORTC = 0 ' MAKE-SURE THAT THE MOSFETS ARE TURNED-OFF TRISA = %00111111 TRISD = %00000000 ' PORTD DATA DIRECTIONS (ALL OUTPUTS) PORTD = 0 ' TURN-ON BACKLIGHT AND OTHERS OFF TRISB = %11101111 ' SET PORTB DIRECTIONS PORTB.4 = 0 ' TURN-OFF CHARGER TRISE = %00000000 ' PORTE DATA DIRECTIONS (ALL-OUTPUTS) PORTB = 0 ' TURN-OFF HEARTBEAT AND TEST POINTS ADCON0 = %10000000 ' RIGHT JUSTIFY,FOSC/64 ADCON1 = %11000010 ' FOSC/64, PORTE DIGITAL '******************************************************************************* GOTO STARTUP ' SKIP AROUND THE INTERRUPT HANDLER ' ***Assembly language INTERRUPT handler**************************************** Asm myint ; Save the state of critical registers movwf wsave ; Save W swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS) clrf STATUS ; Clear STATUS movwf ssave ; Save swapped STATUS ; Save the FSR value because it gets changed below movf Low FSR0, W ; Move FSR0 lowbyte to W movwf fsave ; Save FSR0 lowbyte movf High FSR0, W ; Move FSR0 highbyte to W movwf fsave+1 ; Save FSR0 highbyte ; CHECK IF OVERLOAD OCCURED i,e., PORTB.0 INTERUPTED (FIRST PRIORITY) btfss INTCON, INT0IF ; CHECK IF OVERLOAD OCCURED GoTo CHECKAC ; TURN-OFF THE GATE DRIVES (PORTC.0&PORTC.1) RETAINING OTHER BITS (PULSE BY PULSE LIMIT) MOVLW 0xFC ; MOVE '11111100 ANDWF PORTC,1 ; ADD W WITH PORTC AND PLACE IN PORTC bcf INTCON, INT0IF ; CLEAR THE HARDWARE INTERRUPT FLAG PORTB.0 bsf OVERCURRENT ; SET THE SOFTWARE OVERLOAD FLAG ; CHECK IF THE AC-FAILED i,e., IF PORTB.1 INTERRUPTED CHECKAC btfss INTCON3, INT1IF ; CHECK IF AC-FAILED OCCURED GoTo AC_SYNC ; IF AC DID NOT FAILED THEN SKIP AND CHECK FOR TIMER0 bsf PORTD, 4 ; TURN-ON THE TRANSFER RELAY bcf INTCON3, INT1IF ; CLEAR THE AC-FAIL INTERRUPT FLAG bcf AC ; CLEAR THE AC FLAG bcf SYNCOK ; CLEAR THE SYNCHRONIZED FLAG bcf INTCON3, INT1IE ; DISABLE FURTHER AC-CHECK INTERRUPTS bcf INTCON3, INT2IE ; DISABLE FURTHER SYNC INTERRUPT ; SYNCHRONIZE THE AC-FREE RUNNING TIMER AC_SYNC btfss INTCON3, INT2IF ; CHECK IF AC-FAILED OCCURED GoTo TIMEKEEP ; IF AC-SYNC DID NOT OCCUR THEN SKIP AND CHECK FOR TIMER0 bcf INTCON3, INT2IF ; CLEAR THE INT2 HARDWARE FLAG MOVLW 0x0 ; MOVE ZERO TO THE WORKING REGISTER MOVWF TMR1H ; RESET TMR1H MOVWF TMR1L ; RESET TMR1L ; CHECK FOR TIMER0 INTERRUPT EVERY 312.5uS TIMEKEEP btfss INTCON, TMR0IF ; TEST IF T0 OVERFLOWED GoTo FINISHED ; SKIP IF SET BTG PORTC, 3 ; TOGGLE THE LCDLAMP FOR SCOPE CHECK MOVLW 0xFC ; MOVE '11111100 ANDWF PORTC,1 ; ADD W WITH PORTC AND PLACE IN PORTC movff INTVAL+1,TMR0H ; MOVE THE HIGH VALUE TO W REG movff INTVAL, TMR0L ; MOVE THE LOW VALUE TO W REG bcf TIM0INT ; CLEAR THE TIM0INT SOFTWARE FLAG bcf INTCON, TMR0IF ; CLEAR THE TIMER0 INT HARDWARE FLAG bcf ADCINT ; CLEAR THE ADC INTERRUPT FLAG incf INDEX, 1 ; INCREMENT INDEX movf INDEX, W ; sublw .32 ; Substract INDEX FROM 32 btfss STATUS,Z GoTo FINISHED ; SKIP PHASE CHANGE (INDEX RESET) clrf INDEX ; CLEAR THE INDEX btg PHASE ; TOGGLE THE PHASE ; Restore FSR, PCLATH, STATUS and W registers FINISHED movf fsave, W ; retrieve FSR0 lowbyte value movwf Low FSR0 ; Restore it to FSR0 lowbyte movf fsave+1, W ; retrieve FSR0 highbyte value movwf High FSR0 ; Restore it to FSR0 highbyte swapf ssave, W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS) movwf STATUS ; Restore it to STATUS swapf wsave, F ; Swap the stored W value swapf wsave, W ; Restore it to W (swap to avoid changing STATUS) retfie ; Return from the interrupt EndAsm '/////////////////////////////////////////////////////////////////////////////// '/////////////////////////////////////////////////////////////////////////////// STARTUP: LCDOUT $FE, 1 :PAUSE 100 ' CLEAR AND INITIALIZE THE LCD LCDOUT "ANDIG INVERTER" ' DISPLAY MESSAGE '***PWM SETUP ////////////////////////////////////////////////////////////////// PR2 = $FF ' SET THE PWM PERIOD TO 255} T2CON = %00000100 ' PRESCALE=1, TIMER2 0N } YIELDS A 39KHz PWM CCPR1L = 0 ' SET THE DUTY CYCLE INITIALLY TO 0 CCP1CON = %00001100 ' CONFIGURE AND START AS PWM '***END OF PWM SETUP /////////////////////////////////////////////////////////// '* TIMER ZERO SETUP///////////////////////////////////////////////////////////// T0CON = %00001000 ' NO-PRESCALE , 16BIT, OFF AT THIS MOMENT TMR0H = $FF ' LOAD THE HIGH BYTE TMR0L = $CA ' LOAD THE LOW BYTE '* END OF TIMER ZERO SETUP////////////////////////////////////////////////////// '** SET UP THE INTERRUPTS/////////////////////////////////////////////////////// INTCON = %00110000 ' TMR0 = 1, INT0 = 1 , PIE = 0, GIE=0 AT THIS MOMENT, INTCON2 = %00000000 ' PULLUP = 1,OVERLOAD=AC-FAIL=SYNC=FALLING EDGE INTCON3 = %00000000 '%00011000 ' INT1=INT2=1, LOW PRIORITY (NOW NOT ENABLED) '** END OF SET UP OF THE INTERRUPTS///////////////////////////////////////////// '** SET UP TIMER1 FOR AC-SYCN COUNTING (FREE-RUNNING) ' THIS VALUE IS ADJUSTED ONLY DURING SYNCHRONIZE PHASE INTCON.7 = 1 ' ENABLE GLOBAL INTERRUPT T0CON.7 = 1 ' START TIMER 0 FIRE: TEMP = TMR0L ' NEEDED FOR THE SIMULATOR TO UPDATE TMR0H IF TIM0INT = 0 THEN ' IF A FRESH FIRING IS NEEDED THEN TIM0INT = 1 ' SET THE SOFTWARE INT FIRING FLAG LOOKUP INDEX, [0,25,50,74,98,120,142,162,180,197,212,_ ' GET THE PWMVALUE 225,235,244,250,254,255,254,250,244,235,_ 225,212,197,180,162,142,120,98,74,50,25],PWMVAL CCPR1L = PWMVAL ' LOAD THE PWMVAL TO THE HWPWM IF PHASE = 0 THEN ' FIRE THE MOSFETS ACCORDING TO THE PHASE VALUE MOS1 = TIM0INT ' FIRE USING SAFETY LOGIC ELSE ' EITHER CHANNEL 1 OR CHANNEL 2 (DEPENDS ON PHASE) MOS2 = TIM0INT ' FIRING USING SAFETY LOGIC ENDIF ENDIF GOTO FIRE