diff options
-rw-r--r-- | Binaeruhr.asm | 577 |
1 files changed, 118 insertions, 459 deletions
diff --git a/Binaeruhr.asm b/Binaeruhr.asm index af3a785..b2a2bbe 100644 --- a/Binaeruhr.asm +++ b/Binaeruhr.asm @@ -7,32 +7,24 @@ .INCLUDE "tn2313def.inc"
-.EQU sbuff0, 0 ; serieller Puffer 0 bis
-.EQU sbuff1, 1
-.EQU sbuff2, 2
-.EQU sbuff3, 3
-.EQU sbuff4, 4 ; 4
-.EQU lastB, 5 ; letzter Zustand von PINB
-.EQU lt1p0l, 6 ; letzte Flankenposition PINB0 (Timer 1) low
-.EQU lt1p0h, 7 ; dito high
-.EQU lt1p1l, 8 ; dito PINB1 low
-.EQU lt1p1h, 9 ; dito high
-.EQU bcnt0, 10 ; Bitzähler PINB0
-.EQU bcnt1, 11 ; Bitzähler PINB1
-.EQU t1moml, 12 ; momentane Position Timer 1 low
-.EQU t1momh, 13 ; dito high
-.EQU aender, 14 ; Änderungen in PINB
+.EQU Spalte, 31
+.EQU TicsH, 30
+.EQU TicsL, 29
+.EQU nTicsL, 28
+.EQU Stunde, 0
+.EQU Minute, 1
+.EQU Sekunde, 2
rjmp RESET
reti
reti
reti
+ rjmp TIMER1COMPA ; Timer1 Compare Match A
reti
reti
reti
reti
- reti
- rjmp TIMER0COMPA ; Timer0 Compare Match A
+ reti
reti
reti
reti
@@ -50,452 +42,119 @@ ldi r16,0x00
out CLKPR,r16 ; System-Vorteiler auf 1
- ldi r16,0x03
- out PRR,r16 ; Clocks: Timer/Counter 1 an, Timer/Counter 0 an, USI aus, ADC aus ... zum Stromsparen
- ldi r16,0x00
- out WDTCSR,r16 ; Watchdog aus
-
- ldi r16,0x02
- out PORTA,r16 ; 6x n.d., PORTA1 high (RS232-Sender), kein Pull-up an PORTA0 (RS232-Empfänger)
- ldi r16,0x00
- out PORTB,r16 ; 2x n.d., kein Pull-up an PORTB1 (IR-Empfänger 1) & PORTB0 (IR-Empfänger 0)
- ldi r16,0x06
- out DDRA,r16 ; Ausgänge: PORTA1 (RS232-Sender), PORTA2 (Test)
- ldi r16,0x00
- out DDRB,r16 ; keine Ausgänge auf PORTB
-
- ldi r16,0x02 ; Timer0 Compare-Match-A Interrupt an
- out TIMSK0,r16
-
- ldi r16,104
- out OCR0A,r16
- ldi r16,0x02 ; CTC-Modus: Periode = OCR0A = 104 -> 9600 baud
- out TCCR0A,r16
- ldi r16,0x02 ; Vorteiler 8 für Timer 0
- out TCCR0B,r16
-
- ldi r16,0x02 ; Vorteiler 8 für Timer 1
- out TCCR1B,r16
-
- ldi r16,0x21 ; Start-Bit und
- mov sbuff0,r16
- ldi r16,0x15 ; 0x48 ('H') und Start-Bit und
- mov sbuff1,r16
- ldi r16,0x56 ; 0x61 ('a') und Start-Bit und
- mov sbuff2,r16
- ldi r16,0x48 ; 0x21 ('!') und Start-Bit
- mov sbuff3,r16
- ldi r16,0x0d ; und 0x0d (CR)
- mov sbuff4,r16
-
- in lt1p0l,TCNT1L
- in lt1p0h,TCNT1H
- movw lt1p1l,lt1p0l
-
- in lastB,PINB
- ldi r16,0x03
- and lastB,r16
-
- sei
-
-MAINLOOP:
- in r16,PINB
-
- andi r16,0x03
- eor r16,lastB
- breq MAINLOOP ; keine Änderung
-
- eor lastB,r16 ; Änderung übernehmen
- mov aender,r16 ; Änderungen merken
-
- in t1moml,TCNT1L
- in t1momh,TCNT1H ; Zählerstand holen
- movw r16,t1moml ; und kopieren
-
- sbrs aender,0
- rjmp PIN0WACKELTNICHT
-
- sub r16,lt1p0l
- sbc r17,lt1p0h ; r17:r16 = TimeDiff
-
- movw lt1p0l,t1moml ; aktuellen Zählerstand als alten setzen
-
- subi r16,0xb1
- sbci r17,0x01 ; - 865/2 = 0x01b1 = halbes Bit
-
- brcs RESET0 ; zu kurzes Bit -> Fehler!
-
- subi r16,0x61
- sbci r17,0x03 ; - 865 = 0x0361 = kurzes Bit
- brcc KEINKURZESBIT0
-
- clr r16 ; wird einfach gespeichert!
- inc bcnt0
- rjmp WEITER0
-KEINKURZESBIT0:
- subi r16,0x61
- sbci r17,0x03 ; - 865 = 0x0361 = (noch ein) kurzes Bit (= langes Bit)
- brcc RESET0 ; zu langes Bit -> Fehler
-
- inc bcnt0
- inc bcnt0
- ldi r16,0x01 ; wird doppelt gespeichert!
-
-WEITER0:
- clc
- sbrs lastB,0 ; alten Pinzustand
- sec ; nach C
- lds r17,(0x0060) ; das erste der insgesamt vier Bytes von empfangenen Bits
- rol r17
- sts (0x0060),r17
- lds r17,(0x0061)
- rol r17
- sts (0x0061),r17
- lds r17,(0x0062)
- rol r17
- sts (0x0062),r17
- lds r17,(0x0063)
- rol r17
- sts (0x0063),r17
- brcs RESET0 ; es kamen mehr als 32 Bits an -> Fehler!
-
- subi r16,0x01
- brcc WEITER0
-
- ldi r16,0x1a
- cp bcnt0,r16
-
- brcs ENDE0 ; noch keine 26 klein-Bits angekommen -> Ende
-
- ldi r16,0x1c
- cp bcnt0,r16
- brcc RESET0 ; mehr als 27 klein-Bits angekommen -> Fehler!
-
- sbrs lastB,0 ; jetziger Zustand ist high?
- rjmp ENDE0 ; nein -> dann ist es auch nicht fertig!
-
- lds r16,(0x0063) ; das letzte Byte
- ori r16,0x40 ; die übrigen Bits (also die Bits, die eben nicht empfangen wurden)
- sts (0x0063),r16 ; des zuerst "empfangenen" Bytes werden alternierend auf 1 gesetzt
-
- ldi r26,0x60
- ldi r27,0x00 ; Startadresse in den Speicher,
- mov r16,bcnt0 ; Bitanzahl in r16
- rcall VERSENDEN ; und ab durch die serielle Schnittstelle
-
-RESET0:
- ldi r16,0x05 ; Startbit + '01'=0 (also 0. Empfänger)
- sts (0x0060),r16
- ldi r16,0x00
- sts (0x0061),r16
- sts (0x0062),r16
- sts (0x0063),r16 ; empfangene Bits initialisieren
- clr bcnt0 ; Bit-Zähler auf 0 setzen
-
-ENDE0:
-PIN0WACKELTNICHT:
-
- sbrs aender,1
- rjmp MAINLOOP
- movw r16,t1moml ; Zählerstand rücksichern
-
- sub r16,lt1p1l
- sbc r17,lt1p1h ; r17:r16 = TimeDiff
-
- movw lt1p1l,t1moml ; aktuellen Zählerstand als alten setzen
-
- subi r16,0xb1
- sbci r17,0x01 ; - 865/2 = 0x01b1 = halbes Bit
-
- brcs RESET1 ; zu kurzes Bit -> Fehler!
-
- subi r16,0x61
- sbci r17,0x03 ; - 865 = 0x0361 = kurzes Bit
- brcc KEINKURZESBIT1
-
- clr r16 ; wird einfach gespeichert!
- inc bcnt1
- rjmp WEITER1
-KEINKURZESBIT1:
- subi r16,0x61
- sbci r17,0x03 ; - 865 = 0x0361 = (noch ein) kurzes Bit (= langes Bit)
- brcc RESET1 ; zu langes Bit -> Fehler
-
- inc bcnt1
- inc bcnt1
- ldi r16,0x01 ; wird doppelt gespeichert!
-
-WEITER1:
- clc
- sbrs lastB,1 ; alten Pinzustand
- sec ; nach C
- lds r17,(0x0064) ; das erste der insgesamt vier Bytes von empfangenen Bits
- rol r17
- sts (0x0064),r17
- lds r17,(0x0065)
- rol r17
- sts (0x0065),r17
- lds r17,(0x0066)
- rol r17
- sts (0x0066),r17
- lds r17,(0x0067)
- rol r17
- sts (0x0067),r17
- brcs RESET1 ; es kamen mehr als 32 Bits an -> Fehler!
-
- subi r16,0x01
- brcc WEITER1
-
- ldi r16,0x1a
- cp bcnt1,r16
-
- brcs ENDE1 ; noch keine 26 klein-Bits angekommen -> Ende
-
- ldi r16,0x1c
- cp bcnt1,r16
- brcc RESET1 ; mehr als 27 klein-Bits angekommen -> Fehler!
-
- sbrs lastB,1 ; jetziger Zustand ist high?
- rjmp ENDE1 ; nein -> dann ist es auch nicht fertig!
-
- lds r16,(0x0067) ; das letzte Byte
- ori r16,0x40 ; die übrigen Bits (also die Bits, die eben nicht empfangen wurden)
- sts (0x0067),r16 ; des zuerst "empfangenen" Bytes werden alternierend auf 1 gesetzt
-
- ldi r26,0x64
- ldi r27,0x00 ; Startadresse in den Speicher,
- mov r16,bcnt1 ; Bitanzahl in r16
- rcall VERSENDEN ; und ab durch die serielle Schnittstelle
-
-RESET1:
- ldi r16,0x03 ; Startbit + '10'=0 (also 1. Empfänger)
- sts (0x0064),r16
ldi r16,0x00
- sts (0x0065),r16
- sts (0x0066),r16
- sts (0x0067),r16 ; empfangene Bits initialisieren
- clr bcnt1 ; Bit-Zähler auf 0 setzen
-
-ENDE1:
-PIN1WACKELTNICHT:
-
- rjmp MAINLOOP
-
-TIMER0COMPA:
+ out WDTCSR,r16 ; Watchdog aus
+
+ ldi r17,0xd0
+ ldi r16,0x55
+ out OCR1AH,r17
+ out OCR1AL,r16 ; TimerB bis 0xd055 laufen lassen (= 300 Hz)
+ ldi r16,0x09
+ out TCCR1B,r16 ; no prescaler
+ ldi r16,0x40
+ out TIMSK,r16 ; Counter1 Output Compare A Match Interrupt Enable
+
+ ldi r16,0x55
+ out PORTB,r16 ; Muster auf PORTB (Zeilen)
+ ldi r16,0x0c
+ out PORTD,r16 ; 2x n.d., 2x Pull-up (Taster), Muster auf Spalten
+ ldi r16,0xff
+ out DDRB,r16 ; Ausgänge: PORTB (Zeilen)
+ ldi r16,0x70
+ out DDRD,r16 ; Ausgänge: PORTD4..6 (Spalten)
+
+ ldi Spalte,1
+ ldi r16,0x12
+ mov Stunde,r16
+ ldi r16,0x34
+ mov Minute,r16
+ ldi r16,0x56
+ mov Sekunde,r16
+
+ ldi nTicsL,100
+
+ sei
+
+main_loop:
+ cp nTicsL,TicsL
+ brcc main_loop
+ mov r16,nTicsL
+ subi r16,0x80
+ mov r17,TicsL
+ subi r17,0x80
+ cp r16,r17
+ brcc main_loop
+
+neue_Sekunde:
+
+ ldi r16,100
+ add nTicsL,r16
+
+ sbis PIND,2
+ rjmp neue_Stunde
+ sbis PIND,3
+ rjmp neue_Minute
+
+ inc Sekunde
+ mov r16,Sekunde
+ cpi r16,61
+ brcs main_loop
+
+neue_Minute:
+
+ clr Sekunde
+ inc Minute
+ mov r16,Minute
+ cpi r16,61
+ brcs main_loop
+
+neue_Stunde:
+
+ clr Sekunde
+ clr Minute
+ inc Stunde
+ mov r16,Stunde
+ cpi r16,25
+ brcs main_loop
+
+ clr Stunde
+
+ rjmp main_loop
+
+TIMER1COMPA:
push r16
in r16,SREG
push r16
-
- sbrc sbuff0,0
- sbi PORTA,1
- sbrs sbuff0,0
- cbi PORTA,1
-
-; clc ; so werden die Daten zyklisch gesendet
-; sbrc r0,0
- sec
-
- ror sbuff4
- ror sbuff3
- ror sbuff2
- ror sbuff1
- ror sbuff0
-
+ push r17
+ ldi r17,0x07
+ out PORTD,r17
+
+ inc Spalte
+ cpi Spalte,2
+ brne nicht_Stunde_Anzeigen
+ ldi r17,0x60
+ mov r16,Stunde
+ rjmp anzeigen
+nicht_Stunde_Anzeigen:
+ cpi Spalte,3
+ brne nicht_Minute_Anzeigen
+ ldi r17,0x50
+ mov r16,Minute
+ rjmp anzeigen
+nicht_Minute_Anzeigen:
+ ldi r17,0x30
+ mov r16,Sekunde
+ subi Spalte,3
+ inc TicsL
+ brne anzeigen
+ inc TicsH
+anzeigen:
+ com r16
+ ori r17,0x0c
+ out PORTB,r16
+ out PORTD,r17
+ pop r17
pop r16
out SREG,r16
pop r16
-
- reti ; TIMER0COMPA
-
-WARTEAUFSENDBUFFER: ; wartet, bis der Sende-Puffer leer ist
- ldi r16,0xff
- cp sbuff4,r16
- brne WARTEAUFSENDBUFFER
- cp sbuff3,r16
- brne WARTEAUFSENDBUFFER
- cp sbuff2,r16
- brne WARTEAUFSENDBUFFER
- cp sbuff1,r16
- brne WARTEAUFSENDBUFFER
- cp sbuff0,r16
- brne WARTEAUFSENDBUFFER
- ret ; WARTEAUFSENDBUFFER
-
-VERSENDEN: ; versendet r16/2+1 Bit Manchester-kodierte Daten
- ; aus DRAM, Adresse r27:r26 (=X), base64-kodiert
-
- movw r18,r26 ; Speicheradresse merken
- sbrc r16,0
- rjmp VERSENDENNICHTSCHIEBEN
- sec
- ld r17,X
- rol r17
- st X+,r17
- ld r17,X
- rol r17
- st X+,r17
- ld r17,X
- rol r17
- st X+,r17
- ld r17,X
- rol r17
- st X+,r17
- movw r26,r18
-VERSENDENNICHTSCHIEBEN:
- lsr r16
- ldi r17,0x0d
- cpse r16,r17 ; nicht 26 halb-Bits?
- ret ; -> Fehler!
-
-; ld r18,X+
-; ld r18,X+
-; ld r18,X+
-; ld r17,X+
-; clr r16
-; rjmp AUSLESESCHLEIFENENDE
-
- ldi r20,0x03
-ALTERNIERENDTESTSCHLEIFE:
- ld r16,X+
- mov r17,r16
- lsr r16
- eor r16,r17
- andi r16,0x55
- ldi r17,0x55
- cpse r16,r17 ; Bits alternierend?
- ret ; nein -> Ende!
-
- subi r20,0x01
- brcs ALTERNIERENDTESTSCHLEIFEENDE
- rjmp ALTERNIERENDTESTSCHLEIFE
-ALTERNIERENDTESTSCHLEIFEENDE:
-
- movw r26,r18
- clr r18
- clr r17
- clr r16
-
- ldi r19,0x10 ; 16 Bits zu lesen (13 reale Bits + 3 Geistbits)
-AUSZENSCHLEIFE:
- ld r20,X+
- ldi r21,0x04 ; 4 Bits je Byte
-INNENSCHLEIFE:
- ror r20
- ror r20
- rol r18
- rol r17
- rol r16
- subi r19,0x01
- breq AUSLESESCHLEIFENENDE
- subi r21,0x01
- brne INNENSCHLEIFE
- rjmp AUSZENSCHLEIFE
-AUSLESESCHLEIFENENDE:
-
- ; die zu sendenden 18 Bit Informationen liegen in r16(2):r17(8):r18(8)
-
- rol r18
- rol r17
- rol r16
- rol r18
- rol r17
- rol r16
-
- lsr r18
- lsr r18
-
- rol r17
- rol r16
- rol r17
- rol r16
-
- lsr r17
- lsr r17
-
- rcall TOBASE64
- push r16
- mov r16,r17
- rcall TOBASE64
- push r16
- mov r16,r18
- rcall TOBASE64
- push r16
- ; die zu sendenden Zeichen liegen auf dem Stack (3., 2., 1.)
- rcall WARTEAUFSENDBUFFER
-
- cli
-
- clc
-
- ; aus logistischen Gründen füllen wir den Puffer von hinten nach vorne
-
- ldi r16,0x0d ; 0x0d (CR)
- mov sbuff4,r16
-
- pop r17
- ldi r16,0x40
- sec
- ror r17
- ror r16
- ror r17
- ror r16
- mov sbuff3,r17
-
- pop r17
- swap r17
- mov r18,r17
- andi r18,0x0f
- or r16,r18
- mov sbuff2,r16
-
- andi r17,0xf0
- ori r17,0x04
- pop r18
- clr r16
- clc
- rol r18
- rol r16
- sec
- rol r18
- rol r16
- or r16,r17
- mov sbuff1,r16
-
- mov sbuff0,r18
-
- sei
-
-VERSENDENENDE:
- ret ; VERSENDEN
-
-TOBASE64: ; konvertiert Bit 0-5 von r16 in base64
- ; 0-25: A-Z: +0x41 (=-0xbf)
- ; 26-51: a-z: +0x47 (=-0xb9)
- ; 52-61: 0-9: -0x04
- ; 62: +: -0x13
- ; 63: /: -0x10
- andi r16,0x3f ; zur Sicherheit
- cpi r16,26
- brcc NICHT0BIS25
- subi r16,0xbf
- ret ; TOBASE64
-NICHT0BIS25:
- cpi r16,52
- brcc NICHT26BIS51
- subi r16,0xb9
- ret ; TOBASE64
-NICHT26BIS51:
- cpi r16,62
- brcc NICHT52BIS61
- subi r16,0x04
- ret ; TOBASE64
-NICHT52BIS61:
- cpi r16,63
- brcc NICHT62
- subi r16,0x13
- ret ; TOBASE64
-NICHT62:
- subi r16,0x10
- ret ; TOBASE64
-
-
+ reti
|