Hey, ich habe ein Problem mit dem UART. Ich nutze die library von Peter Fleury. Egal was ich am Programmcode ändere, sobald uart_puts oder uart_putc aufgerufen wird, passiert gar nichts mehr und der AVR scheint festzuhängen. Der Code ist sicher alles andere als perfekt, aber einen Fehler finde ich nicht. Solange keine UART-Ausgabe erfolgen soll, funktioniert alles wie gewünscht. Auf einem ATMEGA 32 bekomme ich das Programm (bezüglich der Register leicht angepasst) zum Laufen. Mit dem ATMEGA 328 passt irgendwas nichts. Sobald die UART-Ausgabe erfolgen soll, passiert gar nichts mehr. An keinem Pin findet noch eine Änderung statt. Auch bei der Auskommentierung großer Teile des Codes und/oder einer direkten string Ausgabe wie "uart_puts("Hallo Welt")" passiert nichts. Ich habe zwei ATMEGA 328 und einen 168 getestet. Es funktioniert nur mit dem ATMEGA 32. Es wäre toll wenn jemand eine Idee bzw. einen Tipp für mich hätte. Viele Grüße Daniel
Dir ist bewusst das ATMega32 und ATMega328 nicht codecompatibel sind? Beispiel: ATMega32 --> USART Control and Status Register A – UCSRA ATMega328 --> UCSRnA – USART Control and Status Register n A Die Funktionsweise könnte gleich sein, die Namen sind aber definitiv anders. beste grüße
Daniel H. schrieb: > Egal was ich am Programmcode ändere, sobald uart_puts oder > uart_putc aufgerufen wird, passiert gar nichts mehr Dann nimm doch erstmal alles andere raus. Und wir suchen auch nicht raus, wo man eine Fleury-Lib findet und wieviel Versionen es davon gibt.
Moin, public schrieb: > Dir ist bewusst das ATMega32 und ATMega328 nicht codecompatibel sind? beide AVRs sind eigentlich entsprechend in der library definiert. Auf einem weiteren ATMega328 befindet sich ein sehr ähnliches Programm, bei dem die Ausgabe über UART problemlos funktioniert. Ich kann mir das wirklich nicht erklären. Peter D. schrieb: > Und wir suchen auch nicht raus, wo man eine Fleury-Lib findet und > wieviel Versionen es davon gibt. sry, irgendwie habe ich so oft von der lib gelesen, dass ich wohl dachte die sei quasi allgemein bekannt. Könnte ich nach etwas bestimmten suchen, das vielleicht fehlt oder falsch definiert wurde? Peter D. schrieb: > Dann nimm doch erstmal alles andere raus. Daniel H. schrieb: > Auch bei der Auskommentierung großer Teile des Codes und/oder einer > direkten string Ausgabe wie "uart_puts("Hallo Welt")" passiert nichts. Ich habe das Programm sowohl stückweise auskommentiert, als auch den Code auf das nötigste beschränkt. Der Tx-Pin bleibt dauerhaft auf "high" und der AVR macht gar nichts mehr, sobald eine Ausgabe erfolgen sollte. Viele Grüße Daniel
Daniel H. schrieb: > sry, irgendwie habe ich so oft von der lib gelesen, dass ich wohl dachte > die sei quasi allgemein bekannt. Nö. Daniel H. schrieb: >> direkten string Ausgabe wie "uart_puts("Hallo Welt")" passiert nichts. Und warum postest Du es dann nicht so?
Da steckt viel zu viel Zeug und Kram in deiner ISR. Nimm all diese Textbearbeitung raus, und tue das in der main(). Und Delays haben in einer ISR NIX verloren!!
Eric B. schrieb: > Da steckt viel zu viel Zeug und Kram in deiner ISR. Nimm all diese > Textbearbeitung raus, und tue das in der main(). > Und Delays haben in einer ISR NIX verloren!! Abgesehen davon, sehe ich in dem gezeigten Code weder eine Freigabe des INT0 noch eine globale Interruptfreigabe. Edit: Ach doch, das sei() ist in der Hauptschleife.
:
Bearbeitet durch User
Hallo, aber das Compilersettinh "Controller" wurde auf 328 umgestellt? Oder versuchst du das selbe HEX auf einem anderen Controller laufen zu lassen?? Gruß Jochen
Daniel H. schrieb: > beide AVRs sind eigentlich entsprechend in der library definiert. Auf > einem weiteren ATMega328 befindet sich ein sehr ähnliches Programm, bei > dem die Ausgabe über UART problemlos funktioniert. Ich kann mir das > wirklich nicht erklären. Und du bist dir sicher, dass es kein Hardwarefehler ist? Was sagt denn der Compiler zum Code? Immer dran denken: Es gibt keinen Grund Warnings zu ignorieren. Ich gehe also davon mal aus, dass der Compiler weder moppert noch meckert.
Peter D. schrieb: > Daniel H. schrieb: >>> direkten string Ausgabe wie "uart_puts("Hallo Welt")" passiert nichts. > > Und warum postest Du es dann nicht so? das habe ich doch so gepostet :/ Eric B. schrieb: > Da steckt viel zu viel Zeug und Kram in deiner ISR. Nimm all diese > Textbearbeitung raus, und tue das in der main(). > Und Delays haben in einer ISR NIX verloren!! ist das nur sehr unschön oder eine definitive Fehlerquelle? J.-u. G. schrieb: > Abgesehen davon, sehe ich in dem gezeigten Code weder eine Freigabe des > INT0 noch eine globale Interruptfreigabe. Die Freigabe von INT0 erfolgt in der "wl_module.c", so wie es in der main.c auskommentiert angegeben ist. Der Interrupt funktioniert auch einwandfrei. Daten Werden empfangen, Daten der Sensoren werden ausgelesen und anschließend werden diese korrekt auf dem LCD ausgegeben. Lediglich uart_puts wird nicht korrekt ausgeführt. Jochen S. schrieb: > aber das Compilersettinh "Controller" wurde auf 328 umgestellt? Oder > versuchst du das selbe HEX auf einem anderen Controller laufen zu > lassen?? Der Controller wurde umgestellt. Ich habe auch verschiedene Taktfrequenzen und Baudraten getestet. Michael K. schrieb: > Und du bist dir sicher, dass es kein Hardwarefehler ist? Ich habe 2 ATMega328 und 1 ATMega168 überprüft und mit allen besteht das gleiche Problem. Das andere Programm, das sehr ähnlich ist, erzeugt eine funktionierende UART-Ausgabe an jedem der genannten Controller. Michael K. schrieb: > Ich gehe also davon mal aus, dass der Compiler weder > moppert noch meckert. Da sind leider schon ein paar Warnungen, die ich bisher nicht "lösen" konnte, aber keine hat einen direkten Bezug zu UART.
Daniel H. schrieb: > Peter D. schrieb: >> Daniel H. schrieb: >>>> direkten string Ausgabe wie "uart_puts("Hallo Welt")" passiert nichts. >> >> Und warum postest Du es dann nicht so? > > das habe ich doch so gepostet :/ Nö. Da ist von INT0, ADC, LCD usw. allerhand Krams drinne, nur kein "uart_puts("Hallo Welt")". Die Chance ist also sehr groß, daß es garnicht am immer noch unbekannten Fleury-UART liegt. Ein bischen mußt Du Dir schon Mühe geben und auch selber etwas tun. Ich würd mal vermuten, in dem ganzen String-Bastel-Kauderwelsch ist der Wurm drin. Warum nimmst Du nicht einfach sprintf, der 328 hat doch genug Flash. Es ist auch keine gute Idee, den String asynchron zur Ausgabe zu basteln. Da kann gut ein Mischmasch aus alter+neuer String entstehen.
:
Bearbeitet durch User
Ist das Absicht, daß du in der while-Schleife immer wieder mit sei() die Interrupts einschaltest? Stings in einer ISR zusammenzubasteln ist tatsächlich keine gute Idee. Ich benutze hier übrigens auch die Fleury-Lib auf einem 328p, funktioniert tadellos.
Daniel H. schrieb: > Eric B. schrieb: >> Da steckt viel zu viel Zeug und Kram in deiner ISR. Nimm all diese >> Textbearbeitung raus, und tue das in der main(). >> Und Delays haben in einer ISR NIX verloren!! > > ist das nur sehr unschön oder eine definitive Fehlerquelle? Ob es eine definitive ist kann ich nicht sagen. Es ist aber eine potenzielle, da unter Umständen deine Daten in der ISR geändert werden während sie gleichzeitig von puts auf der serielle Schnittstelle ausgegeben werden.
Kannst du Ausschließen das während deinem uart_puts aufruf ein interrupt auftritt? Das kann durchaus problematisch sein. Hier kannst du gut nachlesen warum (Kapitel 4): https://docs.google.com/viewer?url=https%3A%2F%2Fwww.google.de%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D5%26cad%3Drja%26uact%3D8%26ved%3D0CDgQFjAEahUKEwjx0vGAgZrJAhWBCywKHVEzAe8%26url%3Dhttps%253A%252F%252Fhomepages.thm.de%252F~hg6458%252Fsemsts%252FInterrupt-Techniken_Schoendube.pdf%26usg%3DAFQjCNHPTyxQpn6tkd-23UprKLNZMMN3qA%26bvm%3Dbv.107763241%2Cd.bGg
Peter D. schrieb: > Die Chance ist also sehr groß, daß es garnicht am immer noch unbekannten > Fleury-UART liegt. > Ein bischen mußt Du Dir schon Mühe geben und auch selber etwas tun. Ich bemühe mich so sehr ich kann. Es tut mir leid wenn ich den Eindruck geweckt haben sollte, dass ich selbst keine Lust hätte dem Problem auf die Spur zu kommen. Peter D. schrieb: > Ich würd mal vermuten, in dem ganzen String-Bastel-Kauderwelsch ist der > Wurm drin. Warum nimmst Du nicht einfach sprintf, der 328 hat doch genug > Flash. > Es ist auch keine gute Idee, den String asynchron zur Ausgabe zu > basteln. Ok, werde mal schauen dass ich das überarbeite. Die Ausgabe auf dem LCD scheint aber einwandfrei. Matthias P. schrieb: > Ist das Absicht, daß du in der while-Schleife immer wieder mit sei() die > Interrupts einschaltest? Ne, das war ein Versehen -danke. Eric B. schrieb: > Es ist aber eine > potenzielle, da unter Umständen deine Daten in der ISR geändert werden > während sie gleichzeitig von puts auf der serielle Schnittstelle > ausgegeben werden. Könnte ich das nicht einfach durch eine Art "Buffer-String" in der while-Schleife lösen? Sajuuk schrieb: > Kannst du Ausschließen das während deinem uart_puts aufruf ein interrupt > auftritt? Das kann durchaus problematisch sein. Den Pegel des Interrupt-Pin beobachte ich auf dem Oszilloskop. Der Interrupt folgt periodisch mehrmals pro Minute und dauert etwa 376µs an. So lange liegt also ein Low-Pegel an. Ich habe keine Vorkehrungen getroffen den Zustand auszuschließen, aber wenn sollte das äußerst selten passieren?! Ich werde mal die ISR bis auf den Empfang säubern und die "String-Bearbeitung" ganz rausnehmen. Mich beschleicht aber irgendwie das Gefühl es könne mit der Portkonfiguration zusammenhängen. Hier mal die momentane Beschaltung des AVR: Pin 1 (PC6): Reset an ISP Pin 2 (PD0): - Pin 3 (PD1): UART Tx Pin 4 (PD2): Int0 an IRQ (NRF24L01) Pin 5 (PD3): - Pin 6 (PD4): an LCD Data0 Pin 7 (Vcc): Versorgungsspannung Pin 8 (GND): Masse Pin 9 (PB6): an DHT22 Signal Pin 10 (PB7): Eingang der UART-Ausgabe aktivieren soll Pin 11 (PD5): an LCD Data1 Pin 12 (PD6): an LCD Data2 Pin 13 (PD7): an LCD Data3 Pin 14 (PB0): an CE (NRF24L01) Pin 15 (PB1): an CSN (NRF24L01) Pin 16 (PB2): SS an Vcc Pin 17 (PB3): MOSI an ISP und NRF24L01 Pin 18 (PB4): MISO an ISP und NRF24L01 Pin 19 (PB5): SCK an ISP und NRF24L01 Pin 20 (AVCC): - Pin 21 (AREF): - Pin 22 (GND): - Pin 23 (PC0): ADC0 an LDR Pin 24 (PC1): an LCD RS Pin 25 (PC2): an LCD RW Pin 26 (PC3): an LCD E Pin 27 (PC4): SDA an bmp085 Sensor Pin 28 (PC5): SCL an bmp085 Sensor
Anregung: lass deine Mainschleife in festen ms ticks laufen (mit_delay_ms()) und zähle für die verschiedene Unterfunktion die ticks mit. So kannst du relativ einfach von einander unabhängige Aufgaben parallellisieren ohne alles zu blockieren:
1 | ISR(INT0_vect) |
2 | {
|
3 | ...
|
4 | int0_occured = 1; |
5 | }
|
6 | |
7 | |
8 | void main() |
9 | {
|
10 | // init everything
|
11 | |
12 | // main loop
|
13 | for(;;) |
14 | {
|
15 | // Interrupt handling
|
16 | if(int0_occured) |
17 | {
|
18 | handle_int0(); |
19 | int0_occured = 0; |
20 | }
|
21 | |
22 | // TASK 1 -- e.g. UART output
|
23 | task1_counter --; |
24 | if(!task1_counter) |
25 | {
|
26 | do_task1(); |
27 | task1_counter = 100; // every 500ms |
28 | }
|
29 | |
30 | // TASK 2 -- e.g. LCD output
|
31 | task2_counter --; |
32 | if(!task2_counter) |
33 | {
|
34 | do_task2(); |
35 | task1_counter = 50; // every 250ms |
36 | }
|
37 | |
38 | // etc etc etc
|
39 | |
40 | // now block for a minimum amount of time
|
41 | _delay_ms(5); // 5ms tick |
42 | }
|
43 | }
|
Ganz striktes Timing kriegt man so natürlich nicht hin, aber es macht alles schon "fliessender" als mit den blockierenden delays.
:
Bearbeitet durch User
Eric B. schrieb: > So kannst du relativ einfach von einander unabhängige Aufgaben > parallellisieren ohne alles zu blockieren: Ah, vielen Dank - sowas ist immer ungemein hilfreich! Ich bin mit solchen Konzepten leider nicht so vertraut und habe mich auch noch nicht groß um derlei Optimierungsmöglichkeiten gekümmert. Es wird aber offenbar Zeit ;) Bezüglich des UART Problems bin ich nicht unbedingt weitergekommen, aber habe ein paar Sachen versucht, die mehr oder weniger aufschlussreich waren. Ich habe schrittweise Teile des Codes entfernt, bis nur noch die UART-Ausgabe selbst vorhanden war. Um wenigstens in etwa abschätzen zu können was passiert, wird noch ein Pin (PB7) ein- und ausgeschaltet. Der Tx-Pin bleibt noch immer dauerhaft auf "High", aber die Zahl der Programmwiederholungen hängt von der Stringlänge ab, die uart_puts() übergeben wird. Länge: 0 -> inf. Pulse Länge: 1 -> 32 Pulse am Pin Länge: 2 -> 16 Pulse Länge: 4 -> 8 Pulse Länge: 32 -> 1 Puls ..danach passiert gar nichts mehr, bis ich einen Reset auslöse oder die Spannungsversorgung aus- und wieder einschalte. Wo der Fehler genau liegt weiß ich leider noch immer nicht.
Daniel H. schrieb: > Da sind leider schon ein paar Warnungen, die ich bisher nicht "lösen" > konnte, aber keine hat einen direkten Bezug zu UART. Die solltest du auf jeden Fall IMO behandeln. Es gibt wenige Ausnahmen, bei denen man ein Warning ignorieren kann (Klassiker: discards 'volatile' qualifier …) aber in der Regel sollte man sie immer beachten und beseitigen.
Daniel H. schrieb: > Wo der Fehler genau liegt weiß ich leider noch immer nicht. Bei dem Testcode liegt der Fehler beim fehlenden sei(). Der Fleury-UART-Code arbeitet mit einem Puffer und Interrupt gesteuertem Senden.
Stefan E. schrieb: > Bei dem Testcode liegt der Fehler beim fehlenden sei(). Ich bin auch ein Esel. Nach dem Hinzufügen von sei() ergibt sich immerhin direkt ein neues Fehlerbild. Direkt nach dem Programmieren läuft das Programm durch, aber es gibt noch immer keine UART-Ausgabe. Nach einem Neustart passiert dann gar nichts mehr. :/
so, ich habe was gefunden.. Da war eine Compiler-Warnung die eigentlich recht eindeutig scheint. uart.c:243: warning: 'SIG_USART_RECV' appears to be a misspelled signal handler uart.c:286: warning: 'SIG_USART_DATA' appears to be a misspelled signal handler Die entsprechenden Stellen beziehen sich wohl auf: #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA Laut Datenblatt des ATMega328 gibt es diese Interrupt Vektoren nicht. Dort habe ich folgendes gefunden: USART Rx Complete: USART, RX USART Data Register Empty: USART, UDRE USART Tx Complete: USART, TX Daher habe ich die oben genannten Zeilen wie folgt geändert: #define UART0_RECEIVE_INTERRUPT USART_RX_vect #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect Der Compiler hat nichts zu meckern und es scheint zu funktionieren. Sind das die richtigen Vektoren? Was hat das "SIG" zu bedeuten? ..und warum funktioniert das andere Programm inklusive UART auf dem gleichen AVR mit der library fehlerfrei?
Daniel H. schrieb: > ..und warum funktioniert das andere Programm inklusive UART auf dem > gleichen AVR mit der library fehlerfrei? da musst du dich mal durchwühlen, ich nutze auch gerne Fleury LIBs aber da ist noch einges veraltet z.B. an manchen Stellen xtalCpu, an anderen wieder F_CPU ich habe die von hier mal angesehen: http://homepage.hispeed.ch/peterfleury/uartlibrary.zip die ganzen Prozzi #defines stehen auch in uart.c, sowas gehört sich ja in uart.h oder man macht sein eigenes, so mache ich es. Man kann leider so schlecht Codes mixen wenn es von verschiedenen Autoren aus unterschiedliche Jahrzehnten stammt. Besser man definiert neu mit ungebrächlichen oder verfemdeten #defines und trägt die benötigen passend ein: z.B. so
1 | #if defined(__AVR_ATmega328P__)
|
2 | #define TIMSKx TIMSK1
|
3 | #define OCIExA OCIE1A
|
4 | #define TIMERx_COMPA_vect TIMER1_COMPA_vect // ATmega
|
5 | #define TCCRxA TCCR1A
|
6 | #define COMxA0 COM1A0
|
7 | #define OCRxA OCR1A
|
8 | #define TCCRxB TCCR1B
|
9 | #define WGMx2 WGM12
|
10 | #define CSx0 CS10
|
11 | |
12 | #define ARDUINO_LED 5
|
13 | #define DDR_ARDUINO_LED DDRB
|
14 | #define PORT_ARDUINO_LED PORTB
|
15 | #define ARDUINO_LED_ON PORT_ARDUINO_LED|=(1<<ARDUINO_LED)
|
16 | #define ARDUINO_LED_OFF PORT_ARDUINO_LED&=~(1<<ARDUINO_LED)
|
17 | |
18 | #elif defined(__AVR_ATmega1284P__)
|
19 | #define TIMSKx TIMSK3
|
20 | #define OCIExA OCIE3A
|
21 | #define TIMERx_COMPA_vect TIMER3_COMPA_vect // ATmega
|
22 | #define TCCRxA TCCR3A
|
23 | #define COMxA0 COM3A0
|
24 | #define OCRxA OCR3A
|
25 | #define TCCRxB TCCR3B
|
26 | #define WGMx2 WGM32
|
27 | #define CSx0 CS30
|
28 | |
29 | //#elif defined(__AVR_ATmega1284P__)
|
30 | #define LED_ARDUINO 7
|
31 | #define LED_ARDUINO_PORT PORTB
|
32 | #define LED_ARDUINO_DDR DDRB
|
33 | #define LED_ARDUINO_ON LED_ARDUINO_PORT |= (1<<LED_ARDUINO)
|
34 | #define LED_ARDUINO_OFF LED_ARDUINO_PORT &= ~(1<<LED_ARDUINO)
|
35 | |
36 | #endif
|
Daniel H. schrieb: > Die entsprechenden Stellen beziehen sich wohl auf: > #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV > #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA Und genau deshalb wäre es sinnvoll ein (möglichst minimales) vollständiges Codebeispiel, inklusive aller verwendeten Dateien, zu posten, damit potentielle Helfer wissen, wovon die Rede ist. Eine "uartlibrary" von Fleury findet man beispielsweise hier: http://homepage.hispeed.ch/peterfleury/avr-software.html In dieser kommt weder ein "SIG_USART_RECV" noch ein "SIG_USART_DATA" vor. > ..und warum funktioniert das andere Programm inklusive UART auf dem > gleichen AVR mit der library fehlerfrei? Ohne den relevanten Code zu kennen, kann das keiner sagen.
Daniel H. schrieb: > Sind > das die richtigen Vektoren? Was hat das "SIG" zu bedeuten? Ja, das sind die richtigen Vektoren. Das SIG deutet aber auf relativ alten Code hin. Was damals SIG hieß heißt heute vect. Die Bezeichnungen haben sich geändert. Du solltest auf jeden Fall mal eine aktueller Version der Lib dir beschaffen oder aber du schreibst dir selbst eine Lib zum UART. Das ist nicht schwer und braucht vielleicht eine Stunde Arbeit aber dann weißt du auch wie der UART funktioniert.
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.