Hallo Foren-User,
ich arbeite z.Zt. an einer Datenübertragung zwischen 2 Attiny2313.
Dabei übertrage ich 16 Bytes über eine lange Leitung (zum Test ca. 60m
Telefonleitung ungeschirmt auf einer Rolle).
Die Übertragung startet mittels Taster am Sender und läuft eigentlich
fehlerfrei (mit internem Oszilator!!!).
Die übermittelten Bytes werden dann beim Empfänger im EEPROM
abgespeichert.
Der Sender schickt die Bytes fehlerfrei auf die Leitung, dies kann
ich mit einem digitalen Speicheroscilloskope sehen.
Nur beim Empfang verschwindet das 1.Byte im Nirvana und wird nicht im
EEPROM abgelegt.
Was mach ich da falsch?
Es ist aber auch nur das 1.Byte, bei der 1. Übertragung NACH DEM
EINSCHALTEN der beiden µController.
danach läuft alles bestens. Die Daten werden dann hintereinander im
EEPROM abgelegt und da sind dann alle Bytes richtig vorhanden!!!
Hier der Assembler-Code, der sich in meiner Interruptroutine befindet
und über URXCaddr ausgelöst wird:
int_rxc:
push temp ;temp auf dem Stack sichern
laden: sbis UCSRA,rxc ;naechsten Befehl überspringen wenn Empfang
fertig
rjmp laden ;warten bis Daten uebertragen sind
in daten1, UDR ;Empfangenes Byte nach Daten1 schreiben
EEwrite:
sbic EECR,EEPE ;warten vom schreiben des vorherigen
Bytes,cleared wenn bereit
rjmp EEwrite ;schreiben in EEPROM fortsetzen
out EEAR, eeadr ;Adresseposition in EEAR schreiben
out EEDR,daten1 ;Empf.Byte ins EEPROM speichern
sbi EECR,EEMPE ;EEPROM Master Write Enable
sbi EECR,EEPE ;EEPROM Write Enable
back1: cpi eeadr,$7f ;Adresse EEPROM auf 128 überpruefen(voll)
brne back
ldi eeadr,$ff ;eeadr auf $ff setzen,da +1 $00 ergibt
back: inc eeadr ;EEPROM Adressposition erhoehen
pop temp ;temp wiederherstellen
reti ;Interrupt beenden
Wie gesagt, NUR nach dem Einschalten des Systems geht das 1.Byte
verloren, sonst nicht.
Danke schon mal im Vorraus!
Caesy
sbis UCSRA,rxc Solltest du dir sparen (können), wenn du sowieso mit einem Interrutp arbeitest. Die RXC-Abfrage braucht man nur im Poll-Betrieb. Deswegen verschwindet auch dein erstes Byte: Du wartest in der RXC-ISR auf das nächste. Das RXC-Flag wird AFAIK bein Eintritt in die ISR gelöscht. (Warte-)Schleifen in ISR sind sowieso "bäh!". Du solltest in der RXC-ISR das Byte in einen (Ring-)Puffer schreiben und dann in der Hauptschleife eine EEPROM-Schreib-Routine aufrufen (während der man die Interrupts ausschaltet).
Also die Startadresse EEADR fängt bei $00 an. Wenn ich auf: sbis UCSRA,rxc verzichte, wird nichts mehr im EEPROM gespeichert,habs grad getestet. "Das RXC-Flag wird AFAIK bein Eintritt in die ISR gelöscht." kann ich nicht bestätigen, da ja ab der 2.Übertragung ja alle Bytes fehlerfrei vorhanden sind.
Wirf mal ein Blick auf Seite 14 des Datenblattes: "... and hardware clears the corresponding interrupt flag." Naja, lass das "rjmp laden" auch weg...
ok, das mit der Schleife hatte ich tatsächlich vergessen,hihi! Doch jetzt gehen mir die Inhalte der nachfolgenden Bytes flöten, auf unbestimmte Anzahl, da wird $00 in den Bytes 2 bis 4 abgelegt und dann geht es entsprechen richtig weiter $05...$10. Aber das 1. Byte ist immer noch nicht vorhanden.
Wie oben schon geschrieben: Der EEPROM-Zugriff hat in der ISR nichts zu
suchen!
Wie sich das mit Interrupts und EEPROM verhält, ist bestimmt im
Datenblatt beschrieben.
>Aber das 1. Byte ist immer noch nicht vorhanden.
Schade!
Aber wie kann ich das ausserhalb der ISR machen, wenn eine Übertragung 16 Bytes enthält. Hat da jemand Tips für mich?
>Hat da jemand Tips für mich?
(Ring-)Puffer.
Das müsste man sogar in Assembler relativ einfach hinbekommen.
> Das RXC-Flag wird AFAIK bein Eintritt in die ISR
gelöscht.
Das Flag wird gelöscht, wenn UDR gelesen wird.
MW
>Das Flag wird gelöscht, wenn UDR gelesen wird.
Stimmt! (Seite 127 im Datenblatt...)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.