Ich denke mal das Problem liegt hier:
header_recive:
rcall Recive
dec Count
cpi Count, 0
brne header_recive
cbi PORTD, 6
ldi Data, 0x06
rcall Transmit
entweder du machst das "cpi Count, 0" weg oder ersetzt es durch
"cpi count, 0x00"
Condi wrote:
> entweder du machst das "cpi Count, 0" weg oder ersetzt es durch> "cpi count, 0x00"
Ersetze XYZ durch XYZ oder "den Teufel mit Beelzebub austreiben"? Die
beiden Ausdrücke sind gleichwertig (und in Assembler sogar tatsächlich,
da nicht Case-sensitiv und dementsprechend count = Count)...
Hallo Florentin,
weshalb fängst Du wieder von vorne und mit den selben Problemen an ?
Diesmal rettest Du gar nichts auf den Stack und plötzlich nimmst
Du nur noch 1 Stoppbit....
Gruss Otto
Laut meinem Mega32 Datenblatt ist:
ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
8n2
Der Code ist zwar nicht so schön, aber er sollte funktionieren. Wenn
0x15 empfangen wurde, wir der Interrupt disabled und dann wird immer
geprüft ob wieder was empfangen wurde.
Bei Neustart sollte halt anstelle des rjmp loop ein reti stehen. Das
Problem liegt in der Schleife, die ich schon erwähnte, die scheint nicht
0 zu werden.
Du solltest mehr Anzeigen in die Schleifen machen, damit du mehr infos
bekommst.
Wegen den Warteschleifen: Der Taschenrechner ist so lahm, dass der µC
sich etwas gedulden muss, bevor er die Handshakes usw senden darf. An
sonsten ist der Taschenrechner noch nicht zum Empfangen bereit und das
Gesendete geht verloren.
Theoretisch könnte man den µC wahrscheinlich mit 4MHz oder so laufen
lassen, würde locker reichen. Vielleicht geht sogar noch weniger.
nop
dec temp
cpi temp, 0
brne wait0_1
wenn Du temp verringerst, wird das ZeroFlag Erst gesetzt, wenn temp NULL
ist.
Daher ja auch BRNE. Du brauchst keinen zusätzlichen Vergleich mittels
CPI temp,0 machen. Das macht der Controller von Hause aus.
dec temp
brne wait0_1
reicht daher.
Stimmt eigentlich, die Bootloader FuseBits hätten es auch sein können.
Tschuldige.
@Michael
Warum hast du in deinem Programm keine Warteschleifen drin?
Ich war immer der Meinung 9600 Baud ist 9600 Baud egal ob der MC mit
1Mhz läuft oder 16Mhz, zumindest bei HW-UART.
vom µC aus gesehen stimmt das auch. Nur beim Taschenrechner anscheinend
nicht. (Ev hat der nen Software-uart oder so was.)
Im Protokoll isses so, dass der GTR (=Taschenrechner) etwas sendet und
dann der µC das bestätigen soll. Wenn das Bestätigungsbyte aber zu
schnell nach Empfang der Daten gesendet wird, hat der GTR anscheinend
ein Problem und erkennt das Byte nicht.
@ Michael Frangenberg
danke nochmal für deine Hilfe gestern. Mein ICQ ging irgendwie nichtmehr
an.
Ich werde heute mal versuchen die Daten zu speichern und wenn das Klappt
das Programm für allgemeine Übertragungen bereit machen also das mit der
Datenlänge aus header etc. Am besten wäre je eigentlich zum speichern
nen externer EEprom oder Sram. Das müsst ich mir noch besorgen.
Hallo Florentin,
das kann es auch nicht - aus mehreren Gründen aber der Reihe nach:
Du solltest zuerst mal "aufräumen"
1. vor brne muß kein cpi, wenn Du auf "0" vergleichst
2. den Z-Pointer mußt Du auch initialisieren (z.B. auf Ramstart)
3. es heißt "receive"
Otto
Hallo Florentin,
auf RAMSTART zu initialisieren geht z.B. so:
Z_INIT: ldi temp, LOW(RAMSTART) ; Wert LO initialisieren
mov ZL, temp ; Z-Register low
ldi temp, HIGH(RAMSTART) ;
mov ZH, temp ; Z-Register high
ret
Verstehe es bitte nicht falsch - Du solltest Deinen Code
zuerst mal aufräumen, sonst findet sich evtl. keiner, der
Lust hat, sich da durch zu wühlen.....
Gruss Otto
Welches Modell hast du genau?
@Michael
Du hast 8Mhz verwendet, d.h. du hättest mindestens auch die Hälfte der
"Waitstates" einlegen müssen. Zumindest (9850, 32kb, schwarz) bei meinem
funktioniert auch 8n1 und Mega162 mit 14,7Mhz. Naja und mit dem PC
klappt es ja auch....
Was ich so gefunden habe, scheint der schon mindestens ein UART zu
haben, nur keine Interrupts bzw. halt deaktiviert.
Hallo Florentin,
der Warteschleife solltest Du ein 2. Register
spendieren und nicht mit "push" und "pop"
arbeiten.
Die im SRAM gespeicherten Konstanten werden
von den Routinen überschrieben - da kann ich
keinen Sinn erkennen.
Beispiel:
den Z-Pointer (R30 und R31) hast Du mittels:
ldi r30,LOW(Content)
ldi r31,HIGH(Content)
auf die Adresse von "content" gelegt.
ldi Count, 16
ldi r30,LOW(Content)
ldi r31,HIGH(Content)
data_receive: rcall Receive
st Z+, Data
dec count
brne data_receive
mit "st Z+" speicherst Du Daten ab dieser
Adresse und überschreibst damit
"END_Header"
Gruss Otto
wieso überschreib ich damit das nächste. Ich verstehe das jetzt so ich
sezt den Z Pointer auf Content lede Byte für Byte data_receive ein und
lade anschliesend den Pinter auf die Nächste adresse...
Hallo,
ldi r30,LOW(Content)
ldi r31,HIGH(Content)
data_receive: rcall Receive
st Z+, Data
dec count
brne data_receive
> sezt den Z Pointer auf Content
ja, aber sndchliessend durchläufst Du
16 x Data_receive und speicherst die Daten
mit Z+ d.h. die Daten werden gespeichert
unter
content
content+1
content+2
..
..
Oder doch nicht? Und wenn es falsch ist wie könnte ich den Code ändern?
Damit es funktioniert, wie es soll. Ich habe da leider noch nicht soviel
Erfahrung.
wieso in der inrerrupt Routine? Die wird doch vor dem speichern und
laden aufgerufen...
ps: das war doch das Status register...wo stand das nochmal im tut?
so es geht!!!! es lag allerdings nicht an fehlerhafter programmierung,
sondern das das Rechner protokoll falsch ausgewertet wurde. und die
variable an der Falschen stelle eingelesen wurde. hier nochmal das
neuste:
so kaum ist das eine Problem gelöst hat man auch schon das nächste am
Hals. ich wollte jetzt machen, das man mehrere Dioden via Rechner an und
aus schalten kann...aber jetzt gehts nimmer. Das äusert sich in sofern,
dass das prog einmal durchläuft auch ordentlich kommuniziert mit dem
Reechner...aber keine Diode geht an. Und wenn ich dann ein zweites mal
was sende was vorher ging kommt jetzt nen Error.
die überprüft die vom Rechner gesendete Variable auf den einen Wert der
dann die entsprechende LED aktiviert. Hä die ist doch schon aktiviert.
Die wird dann nur später deaktiviert und am ende wieder aktiviert.
Also wenn ein Interrupt ausgelöst wird, aber die Bedingung nicht erfüllt
ist springter inne Schleife. Interrupt ist aber noch aktiv...und wenns
erfolgreich war springt er zu header_init und da wird sie deaktiviert
und am ende aktiviert wenn die Übertragung komplett ist.
Hallo Florentin,
>die überprüft die vom Rechner gesendete Variable auf den einen Wert der
dann die entsprechende LED aktiviert.
Kannst Du das Programm vom GTR mal bitte in den Anhang stellen?
Dann kann man das evtl. hier mal nachvollziehen.
Danke
AxelR.
ok ein Problem hätte ich gelöst...und zwar hatte ich immer nur versucht
2 zu senden und genau die LED war falsch angeschlossen auf dem
Steckbrett. Aber es bleibt immer noch das Problem, das es nicht mehr
richtig weiter empfängt nach einer Übertragung und das ich auf dem
Rechner immer nen Error erhalte. Ich vermute es springt nicht richtig
zurück, weil ich weitere Unterroutinen Aufrufe.
und zwar im simulator springt er nach dem Anschalten der dieode via ret
in diee loop. Da liegt das problem. Aber wison springt er nicht dorthin
zurück, von wo die funktion aufgerufen wurde???
so...also es liegt daran das ret nicht wieder dahin zurückspringt, weil
ich die Funkt, ja nicht mit call aufgerufen aheb das konnte garnicht
gehen...so hier der Aktuelle Code: