hallo, ich mach der Übersichtlichkeit mal nen Neuen Thread auf. Ich wandle gerade mein ASM Script in C um...Jetzt kommt wider mal eine Warnung von Inkompatiblen Typen in der Funktion Transmit0. Codes im Anhang
Wie wärs denn, wenn du dich etwas präziser äußern würdest, wie die Warnung genau lautet und wo sie erzeugt wird?
Ist sonst alles korrekt? chmod 755 GTR.elf -------- end -------- GTR.c:46: warning: implicit declaration of function 'Transmit0' GTR.c: At top level: GTR.c:64: warning: conflicting types for 'Transmit0' GTR.c:46: warning: previous implicit declaration of 'Transmit0' was here Build succeeded (3 warnings)
Eine Funktion muss bei ihrem Aufruf bekannt sein. Transmit0 wird in der ISR aufgerufen, aber erst nach der ISR definiert. Deshalb kennt der Compiler beim Aufruf von "Transmit0" keine Funktion dieses Namens und vermutet, dass der Aufruf eine implizite Deklaration sein soll. Lösung: Entweder die Definition von Transmit0 vor dem ersten Aufruf oder am Anfang eine Prototypen-Deklaration.
OK Vielen Dank! Ist das mir dem Return richtig um aus der Interrupt routine raus zu kommen?
hier der Aktuelle...könnt ihr bitte schauen, ob alles passt? Fehler und Warnungen kommen keine. Wie setzt ich das Wait aus dem ASM in C um?
Florentin S. wrote: > OK Vielen Dank! Ist das mir dem Return richtig um aus der Interrupt > routine raus zu kommen? Nö. Eine Funktion, die keinen Wert zurückgibt, braucht auch kein return. Das Ende der Funktion ist die schließende Klammer "}". Wenn die Funktion Transmit0 beendet ist, gehts mit der "}" am Ende zurück in die ISR und aus der dann mit der entsprechenden Klammer zurück ins Programm.
ok ich denk ich hab mich dumm ausgedrückt...es geht um die Stelle:
1 | ISR(USART0_RXC_vect) |
2 | {
|
3 | |
4 | //Interrupt Routine für UART0
|
5 | if (UDR0 != 0x15) { |
6 | //Wen Handshake nicht 0x15 war...
|
7 | return; |
8 | |
9 | }else{ |
10 | //Wenn Handshakebyte 0x15 war...
|
wenn das empfangene Byte nicht 0x015 war soll es das interrupt verlassen. Im Asm ist das durch ret gelöst.
ok die For Schleifen waren schon mahl falsch..statt < muss hin <=...
Florentin S. wrote: > ISR(USART0_RXC_vect) > { > > //Interrupt Routine für UART0 > if (UDR0 != 0x15) { > //Wen Handshake nicht 0x15 war... > return; > ... > wenn das empfangene Byte nicht 0x015 war soll es das interrupt > verlassen. Im Asm ist das durch ret gelöst. In ASM wirklich ret und nicht reti? Ich sehe keinen Fehler bei der C-Variante. Tipp: Du kannst dir das erzeugte Assemblerlisting ansehen. Mit dem korrigierten Makefile aus deinem anderen Thread wird ein GTR.lss erzeugt - da ist C-Code und produzierter Assemblercode sichtbar.
also in asm wars mit reti. Wie trag ich das denn ins makefile ein, das es den ASM Coder erzeugt? hier der Ausschnitt aus asm:
1 | Receive0_int: |
2 | |
3 | in data, sreg |
4 | push data |
5 | in Data, UDR0 ; Empfangenes Byte in Data speichern |
6 | cpi Data, 0x15 |
7 | breq header_init |
8 | pop data |
9 | out sreg, data |
10 | reti ; zur�ck zum Hauptprogramm |
wie realisiere ich nun die Waitschleife wie im ASM? Edit mit dem Ret habe ich mich verschrieben. Jetzt verstehe ich, was du meinst...
Florentin S. wrote: > wenn das empfangene Byte nicht 0x015 war soll es das interrupt > verlassen. Im Asm ist das durch ret gelöst. Die Abfrage an sich ist nicht sonderlich sinnvoll. Dreh sie doch einfach um, dann kannste Dir das "else" komplett sparen.
1 | if (UDR0 == 0x15) |
2 | Transmit0(0x13); |
Im Falle von "UDR0 != 0x15" soll ja sowieso nichts gemacht werden, außer die ISR wieder zu verlassen...
ok ich war mir nicht sicher, ob er die schleife verlässt, wenn ich das nicht festlege. Ich habe noch keine Große Erfahrung mit C!
Florentin S. wrote: > ok ich war mir nicht sicher, ob er die schleife verlässt, wenn ich das > nicht festlege. Ich habe noch keine Große Erfahrung mit C! Wo ist denn da eine Schleife? "if" ist nur eine Abfrage (Verzweigung, bedingte Ausführung)! Hat mit einer Schleife überhaupt nichts zu tun. "while" und "for" sind Schleifen...
sorry hatte mich versprochen...meinte natürlich verzweigung. Wie setze ich das Wait um? Im Momment läuft der Code nämlich noch nicht...
irgend was stimmt nicht...an den Seriellen schnitstellen fliest gar kein Strom. beim ASM tut es das.
also bei der ASM Variante liegen an G und TX 5V an...bei C 0 Strom...
Wenn Du den kompletten Inhalt von main auskommentierst, dann wird auch nichts initialisiert. Abgesehen davon willst Du doch wohl nicht ernsthaft erzählen, dass Du den Strom an der Schnittstelle misst, oder? Ich hoffe, der Unterschied zwischen Strom und Spannung ist Dir geläufig...
Oh...das war noch der Code, den Stefan korrigiert hatte. In meinem Editor, wird das nicht deutlich gemacht. Ja ich hab die Spannung gemessen. Natürlich nicht den Strom ^
da wäre auch geklärt, warum die Fehler weg waren...jetzt kommt wieder: GTR.c:25: error: 'USR1C' undeclared (first use in this function) GTR.c:25: error: 'URSEL' undeclared (first use in this function) GTR.c:25: error: 'USBS' undeclared (first use in this function) GTR.c:25: error: 'UCSZ1' undeclared (first use in this function) GTR.c:25: error: 'UCSZ0' undeclared (first use in this function) GTR.c:26: error: 'USR0C' undeclared (first use in this function) GTR.c:29: error: 'RXCIE' undeclared (first use in this function) GTR.c:29: error: 'RXEN' undeclared (first use in this function) GTR.c:29: error: 'TXEN' undeclared (first use in this function) Build failed (9 errors)
Dann hast Du vermutlich im Makefile bzw. AVRStudio den Controllertyp nicht angegeben...
so jetzt liegt Spannung an...ist nur noch das Problem mit dem wait...
Normalerweise haben Aufrufe von Senderoutinen u.ä. nichts in einem Interrupt Handler zu suchen. Das kann zu Kollisionen und Datenverlust führen! Zu den Wartezeiten: Schau Dir in der libc-Doku mal die Funktionen aus der util/delay.h an. Da könnte was für Dich dabei sein.
anders gehts leider nicht. Also irgendwie bekomme ich am Zielgerät (Taschenrechner) immer einen Com Error. Irgendwas muss aner der Anzah oder so falsch sein...
ich hab auch schon mit verschiedenen wartewerten gespielt...
gibts keinen, der ASM und C kann und mir sagen kann, wo der Unterschied zwischen den beiden Programmen liegt? Hier nochmal die Verkürzte ASM Variante. Soweit, wie ich in C bin:
Nochmal der Tipp vorn mir: Lass dir beim Übersetzen das Listingfile GTR.lss erzeugen (dein Makefile aus der anderen Diskussion macht das schon) und vergleiche den erzeugten Code selbst. Du scheinst ja ASM-KEnntnisse zu haben. Im Moment fehlt deinem main() nach der UART-Initialisierung die Endlosschleife. Möglicherweise harmlos, wenn der C-Startupcode (der Code von der Library, der vor main() ausgeführt wird) nach Verlassen von main() selbst eine Endlosschleife ausführt. Wenn du wie in deinem Code keine Funktionsprototypen benutzt (was nicht empfohlen ist), solltest du die Funktionen im Code definieren bevor sie verwendet werden. Statt pauschalem int (2 Bytes Speicherbedarf) solltest du den kleinstmöglichen Datentyp (hier char, wenn du Vorzeichen willst. Ansonsten besser unsigned char) benutzen. Spart auch heftig Speicher bei den beiden Puffern. Deine Assemblersource funktioniert so nicht. Es soll das Label header_init angesprungen werden und das fehlt in der Source. Ebenso das Label Datarequest0, das Label data_receive, das Label Transmit, ... Mir sieht die ASM-Routine header_init0 derzeit ziemlich vergurkt aus. Es ist nicht sinnvoll, daraus eine genauso vergurkte C-Source zu machen. Bringe vielleicht zuerst die ASM-Source in Ordnung oder erzähle was in deinem Protokoll gemacht werden soll. Wann kommen die Handshakebytes, wann und vorallem warum wird vorm Senden eine halbe µC-Ewigkeit (0,5s!!!) gewartet.
Der asm Code war der Falsche sorry. Der andere Funktioniert. (Anhang). Was soll ich am Assembler noch optimieren? Das warten ist so lange, da das Ziel (Taschenrechner) ziemlich lahm ist. Eine lss wird erzeugt aber sie sieht komisch aus, also der Inhalt.
und der Aktuelle C code: hier das Taschenrechner Protokoll: http://www.frangenberg.info/zeug/GTRprotokoll.pdf
Die Wartezeit ist wohl ein empirischer Wert, den ich so in dem PDF nicht finde. In deinem Assemblercode komme ich auf ca. 4,35 ms Wartezeit in der Transmit0 Funktion und nicht auf ca. 500 ms wie in deinem C-Code. Bitte prüfe die Wartezeit z.B. mit einer blinkenden LED. Ein Frequenzunterschied von 2 Hz (1/500ms beim C-Code) und 230 Hz (1/4,35ms beim ASM_Code) sollte man mit nacktem Auge sehen. Wenn ich richtig liege, könnte man statt der Schleife direkt _delay_ms(4.35) benutzen. Den Restcode habe ich nicht genauer analysiert. Der ASM-Code hat wesentlich mehr Funktionen als der C-Code. Hier kann man sich erst weiter machen, wenn obiges geklärt ist. Funktioniert ein ASM-Code, der nur die Funktionalität des abgespeckten C-Codes hat oder muss im C-Code mehr als bisher programmiert werden (abgesehen davon dass richtig programmiert werden muss)? Programmtechnisch ist die Auswertung des Protokolls innerhalb der Interruptroutine sehr schlechter Programmierstil. Man muss das anders machen z.B. Protokollführung innerhalb der while(1) Schleife von main und die Interruptroutine nur verwenden, um die Daten beim Empfang zu schaufeln und zu signalisieren, dass Daten da sind, die in main ausgewertet werden können. Insbesondere wenn noch mehr Funktionen aus dem PDF umgesetzt werden sollen bist du derzeit rasch in der Sackgasse. Deine Denkweise mit dem C-Interrupt ist übrigens auch eine essentielle Quelle fürs Nichtfunktionieren: Der Interrupt wird bei JEDEM empfangenem Zeichen angesprungen und nach dem Auslesen von UDR0 ist UDR0 futsch. D.h. durch den Vergleich mit dem 0x15 gehen alle anderen Zeichen verloren. Im ASM-Code wird UDR0 vor dem Vergleich in eine globale Variable Data umkopiert, das funktioniert dann. Und in Verbindung mit 500ms warten... da hat der GTR ist schon die paar Bytes auf die Leitung gepackt und auf dem µC ist es bereits in dem ISR-Gulli. Ein besserer C-Code sähe so aus:
1 | // Vorspann wie gehabt
|
2 | |
3 | volatile unsigned char ucUDR = 0; // 1 Byte Puffer |
4 | volatile unsigned char ucUDR_valid = 0; // Anzeige ob Puffer gefüllt oder leer |
5 | volatile unsigned int uiVerloreneZeichen; |
6 | |
7 | ISR(USART0_RXC_vect) |
8 | {
|
9 | if (ucUDR_valid) |
10 | {
|
11 | uiVerloreneZeichen++; |
12 | // Die Auswertung dieser Zahl kann später helfen, wenn man den
|
13 | // 1 Byte Puffer in einen Mehrbyte-Puffer nach dem FIFO Prinzip
|
14 | // umrüsten will. Damit kann man eine Abschätzung der günstigen
|
15 | // Puffergrösse vornehmen.
|
16 | }
|
17 | |
18 | ucUDR = UDR0; |
19 | ucUDR_valid = 1; |
20 | // Nicht mehr!
|
21 | }
|
22 | |
23 | int Receive0(void) |
24 | {
|
25 | while (!ucUDR_valid) |
26 | {
|
27 | }
|
28 | ucUDR_valid = 0; |
29 | return ucUDR; |
30 | }
|
31 | |
32 | int main(void) |
33 | {
|
34 | // UART init wie gehabt...
|
35 | |
36 | while(1) |
37 | {
|
38 | if (Receive0() == 0x15) |
39 | {
|
40 | // hier kommt der Rest aus der alten ISR
|
41 | Transmit0(0x13); //Header Init 0 |
42 | |
43 | // Header Rrecieve 0
|
44 | for (Count=0; Count < 50; Count++) |
45 | {
|
46 | //Header speichern
|
47 | Header[Count] = Receive0(); |
48 | }
|
49 | |
50 | // Handshakebyte
|
51 | Transmit0(0x06); |
52 | |
53 | // Data Receive
|
54 | for (Count=0; Count < 16; Count++) |
55 | {
|
56 | Content[Count] = Receive0(); |
57 | }
|
58 | |
59 | // Handshakebyte
|
60 | Transmit0(0x06); |
61 | |
62 | // Endheader lesen aber dann verwerfen
|
63 | for (Count=0; Count < 50; Count++) |
64 | {
|
65 | Receive0(); |
66 | }
|
67 | |
68 | // Handshakebyte
|
69 | Transmit0(0x06); |
70 | }
|
71 | }
|
72 | }
|
73 | |
74 | // Rest wie gehabt
|
Vielen Dank ich werde deinen Code bei Gelegenheit umsetzen. Das mit dem Wait habe ich geändert. Allerdings funktioniert es immer noch nicht. Die korrekte Auswertung des Protokolls ist erstmal Nebensache. Das kommt später. Erstmal müssen die Handshakebytes an der richtigen stelle kommen. Und das tuen sie im Moment nicht.
so ich habe jetzt nochmal deinen Code als Grundlage genommen. Jetzt muss ich ihn nur noch verstehen. Aber Es kommt trotzdem noch ein Com Error.
noch was. Wie mache ich das, wenn ich die beiden Schnittstellen brauche?
So wie ich das verstanden habe wird nach jedem Empfangenen Zeichen ein Interrupt ausgelöst. Also liefert die Receive Schleife erst das Byte zurück. wenn was empfangen wurde.
> Aber Es kommt trotzdem noch ein Com Error. Also dem GTR stinkt was an der Übertragung. Das kann eine falsche Einstellung sein (nicht 9600 Baud 8N2 wie im PDF genannt). Oder es kann falscher Anlauf der Übertragung sein. Benutzt du die gleiche Hardware für das C-Programm wie für das ASM-Programm und flashst jeweils das Versuchsobjekt? Anders gefragt: kann es an einem Unterschied an der µC Taktung (z.B. unterschiedliche Fuses-Einstellung) liegen, dass die Baudrate nicht stimmt? Ich würde hingehen und die Übertragung mit einem PC und einem PC-Terminalprogramm testen. Sehr hut dafür ist das Br@y-Terminal geeignet, welches im RS232-Artikel aufgeführt ist. Zu beantwortende Fragen: 1/ Stimmt 9600 8N2 seitens des GTR? Stimmt 9600 8N2 seitens des µC? wenn 2/ und 3/ die erwarteten Hexzeichen bringen, kann man das bejahen. 2/ Was schickt der GTR bei manuellem Ausführen der Protokollsequenz zum PC? Ist die Sequenz überhaupt zeitkritisch? Der PC simuliert den µC. 3/ Was schickt der µC bei manuellem Ausführen der Protokollsequenz zum PC? Ist die Sequenz zeitkritisch? Der PC simuliert den GTR. Alles andere ist Fischen im Trüben.
ja mit dem PC habe ich mir auch schon gedacht. Aber das wird etwas kompliziert. Die Platine ist fertig gelötet. Und ich bräuchte ja noch einen Pegelwandler, den Ich so ja nicht drauf bekomme. Und ja ich benutze für ASM und für C das gleiche Zielobjekt. Dara kann es also nicht liegen. Es muss irgendwo ein Fehler im Code sein.
braucht der Pegelwandler das Gleiche VCC wie der µC? Sonst bau ich den auf nen Steckbrett mit extra Netzteil...da hab ich aber nur 4.5V da reicht das?
Florentin S. wrote: > So wie ich das verstanden habe wird nach jedem Empfangenen Zeichen ein > Interrupt ausgelöst. Also liefert die Receive Schleife erst das Byte > zurück. wenn was empfangen wurde. Lass es mich so sagen: Dein alter C-ISR Code frisst Zeichen weg, wenn der Vergleich mit 0x15 gemacht wird. Die alte Receive-Schleife in C funktioniert überhaupt nicht, weil du noch im ISR steckst. Solange du im ISR bist, sind alle Interrupts gesperrt. Da geht nix. Dein ASM-ISR Code frisst Zeichen weg, macht aber vorher eine Kopie. Die alte Receive-Schleife in ASM funktioniert, weil du dich inzwischen mit Rumspringen mit rjmp und den vielen eingestreuten reti Blöcken aus der ISR herausgewuschtelt hast.
Florentin S. wrote: > braucht der Pegelwandler das Gleiche VCC wie der µC? Sonst bau ich den > auf nen Steckbrett mit extra Netzteil...da hab ich aber nur 4.5V da > reicht das? Kommt auf den Pegelwandler an. Die Kenndaten stehen im Datenblatt. Ein normaler MAX232 für Vcc=5V müsste auch mit 4,5V funktionieren. 4,5V ist der untere Wert bei den recommended operation conditions. Hast du keinen anzapfbaren Pegelwandler auf der Platine, um an den GTR zu gehen? Sind dort direkte TTL-Pegel auf der Leitung? OK, ja so ist es, ich sehe es gerade bei http://www.lamepage.de/hardware/casio/index.html
mist mein max232 ist glaube kaputt...selbst it dem Rechner bekomme ich kein Signal.
der Fehler scheint aber ziemlich am Anfang zu sitzen. Denn er kommt fast unmittelbar nach dem Senden.
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.