UART Interrupts, Rückgabe der Variable

Gast #3954659
Hallo,

ich habe ein Problem neuerdings mit meinem UART.

Ich nutze zum Einlesen einen Interrupt. Die Werte kommen auch alle an, 
jedoch bekomme ich nicht die Rückmeldung das der String komplett 
eingelesen ist.


h-Datei
1
#ifndef UART0_H_
2
#define UART0_H_
3

4
#define UART0_BAUD        9600
5
#define UART0_BUFFER_MAX_LEN  4   // wichtig fuer diesen Fehler
6

7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9

10
static volatile char uart0_buffer[UART0_BUFFER_MAX_LEN + 1] = "";
11
static volatile uint8_t uart0_buffer_complete = 0;   // Uebeltaeter
12

13
int8_t uart0_init(void);
14
int8_t uart0_putc(uint8_t c);
15
int8_t uart0_puts(char *s);
16
#endif /* UART0_H_ */


c-Datei
1
#include "uart0.h"
2

3
static volatile uint8_t uart0_buffer_count;
4

5
int8_t uart0_init(void)
6
{
7
  //cli();
8
  // Baudrate berechnen
9
  UBRR0 = 51;//UBRR_VAL;
10
  // Senden und Empfänger(+Interrupt) aktivieren
11
  UCSR0B = (1 << TXEN0) | (1 << RXCIE0) | (1 << RXEN0) ;
12
  
13
  // 8 Bit, Asynchron, 1 Stop-Bit
14
  UCSR0C = (1 <<UCSZ01) | (1 << UCSZ00);
15
  
16
  return 0;
17
}
18

19

20
ISR(USART0_RX_vect)
21
{
22
  unsigned char nextChar;
23
  
24
  // Daten aus Puffer lesen
25
  nextChar = UDR0;
26
  
27
  if( uart0_buffer_complete == 0 )
28
  {
29
    if(nextChar != '\n' &&  nextChar != '\r' &&  uart0_buffer_count < UART0_BUFFER_MAX_LEN)
30
    {
31
      uart0_buffer[uart0_buffer_count] = nextChar;
32
      uart0_buffer_count++;
33
      uart0_puts(uart0_buffer); uart0_puts("\r\n");  // DEBUG
34
    }
35
    else
36
    {
37

38
      uart0_buffer[uart0_buffer_count] = '\0';
39
      uart0_buffer_count = 0;
40
      uart0_buffer_complete = 1;
41
      uart0_puts("complete\r\n");            // DEBUG
42
    }
43
  }
44
}
45

46
// ...


main, stark gekürzt
1
#include "uart0.h"
2

3
int main(void)
4
{
5
/.... init
6
  while(1)
7
  {
8
    if(uart0_buffer_complete)
9
    {
10
      uart0_puts("done\r\n");
11
      uart0_buffer_complete = 0;
12
    }
13
  }
14
}
Gast
Problem ist, dass sobald ich bei
static volatile uint8_t uart0_buffer_count;
das static wegnehme, mecker er in der main.c, dass ich die Variablem 
mehrmals defeniert hab. Das stimmt so aber nicht. Dort werden die 
lediglich abgefragt.

Wenn ich versuche die Stelle zu finden über die Fehlerausgabe in AS6.2, 
dann leitet er mich in die uart.c Datei nach dem include der uart.h 
Datei.

Aber eigentlich sollte static und/oder extern aber richtig sein.
Gast
Hallo Rufus. Mir ist bewusst, dass eine ISR so kurz wie möglich sein 
muss.
Das hab ich dort auch NUR reingeschrieben, da ich keinerlei Feedback 
bekommen habe, ob überhaupt Zeichen ankommen. Eine Led anschließen kann 
ich derzeit leider nicht.


Das Problem hängt scheinbar mit dem Geltungsbereich von Variablen 
zusammen.

initialized and declared 'extern' enabled by default

http://openbook.galileo-press.de/c_von_a_bis_z/009_c_funktionen_011.htm#mj19e69aaaa55d4a98fe6073fe2a99a2c6

