Peter Fleury Uart Lib: Problem mit Rx-Interrupt und getc()

Gast #1291003
Lesenswert?
• ▲
▼
Hallo,
ich habe ein Programm für eine ATmega88 geschrieben, das kontinuierlich 
Daten aus mehreren Sensoren ausliest (SPI) und diese via UART versendet. 
Gestartet wird der Auslese- und Sendevorgang in dem ich ein t(=transmit) 
sende und gestoppt werden soll der kontinuierliche Datenstrom mit dem 
senden eines s(=stop).
Die Routinen für den SPI Zugriff sind sehr kurz gehalten und laufen 
atomar, d.h. in dieser Zeit sind keine Interrupts erlaubt.
Nach dem auslesen der Sensordaten (Integer), wandel ich diese mit der 
itoa()-Funktion aus der stdlib in einen String um und versende dann 
anschließend die Daten.

Nun habe ich folgendes Problem, wenn ich keine Pause (7ms) in die 
kontinuierliche Schleife einfüge dann bekommt der µC das senden von 
s(=stop) nie mit und ich kann den Datenstrom nur durch einen Reset 
stoppen. Die 7ms sind mir aber zu lang.
Hat dafür jemand eine Lösung?
#1291012
Lesenswert?
• ▲
▼
Erstmal den Code posten. Du kannst dir noch so viel Mühe mit einer 
Beschreibung geben, wir wissen dann trotzdem noch nicht, was genau 
dein aktueller Code macht. Eine Beschreibung entspricht schließlich 
immer dem, was du denkst oder möchtest, nicht unbedingt dem, was 
tatsächlich passiert.
Gast #1292138
Lesenswert?
• ▲
▼
@Karlheinz: wartende Schleifen?
Ich warte halt mit
while( !hal_smb380_new_acc_read( 0x02, &acc_x)){};
darauf, bis der Sensor wieder einen neuen Wert ausgibt

Und die _delay_ms(7);
wurden nötig, da der µC keinen RX-Interrupt mehr angenommen hat.

Die Warteschleifen sind ja nicht unbedingt schlecht, in der Zeit könnte 
ja ein RX-Interrupt auftreten und verarbeitet werden, oder?

Hast du einen besseren Vorschlag wie ich das programmieren kann?
Angehängte Dateien:
#1292158
Lesenswert?
• ▲
▼
Thomas schrieb:

> Hast du einen besseren Vorschlag wie ich das programmieren kann?

Wartende Schleifen sind immer schlecht.
In einem µC funktioniert der Status-Gedanke meistens am besten.
Dein Programm (die Hauptschleife) ist in einem Zustand. Irgendwelche 
Ereignisse verändern den Zustand. Aber: Es wird nicht gewartet. 
Reaktionen erfolgen nur aus Zustandsänderungen heraus.
Bei dir wäre zb ein Zustand: Daten vom Sensor holen und verschicken - 
kurz sampleData, der entweder TRUE oder FALSE sein kann

1
int main()
2
{
3
  unsigned int c;
4
  unisgned char sampleData;
5

6
  ...
7

8

9
  sampleData = 0;
10
  while( 1 ) {
11
    c = uart_getc();
12

13
    if ( (unsigned char)c == 't' )
14
      sampleData = 1;
15

16
    if ( (unsigned char)c == 's' )
17
      sampleData = 0;
18

19
    if( sampleData ) {
20
      if( hal_smb380_new_acc_read( 0x02, &acc_x ) {
21
        itoa( acc_x, buffer_acc_x, 10 );   
22
        uart_puts( "acc , " );
23
        uart_puts( buffer_acc_x );        // and transmit string to UART
24
        uart_puts( "\r\n" );
25
      }
26
    }
27
  }
Gast #1296606
Lesenswert?
• ▲
▼
Hallo Karl-Heinz,
ich hab das Programm jetzt mal umgeschrieben, siehe Dateien im Anhang. 
Allerdings mein eigentliches Problem bekomme ich damit nicht gelöst.

Wenn ich das Main-Programm mit dem auskommentierten Bereich in der 
Endlosschleife laufen lasse, dann funktioniert das starten der 
Übertragung mit dem senden von 't' wenn ich dann ein 's' sende dann 
stopt das Programm auch, aber etwas verzögert.
Wenn ich nun den auskommentierten Bereich auch ausführen lasse, dann 
kann ich das Proagramm wieder mit 't' starten aber auf das senden von 
's' reagiert das Programm nicht mehr, auch nicht verzögert ( ich hab mal 
1 Min gewartet). Daten liest das Programm weiterhin aus und sendet diese 
auch noch.

Irgendwie habe ich das Gefühl, dass der RX-Interrupt nicht mehr 
bearbeitet wird.
Angehängte Dateien:
#1300283
Lesenswert?
• ▲
▼
Ich würde mal die ganzen CRITICAL_REGION Makros weglassen. Du benutzt 
Hardware-SPI, daher können die Interrupts die ganze Zeit über enabled 
bleiben.

Wenn du das Gefühl hast, dass der RX-Interrupt nicht mehr angesprungen 
wird, dann mach dir in die ISR eine Ausgabe rein. Nein, nicht über UART; 
schalte eine LED ein. In der mainLoop setzt du nach jeder Ausgabe die 
LED wieder zurück. Wenn du dann Zeichen versendest, müsste die LED 
zumindest blinzeln. Dann weißt du, dass die ISR aufgerufen wird.
Gast #1300324
Lesenswert?
• ▲
▼
Hallo,
was ich schon mal probiert habe war, die Makros durch cli() und sei() zu 
ersetzen hat aber auch nichts geändert. Ich werde die Makros heute Abend 
mal ganz raus machen und schauen ob das was bringt.

Ich habe zwar keine LED (spezielles Board) aber einige Port-Pins habe 
ich noch frei. Werde das dann mal mit einem Oszi prüfen.

Könnte es evtl. auch am RS232/USB-Wandler (FT232RL) liegen? Dort 
flackern allerdings die beiden RX- und TX-LEDs.
Gast #1301792
Lesenswert?
• ▲
▼
@Karl-Heinz: Danke schon mal!

Ich hab das Problem jetzt genauer lokalisieren können, es liegt am 
USB/Seriell-Wandler (FT232RL). Der FT232RL gibt (bei Baudraten >=9600) 
die RX-Daten nicht aus, während er kontinuierlich mit TX-Daten versorgt 
wird.

Ob das ein Problem des Chips, des Treibers oder der USB-Geschwindigkeit 
(USB 1.0 / USB 2.0) ist konnte ich noch nicht genauer eingrenzen. Für 
Vorschläge, wie ich das genauer bestimmen kann wäre ich sehr dankbar.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.