Hallo zusammen, wie der Betreff schon sagt, habe ich einen ATMega324PA und möchte beide USART's mit Interrupts verwenden. Ich habe das Ganze mal in einem minimalen Programm komprimiert, erstmal nur für eine Schnittstelle. Die Sende-/ und Empfangsdaten sollen in einem Ringspeicher abgelegt werden. Wichtiger sind mir die Empfangsdaten an dieser Stelle. Die Senderoutine kann ich zur Not auch ohne ISR basteln. Im Anhang findet ihr meinen aktuellen Code. In der Main prüfe ich, ob sich der Schreib-/ und Lesepointer unterscheiden und möchte daraufhin ein Byte aus dem Speicher laden und an den PC zurückschicken. Das Delay am Ende ist aktuell auskommentiert. So funktioniert es nicht! Wenn ich das Delay einkommentieren dann funktioniert die Kommunikation. Kleiner als 2ms darf ich den Delay aber auch nicht machen und bei vielen Daten überholt der Schreib-/ den Lesepointer. Warum braucht der Knecht diese Auszeit? Er Antwortet mir ohne den Delay nichtmal auf einzelne Bytes... Der Prozessor läuft mit einem 14,7456 Mhz Quarz bei 115200 Baud. Die Fuse-Bits stehen auf High = 0xD9 und Low = 0xFF. Ich hoffe ich habe alle wichtigen Infos gegeben. Gruß, Zitrone
Gast
#3278826
Hi, ich habe auf nem Atmega16 mal ne kommunikation mit Sendefifo und Interrupt gabastelt, und habe aber nicht den UDRE (Uart Data register empty)interrupt benutzt, sondern den TXC (transmition complete). Ich glaube mich zu erinnern, dass ich ähnliche Probleme hatte, wenn der Tx-Interrupt kam, bevor die Daten komplett gesendet wurden. Versuchs doch mal damit. vg. Norbert
Gast
#3278848
Nachtrag: Für Tx-complete musst Du allerdings immer das Erste Byte manuell senden, wenn der Sendebuffer zuvor leer war. Die folgenden folgende Queue kann dann vom Interrupt geleert werden.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
Und wieder mal: VOLATILE ! FAQ: Was hat es mit volatile auf sich
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
ist der _delay nicht drinnen, hat der Compiler genug Register frei um sich die Werte für ptrRecWrite bzw. ptrRecRead in CPU-Registern halten zu können. Da passiert einfach zu wenig in der Hauptschleife, als das er die Werte jedesmal aus dem Speicher nachladen müsste.
Julian B. schrieb: > Kleiner als 2ms darf ich den Delay aber auch nicht machen und bei vielen > Daten überholt der Schreib-/ den Lesepointer. Könnte ein Hinweis auf einen weiteren Fehler sein, auch wenn ich beim Drüberscrollen nichts mehr gesehen habe. Aber ergänze mal das fehlende volatile an den Pointer Variablen. Und dann sieht man weiter.
Hallo zusammen, danke für die Antworten. @ Norbert: Das habe ich im Vorfeld auch schon ausprobiert. Habe es gerade aber nochmal gemacht. Allerdings ohne Erfolg die Daten (0xAA, 0xBB, 0xCC) werden korrekt ausgegeben aber Daten annehmen will der Knecht nicht. Schade. @ Karl Heinz: Entschuldige bitte, dass ich die Version ohne volatile hochgeladen habe. Volatile ist mir bekannt und benutze ich auch da wo es sinnvoll ist. Ich habe die Variablen jetzt wie folgt Deklariert:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Leider auch ohne Erfolg. Das habe ich im Vorfeld auch schon mehrfach ausprobiert mal mit mal ohne usw..... volatile sollte an dieser Stelle natürlich verwendet werden. Leider besteht das Problem mit den empfangenen Daten weiterhin. Ich verstehe nur leider nicht warum...
Julian B. schrieb: > Leider auch ohne Erfolg. Logisch. Ist ja auch falsch geschrieben
1 | |
2 | |
Der Pointer Wert selber ist volatile. Nicht das worauf er zeigt. D.h. eigentlich ist das auch volatile. Also
1 | |
2 | |
Diese Modifier wirken immer von rechts nach links. Es sei denn, der Modifier steht schon ganz links, dann wirkt er auf das Teil rechts von ihm
1 | |
Das Volatile bezieht sich auf den Pointer, denn der * steht links von ihm
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
1 | |
Das volatile bezieht sich auf den uint8_t, denn der steht links von ihm. Der Pointerwert selber ist nicht volatile, wohl aber das worauf er zeigt.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
1 | |
selber Fall. das volatile bezieht sich auf den uint8_t, weil das volatile schon ganz links steht. Du vergleichst die Pointer Werte (und nicht das worauf die Pointer zeigen). Ergo müssen die Pointer Werte volatile sein. Mit
1 | |
sind sie es aber nicht. Und zu guter letzt
1 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Gast
#3278917
noch ne möglichkeit dem volatile zu entgehen (für teste obs daran liegt). Ein nicht optimierter Code braucht in der Regel kein volatile d.h. wenn Du das Ding mit -O0 übersetzt und es läuft und be -O2 läufts nicht mehr, dann kanst Du davon ausgehen, irgendwo ein fehlendes volatile zu haben.
Hier der aktuelle Stand: Volatile hat in keiner Form was gebracht (Habe alle ausprobiert) Bei den Version
1 | |
schickt der Prozessor mir permanent 0x00..... Die Optimierung habe ich mal ausgeschaltet. Bringt aber auch nichts, außer dass die Anfangswerte 0xAA,0xBB und 0xCC nicht mehr ausgegeben werden... Ich werde mir da noch einige Gedanken zu machen.
Julian B. schrieb: > Hier der aktuelle Stand: > > Volatile hat in keiner Form was gebracht Gut. Nichts desto trotz gehört es da rein. Sagt ja keiner, dass das das einzige Problem im Code ist.
Gast
#3279159
Ich würde statt Pointern übrigens mit Indizes rechnen. Dann laufen die beiden Pointer von 0..BUFSIZE-1, was bei Zweierpotenzen ziemlich einfach zu berechnen ist. Auf die Daten greifst du dann mit buf[read_idx] zu.
Hey Svenska, die Idee mit den Indizes hatte ich kurz vor Feierabend dann auch. Ist denke ich auch verständlicher als die Spielerei mit den Pointern... Ich werde das morgen mal ausprobieren. Ich danke euch erstmal und werde berichten :) Gruß
Tag zusammen, habe den Fehler gefunden... Er lag nicht an der Software. Ich habe einen Kurzschluss auf meinem Board gehabt. Zwischen RX und TX... Den Fehler habe ich gefunden nachdem ich auf Indizes umgestiegen bin. Im Anhang der Code mit Indizes... Danke für eure Hilfe!
Und hier noch die Version mit Pointern...(s. Anhang)
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.