Files
pic_mlab/firebee1.asm

1090 lines
33 KiB
NASM

;**********************************************************
;* 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
COUNT1 EQU 0x50 ;COUNTER FOR WAIT LOOP
COUNT2 EQU 0x51 ;COUNTER FOR WAIT LOOP
SW_POWER_OFF_FLAG EQU 0x52 ;SOFTWARE SHUTDOWN FLAG
;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 .40 ;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
CMD_FROM_MCF EQU 0Ch ;3 BYT COMMANDOS FROM MCF = TOTAL 4 BYT
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 UND 1 BYT CHECKSUM = TOTAL 69 BYTES
PRG_OK EQU 0x00 ;PROGRAMMIERUNG BLOCK FERTIG
CHECKSUM_ERROR EQU 0xFE
;**********************************************************************************************"""""""""""""
; 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
;BLOCK PROGRAMMIEREN **********************************************************************************************"""""""""""""
PB CODE 0x0080
PROGRAMM_BLOCK
LFSR 1,RX_BUFFER ;BYT COUNTER AUF RX BUFFER
MOVFF POSTINC1,TBLPTRU ;TABLE POINTER SETZEN
MOVFF POSTINC1,TBLPTRH ;TABLE POINTER SETZEN
MOVFF POSTINC1,TBLPTRL ;TABLE POINTER SETZEN
;EREASE BLOCK
BCF INTCON,GIE ; DISABLE INTTERUPT
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)
BSF INTCON,GIE ; ENABLE INTERRUPT
TBLRD*- ; POINTER DUMMY DECREMENT
; BLOCK WRITE 1.HÄLFTE
MOVLW 23h ; 67 BYT 3 BYT ADR + 64 BYT DATEN
WRITE_WORD_TO_HREG1
MOVFF POSTINC1,TABLAT ; get byte of buffer data
TBLWT+* ; write data, perform a short write to internal TBLWT holding register.
CPFSEQ FSR1L ; SCHON BEI 32 BYTES?
BRA WRITE_WORD_TO_HREG1 ;NEIN->LOOP
; PROGRAMM BLOCK
BSF EECON1,EEPGD ; point to Flash program memory
BCF EECON1,CFGS ; access Flash program memory
BSF EECON1,WREN ; enable write to memory
BCF INTCON,GIE ; DISABLE INTTERUPT
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
; BLOCK WRITE 2. HÄLFTE
MOVLW 43h ; 67 BYT 3 BYT ADR + 64 BYT DATEN
WRITE_WORD_TO_HREG2
MOVFF POSTINC1,TABLAT ; get byte of buffer data
TBLWT+* ; write data, perform a short write to internal TBLWT holding register.
CPFSEQ FSR1L ; SCHON BEI 64 BYTES?
BRA WRITE_WORD_TO_HREG2 ;NEIN->LOOP
; PROGRAMM BLOCK
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
BSF INTCON,GIE ; ENABLE INTERRUPT
MOVLW PRG_OK ; OK senden
MOVWF TXREG
CLRF RX_STATUS ; FERTIG
RETFIE
;**********************************************************************************************"""""""""""""
; Start application beyond vector area
STD 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
MOVLW B'01000000' ;RA6 auf high
MOVWF PORTA ;#master(7)=0, REST=0
MOVLW B'11111111' ;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)
CLRF PORTE ;ALLES AUF 0
MOVLW B'00000111' ;tri: PCI RESET; PCI3V3; LED
MOVWF TRISE ;direction setzen
;--------------------------
; 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)
MOVLW 0x27 ;32kHz TEILER=64
MOVWF REGA
MOVLW B'00000011' ;24H, SOMMERZEIT
MOVWF REGB
CLRF REGC
CLRF REGD
CLRF TASTE_ON_TIME
CLRF TASTE_OFF_TIME
CLRF POWER_ON_TIME
CLRF RX_STATUS
CLRF TX_STATUS
BSF PIE1,TMR1IE ;Enable Timer1 interrupt
CLRF SW_POWER_OFF_FLAG
;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
TSTFSZ SW_POWER_OFF_FLAG ;SOFTWARE SHUTDOWN FLAG SET?
CALL SW_POWER_OFF ;YES->
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
BCF TRISA,RA6 ;PIC_AMKB_RX auf output
BRA LS_ON_POWER ;LADESTROM EINSTELLEN
POWER_AUS
;CLOCK
MOVLW CLK_SLEEP
MOVWF OSCCON
BSF TRISA,RA6 ;PIC_AMKB_RX auf input
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
SW_POWER_OFF
;BEFORE SOFTWARE POWER OFF GET RTC DATA FROM MCF
MOVLW REQ_RTCD_FROM_MCF
MOVWF TXREG ;BLOCK HEADER = 0X81
;WAIT 260 ms APPROX FOR MCF TO SEND RTC DATA
MOVLW .255
MOVWF COUNT1
MOVWF COUNT2
WAIT_MCF
NOP
NOP
NOP
NOP
NOP
DECFSZ COUNT1
GOTO WAIT_MCF
MOVLW .255
MOVWF COUNT1
DECFSZ COUNT2
GOTO WAIT_MCF
CALL POWER_AUS
CLRF SW_POWER_OFF_FLAG
RETURN
;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
CALL SERIAL_OFF ;SERIELL DEAKTIVIEREN
BCF TRISD,RD7 ;NEIN-> #RSTI AKTIVIEREN =LOW -->>>RESET
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?
CPFSEQ 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
;RTC DATEN 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 0x40 ;64 BYT ÜBERTRAGEN?
CPFSLT FSR1L ;NEIN ->SKIP
CLRF RX_STATUS ;JA FERTIG
RETFIE
; SETZEN? ---------------------------------------------------
RX_ISR1
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR2 ;JA ->
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
; RTC DATEN SENDEN? -------------------------------------------------------------------------------------
RX_ISR2
MOVLW REQ_RTCD_FROM_PIC ;DATEN SENDEN?
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR3 ;JA ->
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
;EXT SUB INT STARTEN?-------------------------------------------------------------------------------------
RX_ISR3
MOVLW EXT_SUB_GO ;EXT SUB FREIGEBEN?
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR4 ;JA ->
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
;EXT SUB INT STOPPEN? -------------------------------------------------------------------------------------
RX_ISR4
MOVLW EXT_SUB_STOP ;EXT SUB STOPPEN?
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR5 ;JA ->
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
;REQ BLOCK? -------------------------------------------------------------------------------------
RX_ISR5
MOVLW REQ_BLOCK ;REQ BLOCK?
TSTFSZ RX_STATUS ;TASK HÄNGIG? SKIP NON
BRA RX_ISR6 ;JA ->
CPFSEQ RX_B
BRA RX_ISR6 ;NEIN->
;REQ BLOCK SETZEN
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 0x83 ;3 BYT ÜBERTRAGEN? (BUFFER BEGINNT BEI 0x180
CPFSEQ FSR1L ;NEIN ->SKIP
RETFIE ;NEXT ->
LFSR 1,TX_BUFFER ;BYT RX COUNTER AUF TX_BUFFER
MOVFF POSTINC1,TBLPTRU ;ADRESSE EINTRAGEN
MOVFF POSTINC1,TBLPTRH
MOVFF POSTINC1,TBLPTRL
MOVLW 0xC3 ;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
;PROGRAMM BLOCK? -------------------------------------------------------------------------------------
RX_ISR7
MOVLW WRITE_BLOCK ;WRITE BLOCK 0xA2 BYT EMPFANGEN?
CPFSEQ RX_STATUS ;WENN JA-> SKIP
BRA RX_ISR8 ;NEIN->
;WRITE BLOCK ------------------------
;68 BYT EMPFANGEN: 3 BYT ADRESSE; 64 BYT DATEN; 1 BYT CHECKSUM -------------------
MOVFF RX_B,POSTINC1 ;HOLEN -> (CNT+)
MOVLW 0x44 ;68 BYT ÜBERTRAGEN?
CPFSEQ FSR1L ;WENN FERTIG ->SKIP
RETFIE
; ADRESSE UND DATEN und CHECKSUM SIND DA -> PROGRAMMING FLASH
; TEST CHECKSUM
LFSR 1,RX_BUFFER ;BYT COUNTER AUF RX BUFFER
MOVLW 43h ;67 BYTES
MOVWF RX_B ;COUNTER
MOVLW 0h ;SUM CLEAR
LOOP_TEST_CHECKSUM
ADDWF POSTINC1,0 ;ADD TO WREG
DECFSZ RX_B ;-1 SKIP WENN 0
BRA LOOP_TEST_CHECKSUM
CPFSEQ POSTINC1 ;SUM = CHECKESUM? SKIP JA
BRA CHK_ERR ;NEIN CHECKSUM ERROR
BRA PROGRAMM_BLOCK ; OK-> PROGRAMMIEREN
CHK_ERR
MOVLW CHECKSUM_ERROR ; ERROR senden
MOVWF TXREG;
CLRF RX_STATUS ; FERTIG
RETFIE
;WRITE BLOCK SETZEN?
RX_ISR8
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR9 ;JA ->
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
MOVLW CMD_FROM_MCF ;CMD HEADER 0x0C EMPFANGEN?
CPFSEQ RX_STATUS ;WENN JA-> SKIP
BRA RX_ISR15 ;NEIN->
;COMMAND BYT EMPFANGEN
;3 BYT EMPFANGEN -------------------------------------
MOVFF RX_B,POSTINC1 ;HOLEN -> (CNT+)
MOVLW 0x3 ;3 BYT ÜBERTRAGEN?
CPFSEQ FSR1L ;NEIN ->SKIP
RETFIE
CMD_AUSWERTEN
;RESET?
LFSR 1,RX_BUFFER ;ZEIGER AUF RX BUFFER
MOVLW 'R'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC2 ;NEIN->
MOVLW 'S'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC2 ;NEIN->
MOVLW 'T'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC2 ;NEIN->
;RESET MCF
CALL SERIAL_OFF ;SERIELL DEAKTIVIEREN
BCF TRISD,RD7 ;NEIN-> #RSTI AKTIVIEREN =LOW -->>>RESET
MOVLW 0FFh
LC1_WAIT
NOP
NOP
NOP
DECFSZ WREG
BRA LC1_WAIT
BSF TRISD,RD7 ;JA -> #RSTI DEAKTIVIEREN =HIGH
CALL SERIAL_ON ;SERIELL EINSCHALTEN
CLRF RX_STATUS ;JA FERTIG
RETFIE
LC2:
;POWER AUS?
LFSR 1,RX_BUFFER ;ZEIGER AUF RX BUFFER
MOVLW 'O'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC4 ;NEIN->
MOVLW 'F'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC4 ;NEIN->
MOVLW 'F'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC4 ;NEIN->
;POWER OFF
INCF SW_POWER_OFF_FLAG ;SET SOFTWARE SHUTDOWN FLAG
CLRF RX_STATUS ;JA FERTIG
RETFIE
LC4:
;RESET PIC?
LFSR 1,RX_BUFFER ;ZEIGER AUF RX BUFFER
MOVLW 'R'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC6 ;NEIN->
MOVLW 'P'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC6 ;NEIN->
MOVLW 'I'
CPFSEQ POSTINC1 ;=? SIKP JA
BRA LC6 ;NEIN->
;RESET PIC
RESET
;HIER SOLLTE ER NICHT HINKOMMEN
BRA KALT_START
LC6
;NO REAL CMA
CLRF RX_STATUS ;JA FERTIG
RETFIE
;END CDM AUSWERTEN
RX_ISR15
TSTFSZ RX_STATUS ;TASK HÄNGIG?
BRA RX_ISR20 ;JA ->
CPFSEQ RX_B ;CMD?
BRA RX_ISR20 ;NEIN->
;CMD SETZEN
MOVWF RX_STATUS ;STATUS SETZEN = EMPFANGENES BYT
LFSR 1,RX_BUFFER ;ZEIGER AUF RX BUFFER
RETFIE
RX_ISR20
RX_ISR_END
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
;?????????????????????????????????????????????????????
;test pic ps2 keyboard
; MOVLW 0f9h ;2
; CALL send
; nop
; nop
; MOVLW .10
; CALL send
; nop
; nop
; MOVLW .10
; CALL send
;--------------------------------------------------------------
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 0x2000 DIE SPÄTER EINPROGRAMMIERT WERDEN
;**********************************************************************************************"""""""""""""
EXT_INT CODE 0x2000
EXT_INT_MAGIC DB 0
EXT_INT_START
EXT_SUB CODE 0x2010
EXT_SUB_MAGIC DB 0
EXT_SUT_START
clockrate equ .8000000 ;Xtal value (8Mhz in this case)
fclk equ clockrate/4
;baudrate equ ((fclk/.7812.5)/3-2) ;7812.5 is the baud rate
baudrate equ .83 ;7812.5 is the baud rate
txreg equ 10
delay equ 11
count equ 12
txchar equ 13
send
movwf txreg
movlw baudrate
movwf delay
movlw .9
movwf count
bcf PORTA,6 ;send start bit
nop ;even out bit times
next
decfsz delay,f
goto next
movlw baudrate ;rest of program is 9 instructions
movwf delay
decfsz count,f
goto sendnextbit
bcf PORTA,6 ;send stop bit
movlw baudrate ;Delay for line to settle
movwf delay ;Delay for line to settle
p1
decfsz delay,f ;Delay for line to settle
goto p1 ;Delay for line to settle
bsf PORTA,6
p2
decfsz delay,f
goto p2
return
sendnextbit
rrcf txreg,F
btfss STATUS,C ;check next bit to tx
goto setlo
bsf PORTA,6 ;send a high bit
goto next
setlo
bcf PORTA,6 ;send a low bit
goto next
end