Forum: Mikrocontroller und Digitale Elektronik UART Interrupts, Rückgabe der Variable


von Samuel (Gast)


Lesenswert?

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
}

von Ingo (Gast)


Lesenswert?

Und wie äußert sich der Fehler genau? Auf Anhieb sehe ich keine Fehler! 
Kommt der String "Complete" und "Done" bleibt aus?

von Samuel (Gast)


Lesenswert?

"Complete" kommt auf der Konsole an. Jedoch bleibt "Done" aus. Somit 
wird uart0_buffer_complete nicht auf wahr in der main abgefragt

von Samuel (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du solltest davon Abstand nehmen, in Deinem Uart-Empfangsinterrupt die 
Funktion uart0_puts aufzurufen. Lass all diese Ausgaben mal weg, bzw. 
verlagere sie in die main().

von Samuel (Gast)


Lesenswert?

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.

von Ahab (Gast)


Lesenswert?

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.

von Samuel (Gast)


Lesenswert?

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"

von Walter (Gast)


Lesenswert?

in irgendeinem C File musst Du i auch definieren
(du hast übrigens int char oder sonst was bei i vergessen)

von Samuel (Gast)


Lesenswert?

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

von Samuel (Gast)


Lesenswert?

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ß

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Ingo (Gast)


Lesenswert?

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

von Ingo (Gast)


Lesenswert?

Mich wundert das der Compiler da mitspielt. Mach mal Werror an. Dann 
geht sowas schonmal alles garnicht mehr.

von Samuel (Gast)


Lesenswert?

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?

von Differentialknilch (Gast)


Lesenswert?

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.

von Samuel (Gast)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.