-         

Ergebnis 1 bis 5 von 5

Thema: Verarbeitung von RS232 Input

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    13.09.2007
    Beiträge
    39

    Verarbeitung von RS232 Input

    Anzeige

    Hallo!
    Ich hab ein kleines Problem bei der Realisierung von meiner Steuerung.
    Ich möchte vom PC / Laptop / irgendwas aus sagen wir mal 5 Bytes an den Bot schicken, wobei das erste Byte ein Escapezeichen ist und die folgenden 4 Datenbytes die Benötigten Informationen enthalten.
    Ich sende vom PC aus diese 5 Bytes wann immer sie benötigt werden, sprich wenn ich was gedrückt habe.
    Wie soll ich das jetzt am Bot (Atmega32) verarbeiten?
    Wenn ich in die ISR vom UART Rx komme, dann heisst das ja, dass ein Byte angekommen ist. Soll ich dort nun prüfen, ob es das Escapebyte ist und die darauf folgenden 4 in einer globalen Variable speichern? In der main() würde ich dann in der Hauptschleife immer diese Variable prüfen und je nachdem was drinsteht etwas ausführen oder eben nicht.
    Ist dies so sinnvoll?
    Wie würdet ihr das regeln?

    Danke!

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    13.09.2007
    Beiträge
    39
    O.K. das mit dem direkt in der ISR verarbeiten hat irgendwie nicht funktionniert.
    Ich hab nun den UART so wie im C Tutorial (mit Interrupts).
    Im der main() hab ich dann folgendes...
    Code:
    ...
    int a, b, c, d;
    while(1) {
      if(uart_getc_nowait() == '$') { // $ ist hier mein Escape-Zeichen
        waitms(5);
        a = uart_getc_nowait();
        b = uart_getc_nowait();
        c = uart_getc_nowait();
        d = uart_getc_nowait();
      }
      ...
    }
    ...
    Was mich jetzt daran stört, ist dass ich nach der Escapezeichenüberprüfung das waitms(5); brauche. Ohne geht es nicht.
    Komisch finde ich, dass ich es nicht zwischen den einzelnen Zuweisungen brauche.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    03.10.2007
    Beiträge
    68
    Hi,

    wieso brauchst Du das Delay?

    Wie sieht die Routine uart_getc_nowait aus.
    Wenn dies die ISR ist, so hast Du was falsch verstanden.

    Die ISR empfängt die Zeichen und schreibt diese in einen Puffer, sie kann Dir dann auch ein Flag setzen, welches du im HP abprüfst.

    Die ISR rufst nicht Du im HP aus, sondern diese wird automatisch gestartet wenn ein Zeichen eintrifft. Dies ist ja der Sinn, das man sich da nicht drum kümmern muß.

    Grüße

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    13.09.2007
    Beiträge
    39
    Das uart_getc_nowait() ist nicht die ISR. Ich habs so wie im C Tutorial aus dem RN Artikelbereich, siehe hier.
    Das Delay brauch ich, da ich sonst denselben Rückgabewert bekomme, wie wenn kein Zeichen geschickt wurde (-1). Komischerweise brauch ichs aber nur direkt nach der IF-Bedingung.
    Ich möchte nicht wirklich die uart_getc_wait() Methode verwenden, ka wieso.

    Ich schicke vom PC aus immer 5 Bytes, also z.B. $1234 (als String gesehen), keine Ahnung, warum ich das Delay brauche und vor allem nur dort.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    13.04.2007
    Ort
    NRW
    Beiträge
    37
    Hallo,
    also ich arbeite in Zusammenhang mit RS232 immer mit dieser Routine

    Code:
    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7
    
    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    
    // USART Receiver buffer
    #define RX_BUFFER_SIZE 8
    char rx_buffer[RX_BUFFER_SIZE];
    
    #if RX_BUFFER_SIZE<256
    unsigned char rx_wr_index,rx_rd_index,rx_counter;
    #else
    unsigned int rx_wr_index,rx_rd_index,rx_counter;
    #endif
    
    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow;
    
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    char status,data;
    status=UCSRA;
    data=UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
       {
       rx_buffer[rx_wr_index]=data;
       if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
       if (++rx_counter == RX_BUFFER_SIZE)
          {
          rx_counter=0;
          rx_buffer_overflow=1;
          };
       };
    }
    
    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    char data;
    while (rx_counter==0);
    data=rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif
    
    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 8
    char tx_buffer[TX_BUFFER_SIZE];
    
    #if TX_BUFFER_SIZE<256
    unsigned char tx_wr_index,tx_rd_index,tx_counter;
    #else
    unsigned int tx_wr_index,tx_rd_index,tx_counter;
    #endif
    
    // USART Transmitter interrupt service routine
    interrupt [USART_TXC] void usart_tx_isr(void)
    {
    if (tx_counter)
       {
       --tx_counter;
       UDR=tx_buffer[tx_rd_index];
       if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
       };
    }
    
    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
       {
       tx_buffer[tx_wr_index]=c;
       if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
       ++tx_counter;
       }
    else
       UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif
    ich frage den Puffer direkt über die Variable rx_counter ab

    Code:
    if(rx_counter>0)          //rx_counter ist immer dann größer 0 wenn Zeichen im Puffer vorhanden sind
           {
             myVariable=getchar();//wenn Zeichen über RS232 empfangen wird  Zeichen in cZeichenEmpfangen gespeichert
             switch (myVariable)  //je nachdem welches Zeichen empfangen wird, führe Anweisung aus
             {
               case 'A': ...
       
                        break;              
                          
               case 'B':                                         
                        break;
                          
               default;
    }
    das ist der Quellcode der automatisch erzeugt wird wenn man bei CodevisionAVR mit dem CVodeVizzard arbeitet und man die Einstelungen für die Schnittstelle macht (funktioniert nur mit der Vollversion, haben in der Schule damit gearbeitet)...

    vielleicht hilft dir das ja...

    Gruß Pierce
    Lasst mich Arzt, ich bin durch...

    http://www.pennergame.de/change_please/9251940/

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •