Forum: Mikrocontroller und Digitale Elektronik Befehl empfangen mit UART und auswerten


von Mimo A. (mimo)


Lesenswert?

Hallo Leute,

ich brauche eure Hilfe!
ich habe geschaft bis jetzt ein Zeichnen auf mein Mikrokontroler(type: 
AT90PWM von Atmel) zu empfangen und zu bewerten. Ich möchte jetzt eine 
Zahle von 0 bis 360 empfangen und in einem register im mikro speicher, 
damit wird getzhält bis  zum diesem Zahl.
Bis jetzt löst sich immer der Receive-Interrupte bei Empfang eines 
Zeichen.
Wie kann ich mehrer zeichenempfangen(zm: 3 byte für einen Zahl und 
umwandlen in einem short variable)
ich danke euch voraus!
hier ist der code.

#include <avr/io.h>
#include <inttypes.h>
#include <stdint.h>
#include <avr/interrupt.h>
#define F_CPU 8000000
#define uart_baud 9600
#define UART_BAUD_SELECT ((F_CPU / (uart_baud * 16L))-1)


// Interrupt wird ausgelöst sobald neue Daten im USART-Empfangspuffer 
liegen
SIGNAL(SIG_UART_RECV)
{  unsigned char buffer;
  // Daten aus dem Puffer lesen ...
  buffer = UDR;

  switch (buffer)
  {
  case 'a': PORTE = 0x02;break;
  case 'b': PORTE = 0x04;break;
  default : break;
  }
  // ... warten bis der Sendepuffer leer ist ...
  while ( !( UCSRA & (1<<UDRE)) )
    ;
  // ... und gleich wieder zurück schicken
  UDR = buffer;
}

/////////Init///////////////////
void uart_init(void)
{
  UBRRH=(UART_BAUD_SELECT>>8);
  UBRRL=UART_BAUD_SELECT;
  UCSRB |= (1<<RXCIE)|(1<<TXEN) |(1<<RXEN);  //Transmitter Enabled 
,Emfpang enabl
  UCSRC |= (0<<UMSEL)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0); 
//Asynchron 8N1
}
/////////////Senden UART---->PC///////////////
void sendeByte(unsigned char data)
{
  while (!(UCSRA & (1<<UDRE)));
  UDR = data;
}

////////////////// SENEDE STRINGE
void put_string(unsigned char *zeiger)
{
  while (*zeiger !=0)
  {  while (!(UCSRA & (1<<UDRE)));
  UDR=*zeiger;
  *zeiger++;
  }
}


int main(void)
{
  DDRE=0xff;
  PORTE=0x00;
  uart_init();
  unsigned char promt[]="Hallo";
  put_string(promt);
  sei();
  while (1);
  return 0;
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

1
#define F_CPU 8000000

Beliebter Fehler.

Das ist zu groß für eine int-Konstante, hänge da noch das Suffix L an:
1
#define F_CPU 8000000L

von Karl H. (kbuchegg)


Lesenswert?

Mimo Abid wrote:
> Wie kann ich mehrer zeichenempfangen(zm: 3 byte für einen Zahl und
> umwandlen in einem short variable)

Du fängst mal damit an, dass du die Zeichen in der UART Empfangsroutine
nicht direkt auswertest, sonden in einem Buffer (einem char Array)
zwischenspeicherst. Das machst du solange bis ein vereinbartes
Ende Zeichen (zb. Carriage Return) daherkommt woraufhin du den
Bufferinhalt zur 'vollständigen Zeile' erklärst, dir zb ein
globales Flag auf true stellst und in der Hauptschleife denn
Bufferinhalt abarbeitest

ungefähr so
1
volatil uint8_t  LineComplete;       // wenn 1: Zeile komplett
2
char     Buffer[128];                // hier entsteht die Zeile
3
uint8_t  NextCharInBuffer;           // Char Zähler für den Buffer
4
5
ISR( ... )
6
{
7
  char c = UDR;
8
9
  if( c == '\n' ) {
10
     // Zeile ist fertig. Mach einen String daraus
11
     Buffer[NextCharInBuffer] = '\0';
12
     // mit dem nächsten Zeichen wird wieder vorne angefangen
13
     NextCharInBuffer = 0;
14
     // und aller Welt mitteilen, dass im Buffer ein gültiger
15
     // String existiert
16
     LineComplete = 1;
17
   }
18
19
   else {
20
     Buffer[NextCharInBuffer] = c;
21
     NextCharInBuffer++;
22
   }
23
}
24
25
26
int main()
27
{
28
   ....
29
30
   LineComplete = 0;
31
   NextCharInBuffer = 0;
32
33
   ...
34
35
   sei();
36
37
   while( 1 ) {
38
39
     if( LineComplete ) {   // eine vollständige Zeile empfangen
40
                            // mach was damit
41
42
       ...
43
44
       LineComplete = 0;    // Zeile wurde abgearbeitet
45
     }
46
   }
47
}

Obiges enthält noch keine Fehlerbehandlung und auch der
Fall, dass eine Zeile nicht schnell genug abgearbeitet wurde
ehe das nächste Zeichen eintrifft wurde nicht behandelt.
Aber dafür kannst du dir ja selbst was ausdenken.

von Mimo A. (mimo)


Lesenswert?

danke leute für den schnell antwort. Bei mir heisst die Interuppt 
Routine : ISR(USART_RXC_vect)
ich bekomme den folgenden warning:

../UART_Senden.c:47: warning: `USART_RXC_vect' appears to be a 
misspelled signal handler

weisst jemanden was das bedeuted?

von Karl H. (kbuchegg)


Lesenswert?

'misspelled' heist 'falsche Schreibweise' oder 'Tippfehler'.

Die komplette Fehlermeldung heist also übersetzt:

`USART_RXC_vect' appears to be a misspelled signal handler

'USART_RXC_vect schaut nach einem falsch geschriebenen
Namen für den Handler aus'

Der Compiler hat also erkannt, dass du eine ISR schreiben
willst, allerdings hat er mit dem Namen USART_RXC_vect
nichts anfangen können. Seiner Meinung nach gibt es keine
ISR die so heissen kann.

Und wie wir alle wissen: Der Compiler hat immer recht.

von Mimo A. (mimo)


Lesenswert?

und wie oder wo bekomme ich den richtigen Namem für mein 
interupt_receive routine?

von Troll B. (blaubeer)


Lesenswert?

Mimo Abid wrote:
> und wie oder wo bekomme ich den richtigen Namem für mein
> interupt_receive routine?

Durch Nachschauen in der zugehörigen Dokumentation!

MfG, Heidelbär  ääähhh Blaubär

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.