mikrocontroller.net

Forum: Compiler & IDEs UART - Verständnisproblem Strings


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
mein Name ist Michael und ich programmiere in der Schule schon etwas 
länger mit µC. Jetzt haben wir jedoch mit dem UART begonnen und ich habe 
irgendwie ein Verstädnis problem bei einem kleinen privaten Projekt...

Ich nutze HTerm zum senden über die Serielle Schnittstelle vom PC aus. 
Mein µC ist ein AtMega8. Der Empfang funktioniert tadellos.
Jetzt möchte ich vom PC aus einen "String" an dem µC senden.
Und zwar will ich z.B. die Zeichenfolge "000 100 200 255 150 050" 
senden.
Ich habe 6 LED's an den AtMega angeschlossen und wollte diese 
Zahlenwerte nun als Helligkeitswerte der jeweiligen LED's verwenden 
(Soft-PWM). Also
LED1 = 000 ->aus
LED2 = 100 ->etwas hell...
usw...
(8-Bit 0-255)

Mein Problem liegt jetzt darin das ich es nicht hinbekomme die einzelnen 
Zahlenwerte in eine uint8_t Variable abzulegen.

Hier mal mein bisheriger Code. Über einige Tipps würde ich mich sehr 
freuen.
#include <avr/io.h>
#include <avr/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h> 

#define UART_SIZE 3
#define F_CPU 14745600L
#define USART_BAUDRATE 9600UL

volatile int8_t uart_count;
volatile char uart_buffer[UART_SIZE];
volatile uint8_t pwm_soll;
volatile uint8_t pwm_phase;

ISR(USART_RXC_vect) {
  while (uart_count < UART_SIZE) {
    uart_buffer[uart_count++] = UDR;
  };
  UDR = uart_buffer;
  pwm_soll = atoi(uart_buffer);
  
  
  for(int i=0;i<UART_SIZE;i++) {
      uart_buffer[i] = 0;
      uart_count=0;
  }  
  //pwm_soll = 2;
}

void prepare_usart(void) {
  // Senden und empfangen aktivieren und Empfang Interrupt aktivieren
  UCSRB |= (1<<TXEN) | (1<<RXEN) |(1<<RXCIE); 
  //Kommunikation asynchron "8N1"
  UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
  //Geschwindigkeit berechnen
  UBRRL = ((F_CPU)/((USART_BAUDRATE)*16L)-1);
  uart_count = 0;
  sei();
  
}

int main(void) {
  prepare_usart();
  int tmp = 0;
  pwm_soll = 255; 
  pwm_phase = 0;

  DDRB |= (1<<PB0); // Pin PB0 an Port B als Ausgang
   
  while( 1 ) {
    tmp++;
    
    if( pwm_soll == pwm_phase ) {
        PORTB |= (1<<PB0); 
    }

    pwm_phase++;

    if( pwm_phase == 255 ) {
      pwm_phase = 0;
      PORTB &= ~(1<<PB0);
    }
  }
  return 0;
}

Mit freundlichen Grüßen
Michael

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur kurz den Quelltext überflogen. Es scheint ein Verständnisproblem 
bezüglich der Arbeitsweise des USART_RXC_vect vorzuliegen. Der Interrupt 
wird jedesmal erzeugt, wenn ein Zeichen empfangen wurde und nicht erst, 
wenn genug Zeichen für deinen Buffer da sind. Denk immer dran: die 
Controllerhardware weiß von deinem Buffer nix.

Das heißt deine Buffer-Füll-Schleife:
  while (uart_count < UART_SIZE) {
    uart_buffer[uart_count++] = UDR;
  };

fliegt zwangsläufig auf die Nase.

Die korrekte Vorgehensweise wäre:
1. Das empfangene Zeichen in den Buffer schreiben
2. wenn ausreichend Daten im Buffer, auswerten. Wenn nicht, erstmal nix 
machen.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal für deine schnelle Antwort...
Also müsste ich im Prinzip, wenn ich weis wieviele Zeichen ich sende, 
den ganzen Zeichenstrom in einen buffer legen und diesen dann wenn alle 
Zeichen da sind aufteilen !?würde im Buffer denn auch wirklich "255 000" 
usw. liegen wenn ich diese Zeichenkette als ASCII zeichen sende?

MfG
Michael

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip ist es genau so. Was du dir jetzt noch überlegen musst:
* Wie sind deine Strings terminiert (z.B. durch Linefeed)?
* Was passiert, wenn du als erste Nachricht nach dem Einschalten ein 
Fragment empfängst (was ja, wenn der Sender bereits sendet, schnell 
passieren kann)? Wie schaffst du es, das Fragment zu verwerfen und 
zumindest die folgende Nachricht korrekt zu empfangen?
* Was passiert, wenn du aus welchen Gründen auch immer kompletten Unsinn 
empfängst? Kannst du sicherstellen, dass dein Programm nicht komplett 
aussteigt?

Wenn du dir das überlegt hast, dann fröhliches Programmieren. Du kannst 
ja mal dein Zwischenergebnis hier posten!

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.