#include "P16F84.inc" ; MANFRED GLAHE 29.7.03 ; Gesangs- Überwachung- Zeitaufzeichnung VZLUEK EQU 0x0F ; Lückenüberbrückung 1 VZL EQU 0x0C ; Lückenüberbrückung 2 BYTAUS EQU 0x0D ; Variable Senderegister BITAUS EQU 0x0E ; Variable für Bitlänge/Byte MILSEK EQU 0x10 ; UHR 8 HZ SEK1 EQU 0x11 ; UHR 1 HZ SEK2 EQU 0x12 ; UHR Sekunden Byte 2 SEK3 EQU 0x13 ; UHR Sekunden Überlauf TONAKT EQU 0x14 ; Ton aktiv SLAVAD EQU 0x15 ; Slave Adresse FRAM ADRMSB EQU 0x16 ; FRAM Adresse MSB ADRLSB EQU 0x17 ; FRAM Adresse LSB DAUER EQU 0x18 ; Sekunden Ton DAUER sichern SEK2STR EQU 0x19 ; Sekunden MSB sichern SEK1STR EQU 0x1A ; Sekunden LSB sichern TEMPMSB EQU 0x1B ; Temperatur MSB sichern TEMPLSB EQU 0x1C ; Temperatur LSB sichern TEMPBIT EQU 0x1D ; Variable für Bitlänge Temperatur TEMPSER EQU 0x1E ; Temperaturbit Zwischenspeicher SEK3STR EQU 0x1F ; Sekunden Überlauf Bit sichern BYTEIN EQU 0x20 SICHW EQU 0x21 ; Working Register sichern LUECK EQU 0x22 ; Zeit um Lücken INT ausblenden zu können TEMP13 EQU 0x2F ; LÖSCH, TEMP, FRAM, wird mehrfach genutzt org 0x00 ; Reset Vector Adresse GOTO START ;;;;;;;;;;;;;;;;;;;;;;;; INTERRUPTVECTOR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x04 ; Interrupt Vector Adresse movwf SICHW ; Working Register sichern btfsc INTCON,2 ; TRM0 Interrupt, Timer Überlauf CALL UHR btfsc INTCON,0 ; Portchange Interrupt CALL AUFZNG movfw SICHW ; Working Register wieder laden retfie ;;;;;;;;;;;;;;;;;;;;;;;; VOREINSTELLUNGEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x10 START: BANKSEL TRISA movlw 0xC7 ; C7 = Vorteiler auf :256 !!!!! C3=TEST !!!!!! movwf OPTION_REG movlw 0x11 ; Bit 0, 4 = EIN, Bit 1, 2, 3 = AUS movwf TRISA movlw 0xF0 ; Bit 0-3=AUS, Bit 4+5=EIN,Int on change movwf TRISB BANKSEL PORTA ;;;;;;;;;;;;;;;;;;;; RAM BEREICH 0Ch bis 2Bh löschen ;;;;;;;;;;;;;;;;;;; movlw 0x19 ; Anzahl der zu löschenden Byt's = 16 movwf TEMP13 ; Löschen von 0C + 16 = bis 22 movlw 0x0C ; Start Adresse laden movwf FSR movlw 0x00 ; W Register löschen LOSCH: movwf INDF incf FSR decfsz TEMP13 GOTO LOSCH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clrf TONAKT clrf TMR0 movlw 0xA8 ; GIE, TOIE, RBIE = RB Port change Interrupt movwf INTCON movlw 0xA0 ; ID=A, ADR=0, R/W=0 (FRAM beschreiben) movwf SLAVAD movlw 0x0C movwf PORTA ; SPI-BUS für TC77, WP/LESEN setzen bsf PORTB,2 ; LED Aufnahme deaktivieren bsf PORTB,3 ; LED Aufnahme deaktivieren bsf PORTB,3 ; LED INTdetekt deaktivieren ;clrf INTCON ; NUR ZUM TESTEN !!!!! ;movlw 0xFD ; NUR ZUM TESTEN !!!!! ;movwf TMR0 ; NUR ZUM TESTEN !!!!! ;;;;;;;;;;;;;;;;;;;;;;;;;; HAUPTPROGRAMM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HPT1: btfsc PORTB,5 ; Wenn Portb B5 = 1 ist, dann PC LESEN ;CALL LESEN ; FRAM Auslesen mit µP NUR ZUM TESTEN !!!!! CALL UPAUS ;bsf PORTB,2 ; NUR ZUM TESTEN !!!!! GOTO HPT1 ;;;;;;;;;;;;;;;;;;;;;;;;;; HAUPTPROGRAMM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UPAUS BANKSEL TRISA movlw 0xFF movwf TRISA movwf TRISB BANKSEL PORTA XXX: SLEEP ; Sleep Modus aktivieren GOTO XXX return ;;;;;;;;;;;;;;;;;;;;;;;;;; AUFZEICHNEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AUFZNG bcf PORTB,3 ; LED INT aktivieren btfss LUECK,0 ; Start Aufzeichnen schon aktiv wenn LÜCKE=1 ist CALL VZSTR ; Kürzere Signale verhindern die Aufzeichnung btfsc LUECK,0 GOTO LUECK2 btfss PORTB,4 ; Komparator noch = 1 GOTO UEBSP ; Überspringen wenn t=< ist LUECK2: btfss LUECK,0 ; POS Flanke INT übergehen wenn LÜCKE=1 ist GOTO LUEK1 CALL VERZ3 btfss LUECK,0 ; POS Flanke INT übergehen wenn LÜCKE=1 ist GOTO LUEK1 ; Block in FRAM schreiben und fertig! GOTO UEBSP LUEK1: btfss PORTB,5 ; Bit Lesen gesetzt ? GOTO STOP4 bsf ADRMSB,7 ; Überlauf Schreibsperre setzen GOTO STOP3 STOP4: btfsc TONAKT,1 GOTO STOP CALL TONSTR ; Ton Startzeit sichern CALL TEMP ; Temperatur sichern CALL SEKUBL ; Überlaufbit Sekunden im Tempcode unterbringen STOP: btfss TONAKT,1 GOTO STOP1 CALL FRAM ; Alle (5Byte) Daten nach Fram schreiben clrf TONAKT GOTO UEBSP STOP3: clrf TONAKT GOTO STOP2 STOP1: incf TONAKT STOP2: bsf LUECK,0 UEBSP: movfw PORTB ; Löscht den PORT CHANGE Zustand bcf INTCON,0 ; Port change INT wieder löschen return ;;;;;;;;;;;;;;;;;;;;;; PIC LESEN TESTPROGRAMM;;;;;;;;;;;;;;;;;;;;;;;;;;; LESEN clrf PORTB bsf TEMP13,0 ; NUR ZUM TESTEN !!!!! bsf PORTB,0 ; Startsequenz bsf PORTB,1 ; Startsequenz CALL VERZ1 bcf PORTB,0 ; Startsequenz CALL VERZ1 bcf PORTB,1 ; Startsequenz CALL VERZ1 movlw 0x08 movwf BITAUS movfw SLAVAD ; Slave Adresse laden, ist A1 für lesen addlw 0x01 ; 1 addieren für LESEN movwf BYTAUS rlf BYTAUS rlf BYTAUS ; Bit 7 ist nun auf Position, Portb = B0 andlw 0FD ; Taktbit nicht verändern movwf PORTB ; 1. Bit auf Portb angelegt MSBit SLAVE: bsf PORTB,1 ; pos Flanke SCK Slave Adress rlf BYTAUS movfw BYTAUS bcf PORTB,1 ; neg Flanke SCK andlw 0xFD ; Taktbit nicht verändern movwf PORTB decfsz BITAUS GOTO SLAVE CALL ACKSLV ; Slave Acknowledge ermöglichen CALL VERZ2 bsf BITAUS,3 ; Bytelänge (8 Bit) neu setzen DATEN: bsf PORTB,1 ; pos Flanke SCK 1. Daten Byte CALL VERZ1 bcf PORTB,1 ; neg Flanke SCK decfsz BITAUS GOTO DATEN CALL ACKLES ; Lesen Acknowledge mit PIC setzen CALL VERZ2 bsf BITAUS,3 decfsz TEMP13 ; 5 Datenbyte's gesendet ? GOTO DATEN CALL VERZ1 bcf PORTB,0 ; Stopsequenz CALL VERZ1 bsf PORTB,1 ; Stopsequenz bsf PORTB,0 ; Stopsequenz bsf ADRMSB,7 return ;;;;;;;;;;;;;;;;;;;;;;;; TEMPERATUR / LESEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;; TEMP bcf PORTB,2 ; LED Aufnahme aktivieren bcf PORTA,2 ; CS\ für TC77 auf aktiv setzen movlw 0x02 movwf TEMP13 ; Variable 2 mal Durchlaufen movlw 0x08 ; MSB 8 Bit einlesen TEMP3: clrf TEMPSER ; Serielles Register wieder löschen movwf TEMPBIT ; Bitlänge Temperaturwert auf 13 setzen TEMP1: bsf PORTA,1 ; pos Flanke SCK movfw PORTA ; Temperatur Bit laden bcf PORTA,1 ; neg Flanke SCK andlw 0x01 ; Bit A0 selektieren iorwf TEMPSER ; Bit A0 mit Bitseriel verknüpfen decfsz TEMPBIT GOTO TEMP2 decfsz TEMP13 ; 13 Bit Variable GOTO TEMP5 GOTO TEMP4 TEMP5: movfw TEMPSER movwf TEMPMSB ; Temperatur MSB sichern movlw 0x05 ; LSB 5 Bit einlesen GOTO TEMP3 TEMP2: rlf TEMPSER GOTO TEMP1 TEMP4: movfw TEMPSER movwf TEMPLSB ; Temperatur LSB sichern bsf PORTA,2 ; CS\ für TC77 auf inaktiv setzen return ;;;;;;;;;;;;;;;;;;;; FRAM FM24C256 SCHREIBEN ;;;;;;;;;;;;;;;;;;;;;;;;;;; FRAM ;GOTO ENDE ; NUR ZUM TESTEN !!!!!!!!!!!!!!!!!! btfsc ADRMSB,7 ; Überlauf- Schreibsperre GOTO ENDE bcf PORTA,3 ; WP/LESEN Sperre aufheben CALL VERZ1 bsf PORTB,1 ; Startsequenz CALL VERZ1 bsf PORTB,0 ; Startsequenz CALL VERZ1 bcf PORTB,0 ; Startsequenz CALL VERZ1 bcf PORTB,1 ; Startsequenz movlw 0x0F movwf TEMP13 ; Anzahl Byt's (8 Byte) x2 neu setzen bsf BITAUS,3 ; Bitlänge (8 Bit) neu setzen GOTO BLOCK2 SPI3: decfsz BITAUS ; Variable für Bitlänge/Byte GOTO SPI2 GOTO SPI4 decfsz TEMP13 GOTO SPI4 SPI2: rlf BYTAUS ; FRAM Daten nächstes Bit vorbereiten SPI1: btfss BITAUS,3 GOTO BLOCK decfsz TEMP13 ; Sind alle Daten Byte's gesendet ? GOTO BLOCK1 BLOCK2: movlw DAUER-0x04 ; SLAVAD- ADRMSB -ADRLSB- DATEN, +5 Byte movwf FSR BLOCK1: incf FSR movfw INDF ; Nächstes Byte nach FRAM, usw. bis 7.Byte movwf BYTAUS rlf BYTAUS ; FRAM Daten nächstes Bit vorbereiten rlf BYTAUS ; FRAM Daten nächstes Bit vorbereiten BLOCK: movfw BYTAUS ; Neues Bit laden andlw 0xF1 ; Verknüpfen mit anderen Port- Pins movwf PORTB ; AUSGABE DATEN-BIT bsf PORTB,1 ; pos Flanke SCK CALL VERZ1 bcf PORTB,1 ; neg Flanke SCK GOTO SPI3 SPI4: CALL ACKSCH ; Acknowledge vom FRAM abfragen bsf BITAUS,3 ; Bitlänge (8 Bit) neu setzen decfsz TEMP13 ; Sind alle Daten gesendet ? GOTO SPI1 CALL VERZ1 bsf PORTB,1 ; Stopsequenz CALL VERZ1 bsf PORTB,0 ; Stopsequenz CALL VERZ1 movlw 0x05 ; 5 Datenbyte's pro FRAM/Schreibcyclus addwf ADRLSB ; Startadresse FRAM erhöhen, 5/ Durchlauf addcf ADRMSB ; Übertragsbit nach ADRMSB clrf DAUER ENDE: bsf PORTA,3 ; WP/LESEN Sperre aktivieren bsf PORTB,2 ; LED Aufnahme deaktivieren bsf PORTB,3 ; LED INT deaktivieren return ;;;;;;;;;;;;;;;;;;;;;;; SICHERUNG START ZEITEN ;;;;;;;;;;;;;;;;;;;;;;;;; TONSTR movfw SEK1 ; TON Startzeit sichern movwf SEK1STR ; movfw SEK2 ; movwf SEK2STR ; movfw SEK3 ; movwf SEK3STR ; Ton Startzeit gesichert bsf TONAKT,0 return ;;;;;;;;;;;;;;;;; ACKNOWLEDGE FRAM SCHREIBEN ABFRAGEN ;;;;;;;;;;;;;;;;;; ACKSCH BANKSEL TRISB ; Ausgang B0 für Acknowledge hochohmig setzen movlw 0xF1 ; Bit 0=EIN, Bit 1=AUS,Bit 4-7=EIN,Int on change movwf TRISB BANKSEL PORTB bsf PORTB,1 ; pos Flanke SCK CALL VERZ1 bcf PORTB,1 ; neg Flanke SCK CALL VERZ1 BANKSEL TRISB ; Ausgang B0 für Acknowledge aktiv setzen movlw 0xF0 ; Bit 0-3=AUS, Bit 4-7=EIN,Int on change movwf TRISB BANKSEL PORTB return ;;;;;;;;;;;;;;;;;;;;;; ACKNOWLEDGE FRAM LESEN ABFRAGEN ;;;;;;;;;;;;;;;;; ACKSLV BANKSEL TRISB ; Ausgang B0 für Acknowledge hochohmig setzen movlw 0xF1 ; Bit 0=EIN, Bit 1=AUS,Bit 4-7=EIN,Int on change movwf TRISB BANKSEL PORTB bsf PORTB,1 ; pos Flanke SCK CALL VERZ1 bcf PORTB,1 ; neg Flanke SCK return ;;;;;;;;;;;;;;;;;;;;;; ACKNOWLEDGE FRAM LESEN BESTÄTIGEN ;;;;;;;;;;;;;;; ACKLES BANKSEL TRISB ; Ausgang B0 für Acknowledge aktiv setzen movlw 0xF0 ; Bit 0=AUS, Bit 1=AUS,Bit 4-7=EIN,Int on change movwf TRISB BANKSEL PORTB bcf PORTB,0 bsf PORTB,1 ; pos Flanke SCK CALL VERZ1 bcf PORTB,1 ; neg Flanke SCK BANKSEL TRISB ; Ausgang B0 für Acknowledge hochohmig setzen movlw 0xF1 ; Bit 0-3=AUS, Bit 4-7=EIN,Int on change movwf TRISB BANKSEL PORTB return ;;;;;;;;;;;;;;;;;;; SEKUNDEN ÜBERLAUF BIT VERKNÜPFEN ;;;;;;;;;;;;;;;;;;; SEKUBL rrf SEK3STR ; Überlaufbit Bit0 nach Bit7 schieben rrf SEK3STR movfw SEK3STR xorwf TEMPLSB return ;;;;;;;;;;;;;;;;;;; VERZÖGERUNG 2 DRAHT BUSTAKT ;;;;;;;;;;;;;;;;;;;;;;;; VERZ1 movwf SICHW ; Working Register sichern movlw 0x01 movwf SEK3 VZG1: decfsz SEK3 GOTO VZG1 movfw SICHW ; Working Register sichern return ;;;;;;;;;;;;;;;;;;; VERZÖGERUNG 2 DRAHT BUSTAKT ;;;;;;;;;;;;;;;;;;;;;;;; VERZ2 movwf SICHW ; Working Register sichern movlw 0x07 movwf SEK3 VZG2: decfsz SEK3 GOTO VZG2 movfw SICHW ; Working Register sichern return ;;;;;;;;;;;;;;;;;;; VERZÖGERUNG LÜCKE ÜBERBRÜCKEN ;;;;;;;;;;;;;;;;;;;;;;; VERZ3 ;GOTO Y2 ; NUR ZUM TESTEN !!!!! clrf VZL movlw 0xFE movwf VZLUEK VZG3: decfsz VZL GOTO VZG3 decfsz VZLUEK GOTO VZG3 Y2 btfss PORTB,4 ; Ist INT Ein noch 0 ? clrf LUECK bsf PORTB,3 ; LED INT deaktivieren return ;;;;;;;;;;;;;;;;;;; VERZÖGERUNG START AUFNAHME ;;;;;;;;;;;;;;;;;;;;;;;;; VZSTR ;GOTO Y1 ; NUR ZUM TESTEN !!!!! clrf VZL movwf SICHW ; Working Register sichern movlw 0x1F movwf VZLUEK ; ist jetzt frei und kann hier benutzt werden VZST1: decfsz VZL GOTO VZST1 decfsz VZLUEK GOTO VZST1 Y1 NOP ; NUR ZUM TESTEN !!!!! bsf PORTB,3 ; LED INT deaktivieren return ;;;;;;;;;;;;;;;;; INTERRUPT / UHR / ZEITGEBER PROGRAMM ;;;;;;;;;;;;;;;;; UHR incf MILSEK btfss MILSEK,3 ;3 GOTO SEKEND clrf MILSEK btfsc TONAKT,1 ; Ist Ton aktiv ? incf DAUER incfsz SEK1 GOTO SEKEND incfsz SEK2 GOTO SEKEND incf SEK3 SEKEND: bcf INTCON,2 ; Interrupt Flag wieder zurücksetzen clrf TMR0 ; 7.996 HZ, mit 4.194304 MHZ, prescale :256 ;movlw 0xFD ; NUR ZUM TESTEN !!!!! ;movwf TMR0 ; NUR ZUM TESTEN !!!!! movfw PORTB return END