So ich bin den besagten Zettel mal durchgegangen, und hab das ein wenig umsortiert.
Vorüberlegungen:
-je Telegramm gibt es immer 49 fallende Flanken an der clock. Uns interessieren nur die letzten 24 vor der allerletzten. (also wenn man die von 49 bis 1 runternummeriert, interessieren uns die Flanken 25 bis 2. Flanke 1 ist insofern noch interessant, als daß man dort sicher weiß, daß jetzt ein komplettes gültiges Paket empfangen wurde.
-jeder Kanal benötigt 3 Bytes, um das 24bit-Wort abzulegen. Habe grad nochmal gesehen, das als erstes das LSB gesendet wird (deswegen "nach rechtsschieben/rollen"). Kann sein, daß bei meinem folgenden Code-Schnipsel dann die Benennung der Bytes falschrum ist(*).
diese 3 Bytes müssen in Bascom angelegt (und somit dort lesbar) sein, trotzdem brauch ich die exakte SRAM-Adresse in der ISR. Außerdem sollten sie 3 aufeinanderfolgende Speicherzellen belegen. Deswegen Definition mit AT und ggf Overlay.
-Jeder Kanal braucht außerdem einen Zähler für die Flanken, Definition und so wie beim vorherigen Punkt.
Ich gehe einfachheitshalber davon aus, daß alle 12 Registeradressen dasselbe Highbyte haben, und für jeden Kanal als erstes der Flankenzähler, und dann die 3 Werteregister(Bytes) im Speicher liegen.
In der ISR wird als erstes der Flankenzähler dekrementiert (ist ja ein count down), und wenn er dabei 0 wird, wieder mit 49 geladen (Z-Flag). deswegen interessieren mich danach nur die Flanken [24..1], alle Flanken > 24 werden verworfen, die 0 wurde ausgeschlossen. Zum synchronisierten Scharfschalten kann relativ einfach in Bascom die lange Pause
nach der letzten fallenden Flanke abgewartet werden. Der Flankenzähler ist also mit 49 vorzuladen.
Der Aufruf der ISR selbst sollte mit nosafe erfolgen, da die verwendeten 3 Register und das SREG in der ISR gesichert/wiederhergestellt werden. Das ganze müßte in Bascom in der entsprechenden ISR dann als ASM-Block eingebunden werden, dabei wird das Reti im ASM-Block durch ein Return nach diesem (oder schluckt Bascom eine ISR ohne abschleißendem Return (wenn in der ISR bereits das ASM-RETI steht?).
Ok, hier mal die ISR für einen Kanal:
Code:
ch1_ISR:
;Register sichern
push r16 ;R16->Stack
in r16, sreg
push r16 ;SREG->Stack
push xh ;XH->Stack
push xl ;XL->Stack
ldi xh, high(BitCountAddr1)
ldi xl, low(BitCountAddr1) ;X->BitCounter von Kanal 1
ld r16, x ;r16=BitCounter
dec r16 ;decrementiere
brne ch1_reloaded ;wenn =0 ***********(skip-Befehl???)
ldi r16, 49 ;reload mit 49
ch1_reloaded:
st x+, r16 ;BitCounter gespeichert, x->highByte
cpi r16, 25 ;wenn größer 24, dann
brsh ch1_BitVerwerfen ;springe Bit verwerfen
cpi r16, 17 ;wenn größer 16
brsh ch1_ByteLaden ;springe ByteLaden
inc xl ;X->middleByte
cpi r16, 9 ;wenn größer 8, dann
brsh ch1_ByteLaden ;springe ByteLaden
inc xl ;X->lowByte
ch1_ByteLaden:
;X zeigt jetzt auf die SRAM-Adresse, wo der Datapin
;einzuschieben ist
clc ;Carry=0
sbic port1, pin1 ;Datapin gelesen, wenn=1
sec ;dann Carry=1
;Zustand des DataPins im Carry gespeichert
ld r16, x ;Speicherzelle eingelesen
ror r16 ;Carry (Data) eingeschoben
st x, r16 ;zurückgespeichert (RMW)
ch1_BitVerwerfen:
;Register wiederherstellen
pop xl ;XL<-Stack
pop xh ;xh<-Stack
pop r16
out sreg, r16 ;SREG<-Stack
pop r16 ;r16<-Stack
reti
Wie gesagt scheinen das Highbyte und das lowbyte des 24bit-Ergebnisses so vertauscht zu sein, das könnte aber noch korrigiert werden.
BitCountAddr1 ist die SRAM-Adresse des Bitzählers, siehe oben. Port1 ind Pin1 sind Adresse und Bitnummer des Beinchens, an dem die entsprechende Data-Leitung des MS hängt. Die Takte hab ich jetzt noch nicht zusammengerechnet. Sieht bis jetzt schon irgendwer grobe Fehler und/oder Optimierungsmöglichkeiten? Dino?