www.mikrocontroller.net

Forum: Compiler & IDEs Flash + String + Uart senden


Autor: Josef Kaeufl (josefk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

hab ein kleines Problem mit meiner Sendefunktion. Die Funktion sollte 
einen im Flash abgelegten String senden.
const char spi_start[] PROGMEM = "Aktiviere SPI...";
const char sdparser_start[] PROGMEM = "SD Karten Zugriff...";

void uart0_init(void)
{
  // Baudrate 9600
  UBRR0L = 103;

  // Baudrate 115200
  //UBRR0L = 3;

  // Datenbyte 8
  UCSR0C |= (1 << UCSZ00);
  UCSR0C |= (1 << UCSZ01);
  // Parity keine
  UCSR0C &= ~(1 << UPM00);
  UCSR0C &= ~(1 << UPM01);
  // Stoppbit 1
  UCSR0C &= ~(1 << USBS0); 
  // Asynchronous Operation
  UCSR0C &= ~(1 << UMSEL0);
  UCSR0C &= ~(1 << UCPOL0);  

  UCSR0B |= (1 << RXCIE); // Interrupt enabel für RXC flag
  UCSR0B |= (1 << RXEN0);  // Receive Enable
  UCSR0B |= (1 << TXEN0);  // Transmitter Enable

}

void rs232_puts_P(PGM_P s)
{
   unsigned char c;
   while (*s != '\0')
   {
      while ( !(UCSR0A & (1<<UDRE0)));         //Warten bis UDR leer ist für Senden
      c = pgm_read_byte (s);
      UDR0 = c;
      s++;                                    //Adresse erhöhen
   }    
   while ( !(UCSR0A & (1<<UDRE0)));  
   UDR0 = '\n';   
   while ( !(UCSR0A & (1<<UDRE0))); 
   c = pgm_read_byte (s); 
   UDR0=c;
   while ( !(UCSR0A & (1<<TXC0)));              //Warten bis Senden abgeschlossen
}


main
{
//UART0 aktivieren (Logger)
  uart0_init();
  uip_ipaddr_t IpAddr;
//SPI Schnitstelle aktivieren
  rs232_puts_P(spi_start);
  SpiInit();
//erstellt obj_dir_app leer oder mit SD-Inhalt
  app_object_parser();
  rs232_puts_P(sdparser_start);
//...
while(1);
}

Was dann im Terminal raus kommt:
<\0><\0><\n>
ASD Karten Z<\n>
uAk<\n>
t<\0><\n>
A

Ich finds komisch. Irgendwo mach ich was falsch, nur wo?

Autor: Hermann-Josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Josef,
while (*s != '\0')

prüft nicht im Flash sondern im RAM.

Ich würde das so schreiben:

   unsigned char c;
   while ( (c = pgm_read_byte(s)) != '\0')
   {
      while ( !(UCSR0A & (1<<UDRE0)));         //Warten bis UDR leer ist für Senden
      UDR0 = c;
      s++;                                    //Adresse erhöhen
   }    

oder noch etwas 'optimiert':
   while ( (c = pgm_read_byte(s++)) != '\0')
und dann das Erhöhen der ADresse weiter unten weglassen.

Ciao
Hermann-Josef

Autor: Josef Kaeufl (josefk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahhh Danke. Das bringt mich schon weiter. Scheint immer noch nicht ganz 
zu funktionieren, aber der 
Beitrag "Re: Problem mit pgm_read_byte_far" zeigt auch ein 
mögliches Problem.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hermann-Josef wrote:
> oder noch etwas 'optimiert':
>
>    while ( (c = pgm_read_byte(s++)) != '\0')
> 

Die Bedingung wird aber auch zu Anfang der Schleife durchlaufen. Dann 
würde ja immer das erste Zeichen fehlen...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. wrote:
> Hermann-Josef wrote:
>> oder noch etwas 'optimiert':
>>
>>    while ( (c = pgm_read_byte(s++)) != '\0')
>> 
>
> Die Bedingung wird aber auch zu Anfang der Schleife durchlaufen. Dann
> würde ja immer das erste Zeichen fehlen...

Äh, nein, warum sollte es?
In pgm_read_byte geht ja der Wert von s vor der Erhöhung hinein.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.