From c5b83c4a7c5ac7816b33618d99588add7bcacf91 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Fri, 6 Nov 2020 22:07:54 +0100 Subject: Binaeruhr.asm: Pooin-Stand erreicht --- Binaeruhr.asm | 577 ++++++++++++---------------------------------------------- 1 file 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 -- cgit v1.2.3-54-g00ecf