Ich verwende das 130428 Sende-Empfangsset von Corad.
Allerdings habe ich eben gesehen, dass die Dinger gut an Preis zugelegt haben...
Bis jetzt habe ich nur den Empfangsseitigen Teil beschrieben. Hoffe, dass ist was geworden. Wenn das jemand komplett ließt, bin ich für eine kurze Meinung zu haben - also von wegen sinnvoller Aufbau der Beschreibung etc. Das Prog ist sicher noch nicht optimal, aber es arbeitet. Vor dem lesen am besten erst mal das Bild ansehen, ich weiß leider nicht, wie ich das mache, dass man es nicht extra öffnen muss, sondern so sehen kann.
Normalerweise muss man den Sender mit Manchestercode versorgen, den ich aber nicht codieren kann.
Da ich dann raugefunden habe, dass es auch möglich ist, bis zu einer bestimmten Frequenz HIGH LOW
Signale zu übertragen, bin ich dazu übergegangen, über Pulsweiten log. einsen und nullen zu
übertragen. Zudem ist die Eigenschaft wichtig, dass durch dauerhaftes anlegen eines High Signales am Sender
der Empfänger definiert LOW gehalten werden kann, außerdem wird der Empfänger ohne Signal von anderen Quellen
gestört.
Grobes Prinzip der Übetragung:
Das Prinzip des Senders ist, dass in ein Register ein Bitmuster geladen wird.
An diesem Register wird das MSB auf eins oder null getestet. Anhand vom Ergebnis wird die nächste
Pulsweite entweder lang oder kurz. Danach wird ein logic left shift ausgeführt. Das Ganze dann acht mal.
Im Empfänger wird auf ein Register ERST (und das ist wichtig) ein lsl angewendet und dann
je nach Pulslänge das Register mit einer ori 0b00000001 Operation erhöht oder auch nicht. Auch
dass muss sinngemäß achtmal passieren. Gemessen wird
die Dauer zwischen zwei externen Interrupten. Dabei wird bei jedem logik Wechsel getriggert.
Sind die achtmal erreicht, wird das Register ausgelesen und entsprechend der Kodierung eine Aktion
ausgeführt.
Für das Verständis des Systems ist es am besten auf der Empfangsseite anzufangen.
Bei der Entwicklung des Sederprog´s wurde auch hier begonnen.
Das erste Problem das es zu behandeln gilt ist, dass solange der Sender kein Signal gibt, der Empfänger
undefiniert schaltet. Deshalb befinden sich die prozessrelevanten Register in einem
undefinierten Zustand.
Das sind:
TCCR wird nicht im INIT Code gesetzt
TCNT zur Teitmessung
shf das Register aus dem das gesendete Bitmuster ausgelesen wird
shfc in diesem Register wird gezählt, wie oft der ext. INT. erfolgte (das c steht für counter)
Um genau das zu beheben, dient die lange Pulsdauer zu Beginn des Sigales. Im Empfänger wird bei einem
Comparematch mit OCR2 = 100 ein Interrupt ausgelößt, in dessen ISR (definiren) die oben genannten
Register = 0 gesetzt werden.
Ab dem ersten LOW Pegel danach sind die Intervalle zu kurz, um einen Comparematch zu triggern
und es läuft nur noch die ISR des ext Int. (inter). Zu jedem Anfang wird der TIMER mit Prescaler = 64 gestartet,
obwohl das nur beim ersten mal nötig währe.
Das nullsezten von TCNT passiert "manuell" am Edne der ISR.
Für das spätere verstehen der Programme ist es wichtig, zu beachten, das shfc nach dem Fall der ersten
Flanke bereits = 1 ist, ohne das schon ein Bit übertragen wurde.
Steigt die Flanke wieder, passiert das selbe. Erst ab dem Fallen des rot makierten HIGH Pegels findet
die erste relevante Zeitmessung statt. Diese Zeit wird aber erst während des grün makierten LOW Pegels ausgewertet.
Aus diesem Zusammenhang folgert bereits, das ein Pegel mehr existiert (gelb), als man vielleicht erstmal für nötig hält.
Daher endet shfc letztendlich auch bei 11, die sich im Sendeprogramm wiederfinden wird!
Diese 11 sind 3 mehr, als für das einlesen von 8 Bit nötig sind und OH, welch wunder, diese Differenz findet sich
im Proramm des Empfängers. (Kommentar dazu im Code)
Hat shfc den WERT 11 errreicht, wird shf ausgelesen.
[/url]Code:.include "m8def.inc" .def shf = r20 .def tmp = r16 .def shfc = r21 .def aus = r22 .def zeit = r23 .def merker = r24 .def an = r25 .def timer = r17 .org 0x0000 rjmp reset .org INT1addr rjmp inter .org OC2addr rjmp definieren reset: ;Stack wird bei Interrupts benötigt! ldi r16,HIGH(RAMEND) out SPH,r16 ldi r16,LOW(RAMEND) out SPL,r16 ldi tmp,0b00000100 out MCUCR,tmp ;int @ ext logicchange ldi tmp,0b10000000 out GICR,tmp ldi tmp,0b11110111 out DDRD,tmp com tmp out PORTD,tmp ldi tmp,0b00001000 out DDRB,tmp ldi tmp,0b10000000 out TIMSK,tmp ;int @ OCR2 ldi timer,0b00000100 ;out TCCR2,timer ldi tmp,100 out OCR2,tmp sei ldi aus,0 ldi an,255 mainloop: ; wie cool, das Programm läuft ; ohne einen MAIN Code - BÄM! rjmp mainloop definieren: out TCCR2,aus ldi shf,0 ldi shfc,0 ;out PORTD,aus out TCNT2,aus reti inter: inc shfc out TCCR2,timer cpi shfc,2 ;da der shfc Wert des letzten Pegels keine Rolle spielt, brlo later ;da dort nur die letzte Zeit verarbeitet wird, lsl shf ;ergibt sich mit der 2 die Different von drei in tmp,TCNT2 cpi tmp,45 ;Schwellwert für log eins oder null brlo lognull ori shf,1 lognull: ;________________________________________ cpi shfc,10 ; brlo later ;wenn shfc 10 ist, ;wurden die 8 BIT in shf cpi shf,0b00010001 ;eingelesen und können verarbeitet breq on ;werden. Hier mit dem setzten oder cpi shf,0b00010010 ;löschen vom PINB 3 breq off ; rjmp nocommand ; ; on: ; ldi tmp,0b00001000 ; out PORTB,tmp ; rjmp nocommand ; off: ; ldi tmp,0 ; out PORTB,tmp ; nocommand: ;_________________________________________ mov tmp,shf andi tmp,0b11110111 out PORTD,tmp ;dient zur visuellen Kontrolle des eingegangenen Befehls ldi shfc,0 ; und während der Entwicklungszeit für so manche Überraschung^^ ldi shf,0 out TCCR2,aus later: out TCNT2,aus reti
Lesezeichen