Demnach sollten aber keine, extern oder static gehen.
Gast
mit "static" im Header-File kriegt jedes C-File, dass diesen Header 
#included, eine eigene, von allen anderen unabhängige Kopie der Variable 
verpasst.

Du willst was anderes: Nur eine Variable, alle C-Files greifen auf 
dieselbe zu.

Also: Im headerfile nur "extern", und in einem einzgen C-File die 
Variable instanziieren.

in keinem der beiden Files sollte die Variable dabei "static" sein.
Gast
Hallo,
so gehts noch nicht. Was meinst du genau mit instanzieren in diesen 
Fall?

main.h
1
#include "uart.h"

main.c
1
#include "main.h"

uart.h
1
extern volatile i;

uart.c
1
#include "uart.h"
Gast
Datentyp bei dem Wert vergessen. Denke aber es war zu sehen wie gemeint 
;)

Wenn ich i in uart.c defeniere mekert meine main.c immer noch, dass es 
bereits deklariert ist.

Error  3  'uart_str_complete' undeclared (first use in this function) 
C:\...\main.c
Gast
So, jetzt noch einmal zum vergleich, ob es so richtig gemacht wird. Es 
funktioniert auf jedenfalls schon einmal. Danke


uart.c
1
#include "uart.h"
2

3
// Diese Variable soll nur in uart.c vorhanden sein
4
volatile uint8_t uart_str_count = 0;
5
// Diese Variablen beziehen sich auf die extern deklarierten in uart.h
6
volatile uint8_t uart_str_complete;
7
volatile char uart_string[];
8

9
//...

uart.h
1
#ifndef UART_H_
2
#define UART_H_
3
//..
4

5
// Diese beiden Varialben sollen auch ausserhalb verfuegbar sein
6
extern volatile uint8_t uart_str_complete = 0;
7
extern volatile char uart_string[UART_MAXSTRLEN + 1] = "";
8

9
//..
10
#endif /* UART_H_ */

main.h
1
#ifndef MAIN_H_
2
#define MAIN_H_
3
//..
4

5
#include "uart.h"
6

7
//..
8
#endif /* MAIN_H_ */


main.c
1
#include "main.h"
2

3
// Diese Variable bezieht sich auf die extern deklarierten in uart.h
4
volatile uint8_t uart_str_complete; // 1)

1) In der main.c oder ggf. in der main.h besser aufgehoben??

Gruß
Persönliche Seite
Samuel schrieb:

> uart.h

> extern volatile uint8_t uart_str_complete = 0;
> extern volatile char uart_string[UART_MAXSTRLEN + 1] = "";

Initialisierungen gehören nicht in die Headerdatei.

> uart.c

> volatile uint8_t uart_str_complete;
> volatile char uart_string[];

Da gehört die Initialisierung und vor allem die Größenangabe des Arrays 
hin.

> main.c

> // Diese Variable bezieht sich auf die extern deklarierten in uart.h
> volatile uint8_t uart_str_complete; // 1)

Das hat da gar nichts verloren, stattdessen gehört da ein

#include "uart.h"

hin.
Gast
Variablen werden nicht in header-files definiert sondern nur in 
Source-Files und das auch nur einmal. Der Rest wird über "extern" 
erledigt. Und es gibt kein extern static!



Ingo
Gast
Also hab es dann nun geändert.

In der uart.h
die Initialisierung herausgenommen.

Nur in der uart.c die Werte initialisiert.



Für alle anderen h-Files nur noch das einfügen
volatile uint8_t uart_str_complete;
volatile char uart_string[UART_MAXSTRLEN+1];


soweit dann richtig?
Gast
Debuggen geht sicher nicht mit einem Strin aus einem Interrupt zu 
schreiben. Die Methode der Wahl ist einem Pin zu wackeln und mit dem 
Scope zu kontrollieren.
Gast
Doch, das "debuggen" mit dem String ging in der ISR wunderbar. Natürlich 
ist mir klar, dass dieser dort nichts zu suchen hatte. Aber mir blieb da 
keine andere Möglichkeit. Ist inzwischen raus da es funktioniert.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.