www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Finde fehler nicht (UART - Attiny2313)


Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend ! Ich versuche gerade eine Schrittmotorsteuerung aufzubauen 
und steuere den Motor mit Hilfe eines MicroControllers. Ich sende die 
Daten über RS232 an den µC (Attiny2313) und dieser steuert dann den L297 
an.

Mein Problem ist, dass in meinem Code die if-Bedingung in der Funktion: 
void parser(void) gar nicht "reagiert", obwohl rx_flag gesetzt ist.

Zur Überprüfung der einzelnen Stellen, sende ich vom µC zum PC immer 
einzelne Chars z.b. wie  UDR = 'i' für die Aussage, dass die Interrupt 
Routine ausgelöst hat und UDR = 'r' für die Aussage, dass das 
Ausrufungszeichen '!" angekommen ist. Ein ! bedeutet in meinem simplen, 
auch bestimmt nicht so tollen, Protokoll, dass ein Befehl vollständig 
angekommen ist. Wenn ich nun per HTERM an den µC die Zeichenfolge: d! 
schicke, erhalte ich als Status: iir , also zwei mal das i für die 
beiden gesendeten Chars (da die ISR Routine ja zwei mal anspringt) und 
das r, dass das Ausrufungszeichen angekommen ist. Nachdem das ! 
angekommen ist, wird rx_flag auf 1 gesetzt um somit mit dem Parsen der 
empfangen Daten anfangen zu können. Ich erwarte von meinem µC jetzt die 
Meldung: p  (UDR = 'p'), welche aber niemals ankommt... ich hoffe ich 
konnte damit mein Problem und die Funktionsweise des Programmes soweit 
erklären, dass es für eine Problemlösung verständlich ist.

Hier ist das Programm:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


/* Defines bezüglich UART */
#define BAUD 9600UL      
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
/*---ENDE---*/


/* PORT Bezeichnungen für den L297 (Motortreiber) */
#define EN PD5
#define DIR PD4
#define CLK PD3
/*---ENDE---*/


/* Prototypen */
void init_uart(void);
void init_stepper(int en);
void turn_stepper(int direc,int steps);
void parser(void);
/*---ENDE---*/


/* Globale Variablen */
char received_data[10]; // Buffer wo die empfangenen Daten gespeichert werden...
int  rx_flag;     // Status-Flag für vollständig übertragene Befehle...
int i=0;    // Index-Variable für den Daten-Puffer
int stop_flag = 0;  // Stop-Flag um den Motor anzuhalten!
/*---ENDE---*/  



int main(void)
{

  DDRD |= (1<<EN) | (1<<DIR) | (1<<CLK); // Data Direction Register einstellen  
  
  init_uart();
    
  init_stepper(1); // Schrittmotor anschalten

  sei();
  
  UDR = 'm';  // MAIN Meldung
  
  while(1)
  {
    parser();
  }
  
}



/***** STEPPER CODE TEIL *****/
void init_stepper(int en)
{
  switch(en)
  {
    case 1: PORTD |= (1<<EN);
    break;
    case 0: PORTD &=~(1<<EN);
    break;
  //  default:
  }
}

void turn_stepper(int direc,int steps)
{
  
  int i = 0;
  
  PORTD |= (direc<<DIR);

  for(i=0;i<=steps;i++)
  {
    
    PORTD |= (1<<CLK);
    _delay_ms(1);
    PORTD &=~ (1<<CLK);
    _delay_ms(1);
  
  }

}




void parser(void)
{

  //_delay_ms(1000);
  
  
    
  if(rx_flag == 1) // Alle Daten empfangen, beginne mit Parsen !
  {
           

    UDR = 'p';
  
     switch (received_data[0])
     {    
             // Motor drehen.... Buchstabe "d"
       case 0x64:  
             UDR = 'd';
       turn_stepper(1,20);
    
       break;
     
       case 0x73: // Motor Stopp.... Buchstabe "s"
       stop_flag = 1;
       break;

       case 0x65: //Motor einschalten... Buchstabe "e"
       init_stepper(1);
       break;

       case 0x61: //Motor ausschalten... Buchstabe "a"
       init_stepper(0);
       break;

      // default:
     }
  
            rx_flag = 0; // Befehl ausgeführt, neue Daten dürfen ankommen       

       
    
 }
}


/***** UART CODE TEIL *****/

void init_uart()
{
      /*UART: 8 Datenbits; keine Parität; 1 Stopbit*/
  
  UCSRB |= (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
  UCSRC |= (3<<UCSZ0);

  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL;
}


ISR(USART_RX_vect)
{
  received_data[i] = UDR; // Lade die empfangenen Bystes in den Daten-Puffer
  
  UDR = 'i';  

  if(received_data[i]==0x21) // !-Zeichen erhalten, Befehl fertig => Flag setzen.
  {
  UDR = 'r';
  rx_flag = 1;
  
  i=0;
  }
  else
  {
  i++;  
  }  
}


Danke !

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du prügelst Daten in UDR ohne darauf zu warten das die Daten
gesendet wurden:
  UDR = 'i';  

  if(received_data[i]==0x21) // !-Zeichen erhalten, Befehl fertig => Flag 
  {
   UDR = 'r';

Und hier
    UDR = 'p';
  
     switch (received_data[0])
     {    
             // Motor drehen.... Buchstabe "d"
       case 0x64:  
             UDR = 'd';

Autor: magnetus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> int  rx_flag;     // Status-Flag für vollständig übertragene Befehle...

Mach da mal ein "volatile" davor.
volatile int  rx_flag;     // Status-Flag für vollständig übertragene Befehle...

Gruß,
Magnetus

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ holger: das stimmt, das sollte ich ändern. Am besten schreibe ich eine 
Funktion, welche die Daten senden, aber davor mit einer If Bedingung 
überprüft ob die Daten alle fertig gesendet sind.

@ magnetus:

Das mit volatile hat funktioniert. Was macht dieses volatile ? benötigt 
man dieses volatile extra, weil die Zuweisung rx_flag = 1 in einer 
Interrupt Routine statt findet ?


Jetzt erhalte ich allerdings nachdem Senden von d! iip, also die 
if-Bedingung reagiert, aber leider erhalte ich nicht das "r" für das 
!-Zeichen. Vielleicht liegt das an dem "prügeln" der Daten in den UDR :)

Ich arbeite daran und werde ich mich ggf. wieder melden !

Vielen Dank an euch beide.

MfG,
MC_AVR

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MC_AVR schrieb:
> Das mit volatile hat funktioniert. Was macht dieses volatile ? benötigt
> man dieses volatile extra, weil die Zuweisung rx_flag = 1 in einer
> Interrupt Routine statt findet ?


http://www.imb-jena.de/~gmueller/kurse/c_c++/c_volat.html


o-ton. man kann sich auch mal bemühen... ;-)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Interrupt

Autor: magnetus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: MC_AVR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo !

Ein volatile vor char received_data[10] hat auch die restlichen Probleme 
gelöst. Vielen Dank !

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.