Forum: Mikrocontroller und Digitale Elektronik Zeiger Strings ausgeben?!


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht lesenswert
Moin Moin.

Wieso hängt sich der µC auf, wenn ich die Strings ausgeben will?
1
typedef struct  
2
{
3
  const char *ProjectName;
4
  const char *HardwareVersion;
5
  const char *SoftwareVersion;
6
  const char *HardwareDate;
7
  const char *SoftwareDate;
8
}DevBoard_t;
9
10
DevBoard_t  Message={
11
  
12
  .ProjectName    = "DevBoard\r\n",
13
  .HardwareVersion  = "Hardware Version 1.0\r\n",
14
  .SoftwareVersion  = "Software Version 1.0\r\n",
15
  .HardwareDate    = "Hardware from 18.04.17\r\n",
16
  .SoftwareDate    = "Software from 30.05.17\r\n",
17
};
18
19
uart_puts(Message.ProjectName);

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
-1 lesenswert
nicht lesenswert
Jan H. schrieb:
> Wieso hängt sich der µC auf, wenn ich die Strings ausgeben will?

Vielleicht, weil die Funktion uart_puts() fehlerhaft implementiert 
wurde? Sonst gibt es auf kleinen µCs noch tausend andere Gründe, wie 
z.B. Größe des RAMs usw.

Ein
1
int main ()
2
{
3
    fputs (Message.ProjectName, stdout);
4
    return 0;
5
}

funktioniert unter Linux jedenfalls einwandfrei.

Um welchen µC handelt es sich denn? Und wie sieht der Rest des Programms 
aus?

Hängt sich der µC wirklich auf, wenn Du nur so eine kleine 
main()-Funktion hast, oder hast Du noch 30000 weitere Zeilen an Code?

Bitte ein compilierbares, reproduzierbares Beispiel angeben.

: Bearbeitet durch Moderator
von Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht lesenswert
Die Uart Routinen sind hier von der Seite..
Andere Strings kann ich an dieser Stelle, wo ich eigentlich diese 
Strings ausgeben will, ohne Probleme ausgeben.

Verwenden tue ich einen ATMEGA32.

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Jan H. schrieb:
> Die Uart Routinen sind hier von der Seite..

Ach so. Auf µc.net gibt es auch nur genau einen Satz UART-Routinen ...

von Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht lesenswert
1
/*************************************************************************
2
Function: uart_putc()
3
Purpose:  write byte to ringbuffer for transmitting via UART
4
Input:    byte to be transmitted
5
Returns:  none          
6
**************************************************************************/
7
void uart_putc(unsigned char data)
8
{
9
    unsigned char tmphead;
10
11
    
12
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
13
    
14
    while ( tmphead == UART_TxTail ){
15
        ;/* wait for free space in buffer */
16
    }
17
    
18
    UART_TxBuf[tmphead] = data;
19
    UART_TxHead = tmphead;
20
21
    /* enable UDRE interrupt */
22
    UART0_CONTROL    |= _BV(UART0_UDRIE);
23
24
}/* uart_putc */
1
/*************************************************************************
2
Function: uart_puts()
3
Purpose:  transmit string to UART
4
Input:    string to be transmitted
5
Returns:  none          
6
**************************************************************************/
7
void uart_puts(const char *s )
8
{
9
    while (*s) 
10
      uart_putc(*s++);
11
12
}/* uart_puts */

Diese werden verwendet..

von Stefan E. (sternst)


Bewertung
0 lesenswert
nicht lesenswert
Kann es sein, dass du versuchst, die Strings innerhalb einer ISR 
auszugeben?

von Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht lesenswert
Stefan E. schrieb:
> Kann es sein, dass du versuchst, die Strings innerhalb einer ISR
> auszugeben?

Nein. Das passiert alles bevor sei() aufgerufen wird.

von Marius (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich läuft der UART-Software-Puffer voll, wenn du den String 
ohne aktivierte Interrupts ausgibst. Dann wartet die Ausgabe bei
1
;/* wait for free space in buffer */
, weil kein Interrupt passiert, der den Puffer leert.

Gruß
Marius

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Jan H. schrieb:
> UART0_CONTROL    |= _BV(UART0_UDRIE);

Das Zeichen soll also in einer ISR ausgegeben werden. Wo ist die ISR 
dazu?

> Das passiert alles bevor sei() aufgerufen wird.

Wie soll das gehen? Ohne sei() kein Interrupt, ohne Interrupt kein 
ISR-Auffruf! Ohne ISR-Aufruf keine Ausgabe von Zeichen! Das kann so 
nicht gehen.

Pardon, aber mit so einer Salamitaktik kann man den Fehler nicht finden.

Ich wiederhole nochmal:

Bitte zeige ein compilierbares Programm mit reproduzierbarem Fehler. 
Sonst ist das ein Stochern im Dunkeln. Der Fehler kann überall sein, nur 
nicht in Deinem bisher gezeigten Code.

: Bearbeitet durch Moderator
von Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht lesenswert
Ah okay.
Habs verstanden.

Jetzt funktioniert es aber. Scheint wirklich der Puffer voll zu laufen.

Besten Dank!

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Jan H. schrieb:
> Was hat denn die Ausgabe mit einem Interrupt zu tun?

Dein oben zitiertes uart_puts() gibt das Zeichen gar nicht aus. Es 
kopiert das Zeichen nur in einen Ringbuffer und aktiviert dann den 
UART-Empty-Interrupt. Dieser wird ausgelöst, wenn der UART leerläuft. 
Die ISR kopiert dann das nächste auszugebende Zeichen ins UART-Register. 
Die eigentliche Ausgabe läuft also nicht in uart_puts(), sondern in der 
ISR.

> Das habe ich noch
> nicht ganz verstanden. Wenn ein Zeichen rein kommt, weiß ich das es ein
> Interrupt gibt.

Siehe oben. Wenn der UART kein Zeichen auszugeben hat, dann löst er 
einen UDRIE-Interrupt aus. Genau diesen aktiviert Dein uart_puts():

> UART0_CONTROL |= _BV(UART0_UDRIE);

> Jetzt funktioniert es aber. Scheint wirklich der Puffer voll zu laufen.

Lass mich raten: Du hast den sei()-Aufruf nach vorne gezogen.

Achja, bitteschön. ;)

: Bearbeitet durch Moderator

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.