;********************************************************** ;* firebee1 PIC18F4321 MAIN FILE ;********************************************************** ;* CREATED BY FREDI ASCHWANDEN ;* DATE 22.9.2009 ;********************************************************** list PE=18f4520 ;EXTENDED INSTRUCTION SET include "P18f4520.inc" ;------------------------ Equates --------------------------; ;Register addresses ;BANK 0 SECS equ 0x00 SECS_ALARM EQU 0x01 MINS equ 0x02 MINS_ALRAM EQU 0x03 HOURS equ 0x04 HOURS_ALARM EQU 0x05 DAY_OF_WEEK EQU 0x06 DAYS EQU 0x07 MONTHS EQU 0x08 YEARS EQU 0x09 ;offset vom 1968 REGA EQU 0x0A REGB EQU 0x0B REGC EQU 0x0C REGD EQU 0x0D RTC_RAM EQU 0x0E ; bis 0x3F free equ 0x40 TICKS equ 0x41 ;125MS TASTE_ON_TIME EQU 0x42 TASTE_OFF_TIME EQU 0x43 POWER_ON_TIME EQU 0x44 AD_KANAL EQU 0x45 U_ERR EQU 0x46 ;SPANNUNGSFEHLER WENN BIT 0=1, BIT1=1 WARTEN AUF GELADEN U_ERR_TIME EQU 0x47 ;ZEIT SEIT SPANNUNGSFEHLER U_POWER_IN EQU 0x48 ;SPANNUNG POWER IN 1V CA. 6E RX_B EQU 0x49 ;RECEIVED BYT RX_STATUS EQU 0x4A ;STATUS: 0x00=WAIT AUF MCF COMMANDO, 0x82=EMPFANGE 64BYT FROM RTC TX_STATUS EQU 0x4B ;STATUS: 0x00=WAIT 0x81=SENDE 64BYT FROM RTC GO_SUB EQU 0x4C ;WENN GLEICH 0xFB DANN SUBROUTINE AUSFÜHREN GO_INT EQU 0x4D ;WENN GLEICH 0xFB DANN SUBROUTINE AUSFÜHREN EAPIR1 EQU 0x4E ;INTERRUPT ACTIV UND ENABLE EAPIR2 EQU 0x4F ;INTERRUPT ACTIV UND ENABLE ;BANK 1 AB 0x100 RX_BUFFER EQU 0x100 ;0x80 BYT BUFFER BIS 0x17F BANK TX_BUFFER EQU 0x180 ;0X80 BYT BUFFER BIS 0x1FF BANK ;-------------------------------------------------------------- SEND_RTC_TIME EQU .2 ;0.25 SEC (EINHEIT IST EIN TICK = 128MS RESET_ON_TIME EQU .2 ;0.25 SEC (EINHEIT IST EIN TICK = 128MS RESET_OFF_TIME EQU .4 ;0.5 SEC (EINHEIT IST EIN TICK = 128MS OFF_TIME EQU .20 ;2.5 SEC (EINHEIT IST EIN TICK = 128MS ON_TIME EQU .2 ;0.25 SEC (EINHEIT IST EIN TICK = 128MS TIMER_HB EQU .240 ;256- (32768Hz PRO 1/8SEC = 4096TICKS/256) => 256-16=240 (resp 256-16/4 (wenn osco) = 252) TIME_MAX EQU .160 ;MAXIMALTIME U_ERR_PW_AUS EQU .5 ;5 SEC ;SERIEL SYNC1 EQU 0FFh SYNC1_DATA EQU 'A'; SYNC2 EQU 0FEh SYNC2_DATA EQU 'C'; SYNC3 EQU 0FDh SYNC3_DATA EQU 'P'; SYNC4 EQU 0FCh SYNC4_DATA EQU 'F'; REQ_RTCD_FROM_PIC EQU 01h ;RTC AND NVRAM DATEN VOM PIC ANFORDERN RTCD_FROM_PIC EQU 81h ;RTC AND NVRAM DATEN HEADER UND STATUS REQ_RTCD_FROM_MCF EQU 02h ;RTC AND NVRAM DATEN VOM MCF ANFORDERN RTCD_FROM_MCF EQU 82h ;RTC AND NVRAM DATEN HEADER UND STATUS U_MIN_TO_MCF EQU 03h ;UNTERSPANNUNGSMITTEILUNG AN PROCESSOR EXT_SUB_GO EQU 04h ;SERIELL CODE UM SUBROUTINEN/INTERRUPTS ZU AKTIVIEREN EXT_SUB_STOP EQU 05h ;SERIELL CODE UM SUBROUTINEN/INTERRUPTS ZU STOPPEN CLK_SLEEP EQU B'00010010' ;125kHz intern, SLEEP MODE CLK_ACTIV EQU B'01110010' ;inTernal CLK=8MHz, SLEEP MODE, SLEEP MODE EXT_CODE EQU 0xFB ;CODE FÜR EXTERNE SUBROUTINEN/INTERRUPTS AUSFÜHREN (FireBee!) EXTERN_INT_ADR EQU 0x2000 ;HIER MUSS 0xFB STEHEN WENN EXTERNE INTERRUPTS AUSFÜHRBAR EXTERN_INTERRUPTS EQU 0x2002 ;STARTPUNKT EXTERNE SUBROUTINES EXTERN_SUB_ADR EQU 0x2010 ;HIER MUSS 0xFB STEHEN WENN EXTERNE SUBROUTINES AUSFÜHRBAR EXTERN_SUBROUTINES EQU 0x2012 ;STARTPUNKT EXTERNE SUBROUTINES REQ_BLOCK EQU 0xA0 ;BLOCK DATEN LESEN -> CODE UND 3 BYTS ADRESSE = TOTAL 4 BYTES READ_BLOCK EQU 0xA1 ;PROGRAMM BLOCK PIC->MCF -> CODE, 3 BYTS ADRESSE UND 64 BYTS DATEN = TOTAL 68 BYTES WRITE_BLOCK EQU 0xA2 ;PROGRAMM BLOCK MCF->PIC -> CODE, 3 BYTS ADRESSE UND 64 BYTS DATEN = TOTAL 68 BYTES PRG_OK_PIC EQU 0x22 ;PROGRAMMIERUNG BLOCK FERTIG ;**********************************************************************************************""""""""""""" ; Start at the reset vector Reset_Vector code 0x000 BRA KALT_START ;-------------------------------------------------------------- HIGH_INT_VEC code 0x0008 GOTO 0x18 LOW_INT_VEC code 0x0018 INT_HANDLER CLRF BSR ;IMMER ACCESS BANK ;SETZEN GRUPPE 1 MOVFF PIE1,EAPIR1 ;INTERRUPTS HOLEN MOVF PIR1,0 ;MASKE ANDWF EAPIR1 ;ACTIVE SETZEN BTFSC EAPIR1,TMR1IF ;uhr interrupt? BRA RTC_ISR ;ja-> BTFSC EAPIR1,ADIF ;AD INTERRUTP? BRA AD_ISR ;JA-> BTFSC EAPIR1,TXIF ;seriell TX? BRA TX_ISR ;JA-> BTFSC EAPIR1,RCIF ;seriell RX? BRA RX_ISR ;JA-> ;SETZEN GRUPPE 2 MOVFF PIE2,EAPIR2 ;INTERRUPTS HOLEN MOVF PIR2,0 ;MASKE ANDWF EAPIR2 ;ACTIVE SETZEN BTFSC EAPIR2,HLVDIF ;UNDER/OVERVOLTAGE DETECT BRA HLVD_ISR ;JA-> RETFIE ;TESTEN UND SETZEN GRUPPE 1 MOVFF PIE1,EAPIR1 ;INTERRUPTS HOLEN MOVF PIR1,0 ;MASKE ANDWF EAPIR1 ;ACTIVE SETZEN TSTFSZ EAPIR1 BRA INT_HANDLER ;TESTEN UND SETZEN GRUPPE 2 MOVFF PIE2,EAPIR2 ;INTERRUPTS HOLEN MOVF PIR2,0 ;MASKE ANDWF EAPIR2 ;ACTIVE SETZEN TSTFSZ EAPIR2 BRA INT_HANDLER MOVLW EXT_CODE ;GO EXTERNE SUBROUTINEN AKTIV? CPFSEQ GO_INT ;SKIP WENN JA RETFIE GOTO EXTERN_INTERRUPTS ;REGISTER SICHERN UND STARTEN ;**********************************************************************************************""""""""""""" ; Start application beyond vector area CODE 0x0100 KALT_START ;RESET MODE CLRF BSR ;BANK 0 ;ALLE INT AUS UND RÜCKSETZEN CLRF INTCON ;alle INTERRUPT AUS CLRF RCON ;INT PRIORITY AUS CLRF PIE1 ;MASK DISABLE CLRF PIE2 CLRF PIR1 ;INT ACT AUS CLRF PIR2 CLRF IPR1 ;LOW PRIORITY CLRF IPR2 ; clock ; MOVLW B'01000000' ;32MHZ ; MOVWF OSCTUNE CLRF OSCTUNE ;CLOCK MOVLW CLK_ACTIV MOVWF OSCCON ; div init ;SET PORT A: **7:#master/0.409*5V0 **6:PIC_AMKB_RX **5:PIC_SWTICH **4:HIGH_CHARGE_CURRENT **3:2V5 *2:3V3/2 **1:1V25 **0:POWER_IN/11 CLRF PORTA ;#master(7)=0, REST=0 MOVLW B'11111111' ;DIRECTION: alles auf Input MOVWF TRISA ;SET PORT B: **7:PGD **6:PGC **5:PGM **4:PIN_INT,1V5 **3:GAME PORT PIN10 **2:GAME PORT PIN11 **1:GAME PORT PIN6 **0: GAME PORT PIN5 CLRF PORTB ;ALLES AUF 0 MOVWF TRISB ;SET PORT C: **7: PIC_RX **6:PIC_TX **5:AMKB_TX **4:GAME PORT PIN4 **3:GAME PORT PIN12 **2:GAME PORT PIN13 **1+0: OCS 32K768Hz CLRF PORTC MOVWF TRISC ;SET PORT D: **7:#RSTI **6:GAME PORT PIN3 **5:PS2 KB CLK **4:PS2 MS CLK **3:PS2 KB DATA **2:MS DATA **1:TASTER **0:POWER ON/OFF (0=ON) ; SET TASTE UND POWER CLRF PORTD ;ALLES AUF 0 MOVWF TRISD ;ALLES AUF INPUT ;SET PORT E: **3:#MCLR **2:#PCI_RESET **1:PCI 3V3 **0:PIC LED (0=ON) MOVLW B'00000001' ;LED OFF CLRF PORTE ;ALLES AUF 0 MOVWF TRISE ;ALLES AUF INPUT ;-------------------------- ; set OVERvoltage detekt MOVLW B'10011011' ;INT WENN ÜBER 3.9V MOVWF HLVDCON MOVLW B'00000011' ;ERRORS ON, WAIT AUF LADEN MOVWF U_ERR MOVLW .20 ;SEIT 20SEC ERROR MOVWF U_ERR_TIME ;SETZEN BSF PIE2,HLVDIE ;Enable interrupt ;INTIALISIERUNGSPROGAMME CALL LADESTROM ;LADESTROM EINSTELLEN ;UHR initialisieren MOVLW TIMER_HB ;Preload TMR1 register MOVWF TMR1H ; CLRF TMR1L ;=0 MOVLW B'00001111' ; 8 BIT, osc1 enable, TIMER MODE, TIMMER ENABLE MOVWF T1CON ; SET CLRF TICKS ; 1/8 sec register CLRF SECS ; Initialize timekeeping registers CLRF MINS ; MOVLW .12 MOVWF HOURS MOVLW .1 MOVWF DAY_OF_WEEK MOVLW .1 MOVWF DAYS MOVLW .8 MOVWF MONTHS MOVLW .42 MOVWF YEARS ;MONTAG 19.7.2010 12:00:00 (JAHR-1968) CLRF TASTE_ON_TIME CLRF TASTE_OFF_TIME CLRF POWER_ON_TIME BSF PIE1,TMR1IE ;Enable Timer1 interrupt ;AD WANDLER INITIALISIEREN CLRF AD_KANAL ;BEI 0 BEGINNEN CLRF ADCON0 ;AD MOUDUL AUS MOVLW B'00001001' ;VREF=VDD,ANALOG INPUT AN0-AN5 MOVWF ADCON1 MOVLW B'00000000' ;LINKSSBÜNDIG,0 TAD,CLOCK=Fosc/2 MOVWF ADCON2 ; BSF PIE1,ADIE ;INTERRUPT ENABLE CLRF U_POWER_IN ;WERT AUF 0 VOLT ; seriell initialisieren CLRF SPBRGH MOVLW .16 MOVWF SPBRG ;BAUDE RATE = 115K MOVLW B'00000100' ;TX AUS, ASYNC HIGH SPEED MOVWF TXSTA MOVLW B'10010000' ;SERIEL EIN,RX EIN, MOVWF RCSTA MOVLW B'00001000' ;16BIT BRG, RISING EDGE INTERRUPT MOVWF BAUDCON ;SETZEN ;EXTERNER SUBROUTINES CLRF GO_SUB ; interrupts CLRF INTCON3 ;EXTER INTERRUPT AUS, low priority MOVLW B'11110000' ;PORT B PULLUPS AUS, EXT INT ON RISING EDGE, TMR0 AND BPIP Low priority MOVWF INTCON2 MOVLW B'11000000' ;global on, PERIPHERAL INT on MOVWF INTCON ;CLOCK MOVLW CLK_SLEEP ;GEHT JETZT IN SLEEP MODE MOVWF OSCCON ;------------------------------------------------------------------------- ;---------------------------- MAIN LOOP ------------------------------------------------- ;------------------------------------------------------------------------- MAIN MOVLW EXT_CODE ;GO EXTERNE SUBROUTINEN AKTIV? CPFSEQ GO_SUB ;SKIP WENN JA BRA WARTEN ;SONST WARTEN CALL MAIN2,1 ;REGISTER SICHERN UND STARTEN WARTEN BTFSC TRISD,RD0 ;SKIP IF POWER ON SLEEP ;SLEPP BIS ZUM NÄCHSTEN INTERRUPT BRA MAIN MAIN2 CALL EXTERN_SUBROUTINES ;EXTERNE SUBROUTINEN AUSFÜHREN AN STELLE 0 MUSS 0xFA STEHEN SONST UNGÜLTIG RETURN 1 ;RETURN MIT REGISTER ZURÜCK ;**********************************************************************************************""""""""""""" ;--------------------------- subroutines ------------------------------------------------- ;**********************************************************************************************""""""""""""" ;POWER ON/OFF POWER_EIN ;CLOCK MOVLW CLK_ACTIV MOVWF OSCCON BCF TRISA,RA7 ;CLOCK EINSCHALTEN BCF TRISD,RD7 ;#RSTI AKTIVIEREN = LOW BCF TRISB,RB4 ;PIC_INT AKTIVIEREN BCF TRISD,RD0 ;POWER ON BRA LS_ON_POWER ;LADESTROM EINSTELLEN POWER_AUS ;CLOCK MOVLW CLK_SLEEP MOVWF OSCCON BSF TRISD,RD0 ;POWER OFF BSF TRISD,RD7 ;#RSTI DEAKTIVIEREN BSF TRISB,RB4 ;PIC INT DEAKTIVIEREN BSF TRISA,RA7 ;CLOCK DEAKTIVIEREN CLRF POWER_ON_TIME ;RÜCKSETZEN BRA LS_OFF_POWER ;LADESTROM EINSTELLEN ;LADESTROM EINSTELLEN ---------------------------- LADESTROM BTFSC TRISD,RD0 ; ONPOWER? BRA LS_OFF_POWER ; NEIN-> LS_ON_POWER ;GROSSER LADESTROM 5A BCF TRISA,RA4 ;10K ON RETURN LS_OFF_POWER ;KLEINER LADESTROM_MIN 1.85A BSF TRISA,RA4 ;10K OFF RETURN ;--------------------------------------------------- ;SERIELL AUS/EIN SERIAL_OFF BCF TXSTA,TXEN ;TX AUS BCF PIE1,RCIE ;DISABLE RX interrupt BCF PIR1,RCIF ;CLEAR RX interrupt BCF PIE1,TXIE ;DISABLE TX interrupt BCF PIR1,TXIF ;CLEAR TX interrupt RETURN SERIAL_ON BTFSC TXSTA,TXEN ;SCHON EIN? RETURN ;JA-> BSF TXSTA,TXEN ;TX EIN MOVLW SYNC1 MOVWF RX_STATUS ;AUF SYNC WARTEN CLRF TX_STATUS MOVFF RCREG,RX_B ;RCREG LEEREN MOVFF RCREG,RX_B ;RCREG LEEREN BCF PIR1,TXIF ;CLEAR TX interrupt BCF PIR1,RCIF ;INTERRUPT RX FLAG LÖSCHEN BSF PIE1,RCIE ;ENABLE RX interrupt NOP RETURN ;--------------------------------------------------------------------- ; TASTENDRUCK TASTE BTFSS PORTD,RD1 ;TASTE GEDRÜCKT? BRA TG_JA ;->JA ;TASTE NICHT GEDRÜCKT ODER LOSGELASSEN CLRF TASTE_ON_TIME ;RÜCKSETZEN MOVLW TIME_MAX ;MAX CPFSGT TASTE_OFF_TIME ;LÄNGER? INCF TASTE_OFF_TIME ;NEIN ERHÖHEN MOVLW RESET_OFF_TIME ;2SEC CPFSGT POWER_ON_TIME ;LÄNGER? RETURN ;NEIN-> ;RESET AUFHEBEN BSF TRISD,RD7 ;JA -> #RSTI DEAKTIVIEREN =HIGH CALL SERIAL_ON ;SERIELL EINSCHALTEN RETURN ;TASTE GEDRÜCKT TG_JA MOVLW OFF_TIME+1 CPFSLT TASTE_ON_TIME ;KÜRZER ALS ONTIME+1 RETURN ;NEIN->FERTIG BTFSC TRISD,RD0 ;ONPOWER? BRA TG_OFF_POWER ;NEIN-> TG_ON_POWER MOVLW SEND_RTC_TIME ;ZEIT FÜR RTC REQ FROM MCF HOLEN? CPFSEQ TASTE_ON_TIME ;TEST BRA TG_ON_POWER2 ;NEIN-> SEND_RTC_REG MOVLW REQ_RTCD_FROM_MCF MOVWF TXREG ;SENDEN BRA TG_END; TG_ON_POWER2 MOVLW RESET_ON_TIME ; CPFSLT TASTE_ON_TIME ;KÜRZER? BRA RESETEN TG_ON_POWER3 MOVLW OFF_TIME CPFSLT TASTE_ON_TIME ;KÜRZER ON/OFF TIME? CALL POWER_AUS ;NEIN->POWER OFF BRA TG_END TG_OFF_POWER MOVLW ON_TIME CPFSLT TASTE_ON_TIME ;KÜRZER ALS ON/OFF TIME? CALL POWER_EIN ;NEIN->POWER ON TG_END CLRF TASTE_OFF_TIME ;RÜCKSETZEN INCF TASTE_ON_TIME ;ERHÖHEN RETURN RESETEN BCF TRISD,RD7 ;NEIN-> #RSTI AKTIVIEREN =LOW -->>>RESET CALL SERIAL_OFF ;SERIELL DEAKTIVIEREN BRA TG_ON_POWER3 ;**********************************************************************************************""""""""""""" ;----------------------------------------- INTERRUPTS ;**********************************************************************************************""""""""""""" ; SERIELL INTERRUPTS ;**********************************************************************************************""""""""""""" ;TX TX_ISR ;TRANSMIT MOVLW RTCD_FROM_PIC ;RTC DATEN SENDEN? CPFSEQ TX_STATUS ;SKIP JA BRA TX_ISR1 ;NEIN-> MOVFF POSTINC0,TXREG ;BYT SENDEN MOVLW 0x3F ;SCHON LETZTES BYTS? CPFSGT FSR0L ;SKIP WENN FERTIG RETFIE ;NEIN WEITERE SENDEN TX_ISR_FERTIG CLRF TX_STATUS BCF PIE1,TXIE ;SONST DISABLE interrupt BCF PIR1,TXIF ;INTERRUPT FLAG LÖSCHEN RETFIE TX_ISR1 MOVLW READ_BLOCK ;READ BLOCK? CPFSEQ TX_STATUS ;SKIP JA BRA TX_ISR2 ;NEIN-> MOVFF POSTINC0,TXREG ;BYT SENDEN MOVLW 0xC3 ;SCHON LETZTES BYTS? CPFSGT FSR0L ;SKIP WENN FERTIG RETFIE ;NEIN WEITERE SENDEN TX_ISR2 BRA TX_ISR_FERTIG ;**********************************************************************************************""""""""""""" ;RX RX_ISR ; BYT RECEIVED MOVFF RCREG,RX_B ; BYT HOLEN ; MOVFF RX_B,TXREG ; ECHO MOVLW SYNC4 ;IM SYNC STATUS? CPFSLT RX_STATUS ;SKIP WENN NEIN BRA RX_SYNC_START ;JA -> ZUERST SYNC EMPFANGEN ;--------------- MOVLW RTCD_FROM_MCF ; DATEN VOM MCF CODE 0x82? CPFSEQ RX_STATUS ; WENN JA-> SKIP BRA RX_ISR1 ; NEIN-> ;64 BYT EMPFANGEN ------------------------------------- MOVFF RX_B,POSTINC1 ;HOLEN -> (CNT+) MOVLW 0x3F ;64 BYT ÜBERTRAGEN? CPFSLT FSR1L ;NEIN ->SKIP CLRF RX_STATUS ;JA FERTIG RETFIE ;------------------------------------------------------------------------------------- RX_ISR1 CPFSEQ RX_B ;BLOCK HEADER 0X82? BRA RX_ISR2 ;NEIN-> MOVWF RX_STATUS ;STATUS SETZEN = EMPFANGENES BYT LFSR 1,.0 ;BYT COUNTER AUF O RETFIE RX_ISR2 MOVLW REQ_RTCD_FROM_PIC ;DATEN SENDEN? CPFSEQ RX_B ;SKIP WENN JA BRA RX_ISR3 ;SONST NEXT ;BLOCK HEADER UND 64 BYT SENDEN ----------------------------------------- LFSR 0,.0 BCF PIR1,TXIF ;INTERRUPT FLAG LÖSCHEN BSF PIE1,TXIE ;Enable interrupt MOVLW RTCD_FROM_PIC MOVWF TX_STATUS ;STATUS SETZEN MOVWF TXREG ;BLOCK HEADER = 0X81 CLRF RX_STATUS ;STATUS RÜCKSETZEN RETFIE ;UND WEG ;------------------------------------------------------------------------------------- RX_ISR3 MOVLW EXT_SUB_GO ;EXT SUB FREIGEBEN? CPFSEQ RX_B BRA RX_ISR4 ;NEIN-> ;EXT SUBS FREIGEBEN -------------------------------------------------------------- MOVLW (EXTERN_INT_ADR & 0xFF0000)>>16 MOVWF TBLPTRU MOVLW (EXTERN_INT_ADR & 0x00FF00)>>8 MOVWF TBLPTRH MOVLW (EXTERN_INT_ADR & 0x0000FF) MOVWF TBLPTRL ;ADRESSE SETZEN TBLRD* ;WERT HOLEN (MUSS 0xFB SEIN SONST UNGÜLTIG) MOVFF TABLAT,GO_INT ;EXTERNE SUBROUTINES AKTIVIEREN WENN OK MOVLW (EXTERN_SUB_ADR & 0xFF0000)>>16 MOVWF TBLPTRU MOVLW (EXTERN_SUB_ADR & 0x00FF00)>>8 MOVWF TBLPTRH MOVLW (EXTERN_SUB_ADR & 0x0000FF) MOVWF TBLPTRL ;ADRESSE SETZEN TBLRD* ;WERT HOLEN (MUSS 0xFB SEIN SONST UNGÜLTIG) MOVFF TABLAT,GO_SUB ;EXTERNE SUBROUTINES AKTIVIEREN WENN OK CLRF RX_STATUS ;STATUS RÜCKSETZEN RETFIE ;UND WEG ;------------------------------------------------------------------------------------- RX_ISR4 MOVLW EXT_SUB_STOP ;EXT SUB STOPPEN? CPFSEQ RX_B BRA RX_ISR5 ;NEIN-> ;EXT SUBS STOPPEN -------------------------------------------------------------- CLRF GO_INT ;STOPPEN CLRF GO_SUB ;STOPPEN CLRF RX_STATUS ;STATUS RÜCKSETZEN RETFIE ;UND WEG ;------------------------------------------------------------------------------------- RX_ISR5 MOVLW REQ_BLOCK ;REQ BLOCK? CPFSEQ RX_B BRA RX_ISR6 ;NEIN-> ;REQ BLOCK ---------------------------------------------------------------- MOVWF RX_STATUS ;STATUS SETZEN = EMPFANGENES BYT LFSR 1,TX_BUFFER ;BYT COUNTER AUF TX_BUFFER -> GLEICH EINTRAGEN RETFIE RX_ISR6 CPFSEQ RX_STATUS ;REQ BLOCK ADRESSE EMPFANGFEN? BRA RX_ISR7 ;NEIN-> ;3 BYT EMPFANGEN ------------------------------------- MOVFF RX_B,POSTINC1 ;HOLEN -> (CNT+) MOVLW 0x82 ;3 BYT ÜBERTRAGEN? (BUFFER BEGINNT BEI 0x180 CPFSLT FSR1L ;NEIN ->SKIP BRA RX_RB3BOK RETFIE RX_RB3BOK LFSR 1,TX_BUFFER ;BYT RX COUNTER AUF TX_BUFFER MOVFF POSTINC1,TBLPTRU ;ADRESSE EINTRAGEN MOVFF POSTINC1,TBLPTRH MOVFF POSTINC1,TBLPTRL MOVLW 0xC2 ;67 BYT ÜBERTRAGEN? (BUFFER BEGINNT BEI 0x180 RX_RB3B2 TBLRD *+ ;LESEN UND NEXT MOVFF TABLAT,POSTINC1 ;UND EINTRAGEN CPFSEQ FSR1L ;WENN FERTIG ->SKIP BRA RX_RB3B2 ;SONST LOOP ;BLOCK HEADER 3 BYTS ADRESSE UND 64 BYT SENDEN STARTEN ----------------------------------------- LFSR 0,TX_BUFFER ;TX COUNTER AUF TX_BUFFER BCF PIR1,TXIF ;INTERRUPT FLAG LÖSCHEN BSF PIE1,TXIE ;Enable interrupt MOVLW READ_BLOCK ;CODE HEADER 0xA1 MOVWF TX_STATUS ;STATUS SETZEN MOVWF TXREG ;BLOCK HEADER = 0XA1 CLRF RX_STATUS ;STATUS RÜCKSETZEN RETFIE ;UND WEG ;------------------------------------------------------------------------------------- RX_ISR7 MOVLW WRITE_BLOCK ;WRITE BLOCK 0xA2 BYT EMPFANGEN? CPFSEQ RX_STATUS ;WENN JA-> SKIP BRA RX_ISR8 ;NEIN-> ;WRITE BLOCK ---------------------------------------------------------------------------- ;67 BYT EMPFANGEN ------------------------------------- MOVFF RX_B,POSTINC1 ;HOLEN -> (CNT+) MOVLW 0x42 ;67 BYT ÜBERTRAGEN? CPFSLT FSR1L ;WENN FERTIG ->SKIP RETFIE ; ADRESSE UND DATEN SIND DA -> PROGRAMMING FLASH LFSR 1,RX_BUFFER ;BYT COUNTER AUF RX BUFFER MOVFF POSTINC1,TBLPTRU ;TABLE POINTER SETZEN MOVLW (EXTERN_INT_ADR & 0xFF0000)>>16 CPFSLT TBLPTRU ;TEST OB WENIGER ALS ERLAUBT BRA NO_PROG ;JA-> MOVFF POSTINC1,TBLPTRH ;TABLE POINTER SETZEN MOVLW (EXTERN_INT_ADR & 0x00FF00)>>8 CPFSLT TBLPTRU ;TEST OB WENIGER ALS ERLAUBT BRA NO_PROG ;JA-> MOVFF POSTINC1,TBLPTRL ;TABLE POINTER SETZEN ;EREASE BLOCK BSF EECON1,EEPGD ; point to Flash program memory BCF EECON1,CFGS ; access Flash program memory BSF EECON1,WREN ; enable write to memory BSF EECON1,FREE ; enable Row Erase operation MOVLW 55h MOVWF EECON2 ; write 55h MOVLW 0AAh ; write 0AAh MOVWF EECON2 BSF EECON1,WR ; start erase (CPU stall) MOVLW 0x42 ;67 BYT WRITE_WORD_TO_HREGS MOVFF POSTINC1,TABLAT ; get byte of buffer data TBLWT+* ; write data, perform a short write to internal TBLWT holding register. CPFSLT FSR1L ;SCHON BEI 67 BYTES? BRA WRITE_WORD_TO_HREGS ;NEIN->LOOP PROGRAM_MEMORY BSF EECON1,EEPGD ; point to Flash program memory BCF EECON1,CFGS ; access Flash program memory BSF EECON1,WREN ; enable write to memory MOVLW 55h MOVWF EECON2 ; write 55h MOVLW 0AAh MOVWF EECON2 ; write 0AAh BSF EECON1,WR ; start program (CPU stall) BCF EECON1,WREN ; disable write to memory NO_PROG CLRF RX_STATUS ;AUF NORMLA SCHALTEN RETFIE ;UND FERTIG ;WRITE BLOCK SETZEN? RX_ISR8 CPFSEQ RX_B ;BLOCK HEADER COMMANDOE 0XA2? BRA RX_ISR9 ;NEIN-> MOVWF RX_STATUS ;STATUS SETZEN = EMPFANGENES BYT LFSR 1,RX_BUFFER ;BYT COUNTER AUF RX BUFFER RETFIE ;------------------------------------------------------------------------------------- RX_ISR9 CLRF RX_STATUS RETFIE ;------------------------------------------------------------------------------------- ;SYNC ABWARTEN UND WENN DA "OK!" SENDEN ---------------------------------------------------- ;------------------------------------------------------------------------------------- RX_SYNC_START MOVLW SYNC1 CPFSEQ RX_STATUS BRA RX_SYNC2 MOVLW SYNC1_DATA CPFSEQ RX_B BRA NON_SYNC MOVLW SYNC2 MOVWF RX_STATUS RETFIE NON_SYNC MOVLW SYNC1 MOVWF RX_STATUS RETFIE RX_SYNC2 ;TEST AUF SYNC UND DATA 2 MOVLW SYNC2 CPFSEQ RX_STATUS BRA RX_SYNC3 ;NICHT SYNC 2 MOVLW SYNC2_DATA CPFSEQ RX_B BRA NON_SYNC MOVLW SYNC3 MOVWF RX_STATUS RETFIE RX_SYNC3 ;TEST AUF SYNC UND DATA 3 MOVLW SYNC3 CPFSEQ RX_STATUS BRA RX_SYNC4 ;NICHT SYNC 3 MOVLW SYNC3_DATA CPFSEQ RX_B BRA NON_SYNC MOVLW SYNC4 MOVWF RX_STATUS RETFIE RX_SYNC4 ;TEST AUF SYNC UND DATA 4 MOVLW SYNC4 CPFSEQ RX_STATUS BRA NON_SYNC ;WIEDER VON VORN MOVLW SYNC4_DATA CPFSEQ RX_B ;SKIP OK BRA NON_SYNC ;NICHT SYNC4 DATA RX_WAIT1 BTFSS TXSTA,TRMT BRA RX_WAIT1 MOVLW 'O' ;SENDE OK! MOVWF TXREG; RX_WAIT2 BTFSS TXSTA,TRMT BRA RX_WAIT2 MOVLW 'K' ;SENDE OK! MOVWF TXREG; RX_WAIT3 BTFSS TXSTA,TRMT BRA RX_WAIT3 MOVLW '!' MOVWF TXREG; CLRF RX_STATUS ;OK START NORMAL RETFIE ;**********************************************************************************************""""""""""""" ;SPANNUNGSÜBERWACHUNGS INTERRUPT HLVD_ISR BTFSS U_ERR,1 ;WARTEN AUF GELADEN? BRA HLVD_LE ;NEIN UNTERSPANNUNG DETEKT-> BCF U_ERR,0 ;SPANNUNGSFEHLER AUS BCF U_ERR,1 ;WARTEN AUF GELADEN=AUS MOVLW U_ERR_PW_AUS+2 ;POWER AUS ÜBERSPRINGEN MOVWF U_ERR_TIME ;ZEIT SETZEN MOVLW B'00010111' ;INT WENN UNTER 3.12V MOVWF HLVDCON WAIT_LVDOK: BTFSS HLVDCON,IVRST ;ABWARTEN BIS AENDERUNG AKTIV BRA WAIT_LVDOK BCF PIR2,HLVDIF ;INTERRUPT FLAG LÖSCHEN RETFIE HLVD_LE ;UNTERSPANNUNG BSF U_ERR,0 ;ERROR SETZEN BSF U_ERR,1 ;WARTEN AUF GELADEN SETZEN CLRF U_ERR_TIME ;RÜCKSETZEN ;MESSAGE AN PROCESSOR MOVLW U_MIN_TO_MCF MOVWF TXREG ;SENDEN MOVLW B'10011010' ;INT WENN ÜBER 3.7V MOVWF HLVDCON BRA WAIT_LVDOK ;**********************************************************************************************""""""""""""" ;A/D INTERRUPT AD_ISR BCF PIR1,ADIF ;CLEAR INTERRUPT PENDIG RETFIE ;RETURN ;************************************************************************************************************* ; uhr interrupt ALLE 1/8 SEC RTC_ISR ;UHR WIEDER RÜCKSETZEN UND AKTIVIEREN MOVLW TIMER_HB ;WIEDER AUF STARTWERT MOVWF TMR1H ;SETZEN BCF PIR1,TMR1IF ;INTERRUPT FLAG LÖSCHEN BSF PORTB,RB4 ;PIC INT HIGH -------- BSF TRISE,RE0 ;LED=OFF BCF PORTB,RB4 ;PIC INT = LOW BTFSC TRISD,RD0 ;POWER OFF? BRA POWER_OFF_I ;JA-> ; POWER IS ON: ; BLINKEN 4X/SEC WENN RESET BTFSC TRISD,RD7 ;RESET AKTIV? BRA PINGS ;NEIN-> BTFSC TICKS,0 ;UNGERADE TICKS? BCF TRISE,RE0 ;NEIN->LED=ON BRA PINGS POWER_OFF_I MOVLW .3 ANDWF SECS,0 ;4 SEKUNDEN AUSMASKIEREN BNZ PINGS ;NICHT MODULO4 -> MOVLW .7 CPFSEQ TICKS ;7. TICK? BRA POWER_OFF_I2 ;NEIN-> BCF TRISE,RE0 ;JA->LED=ON POWER_OFF_I2 MOVLW .30 ; WENIGER ALS 30 SEC SEIT LETZTEM SPANNUNGSFEHLER? CPFSLT U_ERR_TIME BRA PINGS ;NEIN-> MOVLW .5 CPFSEQ TICKS ;5. TICK? BRA PINGS ;NEIN-> BCF TRISE,RE0 ;JA->LED=ON PINGS CALL TASTE ;UP TASTE ; TASTE LOSGELASSEN? MOVLW RESET_OFF_TIME CPFSGT TASTE_OFF_TIME ;TASTE LÄNGER ALS 2 SEC LOSGELASSEN? BRA PINGW ;NEIN-> BSF TRISD,RD7 ;JA-> #RSTI INAKTIV =HIGH BTFSS TRISD,RD0 ;POWER ON? CALL SERIAL_ON ;ja->SERIELL EINSCHALTEN ;--TICKS=125MS PINGW INCF TICKS ;inc ticks BTFSS TRISD,RD0 ;POWER ON? BRA PINGS2 ;JA-> MOVLW 20 CPFSLT U_POWER_IN ;LADEGERÄT ANGESCHLOSSEN? BRA PINGS2 ;->JA LED HELLER MOVLW TIME_MAX ;>=MAXIMALZEIT? CPFSLT U_ERR_TIME ;SEIT SPANNUNGSFEHLER BSF TRISE,RE0 ;JA -> LED OFF PINGS2 MOVLW .7 ; 7? CPFSGT TICKS RETFIE ; NEIN ->RETURN SEKUNDEN ;led blinken POWER ON----------------------------------------- BTFSS TRISD,RD0 ;POWER ON? BCF TRISE,RE0 ;JA -> LED_ON ;TIMER U_ERR ERHÖHEN MOVLW TIME_MAX ;>=MAXIMALZEIT? CPFSGT U_ERR_TIME ;SEIT SPANNUNGSFEHLER INCF U_ERR_TIME ;NEIN ERHÖHEN ;SPANNUNGSFEHLER BEARBEITEN ---------------------------------------- MOVLW U_ERR_PW_AUS ;POWER AUS ZEIT? CPFSEQ U_ERR_TIME ; BRA SEK_NPA ;NEIN CALL POWER_AUS ;JA AUSSCHALTEN ;-------------------------------------------------------- SEK_NPA ;SPANNUNG POWER IN MESSEN MOVLW B'00000001' ;KANAL 0, AD ON MOVWF ADCON0 ; BSF ADCON0,1 ;GO SEK_2 BTFSC ADCON0,1 ;FERTIG? BRA SEK_2 ;NEIN MOVFF ADRESH,U_POWER_IN ;OK WERT EINTRAGEN ;SPANNUNG 2V5 MESSEN -> U_ERR TIMER NICHT ERHÖHEN WENN ÜBER 3.2V RESP. WIEDER -1 BTFSC TRISD,RD0 ;POWER ON? BRA SEK_4 ;NEIN NICHT MESSEN MOVLW B'00001101' ;KANAL 3, AD ON MOVWF ADCON0 ; BSF ADCON0,1 ;GO SEK_3 BTFSC ADCON0,1 ;FERTIG? BRA SEK_3 ;NEIN MOVLW .200 ;UNTER 3.2V -> WENN WERT ÜBER 78% CPFSLT ADRESH ;JA -> BRA SEK_4 ;SONST WEITER ;TIMER U_ERR ERHÖHEN BTFSS U_ERR,0 ;SPANNUNGSERROR? BRA SEK_4 ;NEIN MOVLW TIME_MAX ;>=MAXIMALZEIT? CPFSGT U_ERR_TIME ;SEIT SPANNUNGSFEHLER DECF U_ERR_TIME ;NEIN -> -1 ;------------------------------------------------------------- SEK_4 CLRF TICKS INCF SECS ; Increment seconds MOVLW .59 ; 60 seconds elapsed? CPFSGT SECS RETFIE ;RETURN MINUTEN CLRF SECS ; Clear seconds INCF MINS ; Increment minutes MOVLW .59 ; 60 minutes elapsed? CPFSGT MINS RETFIE ;RETURN STUNDEN CLRF MINS ; clear minutes INCF HOURS ; Increment hours MOVLW .23 ; 24 hours elapsed? CPFSGT HOURS RETFIE ;RETURN TAGE_UND_TAG_DER_WOCHE CLRF HOURS ; Reset hours MOVLW .7 CPFSLT DAY_OF_WEEK CLRF DAY_OF_WEEK INCF DAY_OF_WEEK INCF DAYS MOVLW .28 CPFSGT DAYS RETFIE ;RETURN MEHR_ALS_28_TAGE MOVLW .2 CPFSEQ MONTHS ;FEB? BRA NOT_FEB ;NEIN-> FEB MOVLW .3 ANDWF YEARS,0 ;SCHALTJAHR BNZ NEXT_MONTH ;NEIN-> SCHALTJAHR MOVLW .29 CPFSGT DAYS RETFIE ;RETURN NEXT_MONTH MOVLW .1 MOVWF DAYS INCF MONTHS MOVLW 12 CPFSGT MONTHS RETFIE ;RETURN YEAR MOVLW .1 MOVWF MONTHS INCF YEARS RETFIE ;RETURN NOT_FEB MOVLW .30 CPFSGT DAYS RETFIE MEHR_ALS_30_TAGE MOVLW .4 ;APRIL? CPFSEQ MONTHS ;SKIP BRA NOT_APRIL BRA NEXT_MONTH ;APRIL-> NOT_APRIL MOVLW .6 ;JUNI? CPFSEQ MONTHS BRA NOT_JUNI BRA NEXT_MONTH ;JUNI-> NOT_JUNI MOVLW .9 ;SEPTEMBER? CPFSEQ MONTHS BRA NOT_SEP BRA NEXT_MONTH ;SEPTEMBER-> NOT_SEP MOVLW .11 ;NOVEMBER? CPFSEQ MONTHS ;SKIP RETFIE ;SIND MONATE MIT 31 TAGEN-> BRA NEXT_MONTH ;SONST NOVEMBER-> ;**********************************************************************************************""""""""""""" ; ENDE MAIN ;**********************************************************************************************""""""""""""" ;**********************************************************************************************""""""""""""" ; EXTERN_SUBOUTINES FOGEN AB 0x1000 DIE SPÄTER EINPROGRAMMIERT WERDEN ;**********************************************************************************************""""""""""""" end