loetstelle.net
Lötstelle Userforum
 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Motorsteuerung mit Atmega644p

 
Neues Thema eröffnen   Neue Antwort erstellen    loetstelle.net Foren-Übersicht -> Mikrocontroller
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
truth



Anmeldungsdatum: 12.10.2012
Beiträge: 5

BeitragVerfasst am: Fr 12.Okt 2012 12:25:52    Titel: Motorsteuerung mit Atmega644p Bauteile finden Antworten mit Zitat

Hallo erstmal!

Ich versuche gerade Befehle(Koordinatenositionen) von meinem PC zu einem
Motortreiber über meinem Mikrocontroller (der ATmega644p, der 2
USART-Port besitzt (USART0 und USART1) zu senden.

Das Protokoll soll folgendermaßen aussehen:
- Der PC schickt zunächst die Befehle über USART0 nacheinander an dem
Mikrocontroller. Jeder Befehl sieht so aus: \nx,y\r.
mit \n: Beginn des Befehls
x: Position auf der x-Achse
,: Trennung zwischen x und y
y: Position auf der y-Achse
\r: Ende des Befehls
- Der Mikrocontroller leitet die empfangenen Daten an dem Motortreiber
nacheinander über USART1 weiter. Dabei muss der Mikrocontroller auf ein
Feedback des Motortreibers für jede weitergeleiteten Data warten bevor
er der nächste Befehl schickt.
Dh, zwischen zwei Befehlen, muss der Motortreiber ein Feedback zum
Mikrocontroller liefert, um bescheid zu sagen, ob der empfangene Befehl
als gültiger oder ungültiger Befehl betrachten muss.

Beispiel: gesendetes Befehl --------------------------------> "#2A\r"
Feedback Motortreiber(Wenn Befehl gültig ist) ----> "2A\r"
Feedback Motortreiber(Wenn Befehl ungültig ist) --> "2A?\r"

Der Motortreiber ist ansprechbar, wenn die Befehle folgendermaße
aussehen:
"Beginn des Befehls, Nummer des Motortreibers, Befehl zu ausführen, Ende
des Befehls "

Beispiel mit: "#3p2\r"
#: beginn des Befehls
3: Nummer des Motortreibers
p2: Arbeitsmodus
\r: Ende des Befehls


Irgendwie funktioniert das nicht so recht und ich komme einfach nicht
weiter. Ich vermute dass es an dem Zusammenspiel zwischen USART0 und
USART1 liegt.
Es gibt wahrscheinlich Konflikt zwischen ISR(USART0_RX_vect) und
ISR(USART1_RX_vect).

Vielleicht kann mir jemand hier helfen.
Ich wäre sehr dankbar

Mein Code lautet:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <util/delay.h>

#define F_CPU 9.6e6
#define FOSC 8000000 // Clock Speed
#define BAUD 115200UL

#define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1)   // clever runden
/**************************************************************/
#define usart_buffer_max_size 64u
#define usart_command_max_size 10

char usart_command[usart_command_max_size + 1] = {0};
char usart0_tx_buffer[usart_buffer_max_size];
char usart1_tx_buffer[usart_buffer_max_size];
volatile uint8_t usart_command_size = 0;
volatile uint8_t usart0_tx_buffer_size = 0;
volatile uint8_t usart0_tx_buffer_start = 0;
volatile uint8_t usart1_tx_buffer_size = 0;
volatile uint8_t usart1_tx_buffer_start = 0;
/**************************************************************/


/*************************************************************/
/* Configuration USART0, USART1 and setting Baudrate */

void USART_Init(unsigned int ubrr)
{
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char) ubrr;
  UBRR1H = (unsigned char)(ubrr>>8);
  UBRR1L = (unsigned char) ubrr;
  UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (0<<UDRIE0);
  UCSR0C = (1<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);
  UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (0<<RXCIE1) | (0<<UDRIE1);
  UCSR1C = (1<<USBS1) | (1<<UCSZ11) | (1<<UCSZ10);
}

/**********************************************************/

/*-- function receive USART0 --*/

unsigned char USART0_Receive (void)
{
    while(!(UCSR0A & (1<<RXC0)) ); // Wait for data to be received
   
     return UDR0; // Get and return received data from buffer
}


/*-- function transmit USART0 --*/

void USART0_Transmit (unsigned char data0)
{
  while ( !(UCSR0A & (1<<UDRE0)) ); // Wait for empty transmit buffer 
 
   UDR0 = data0; // Put data into buffer, sends the data
}

/*-- function receive USART1 --*/

unsigned char USART1_Receive (void)
{
  while(!(UCSR1A & (1<<RXC1)) );  // Wait for data to be received
   
   return UDR1; // Get and return received data from buffer
}

/*-- function transmit USART1 --*/ 

void USART1_Transmit (unsigned char data1)
{
  while ( !(UCSR1A & (1<<UDRE1)) ); // Wait for empty transmit buffer 
   
   UDR1 = data1; // Put data into buffer, sends the data 
}

/**********************************************************/

/* Eingang vom Ringpuffer */
void USART0_QueueIn(char c)
{
  int i;

  if (usart0_tx_buffer_size < usart_buffer_max_size)
  {
    i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
    usart0_tx_buffer[i] = c;
    ++usart0_tx_buffer_size;
  }
}

/* Ausgang vom Ringpuffer */
char USART0_QueueOut(void)
{
  char c;

  if (usart0_tx_buffer_size == 0)
    return 0;
  c = usart0_tx_buffer[usart0_tx_buffer_start];
  --usart0_tx_buffer_size;
  usart0_tx_buffer_start = (usart0_tx_buffer_start + 1) % usart_buffer_max_size;
  return c;
}

/* Eingang vom Ringpuffer */
void USART1_QueueIn(char c)
{
  int i;

  if (usart1_tx_buffer_size < usart_buffer_max_size)
  {
    i = (usart1_tx_buffer_size + usart1_tx_buffer_start) % usart_buffer_max_size;
    usart1_tx_buffer[i] = c;
    ++usart1_tx_buffer_size;
  }
}

/* Ausgang vom Ringpuffer */
char USART1_QueueOut(void)
{
  char c;

  if (usart1_tx_buffer_size == 0)
    return 0;
  c = usart1_tx_buffer[usart1_tx_buffer_start];
  --usart1_tx_buffer_size;
  usart1_tx_buffer_start = (usart1_tx_buffer_start + 1) % usart_buffer_max_size;
  return c;
}

/* Sendung einer Antwort über der Ringpuffer zum USART0 */
static void USART0_Send(const char *s)
{
  int i;
 
  for (i = 0; s[i] != 0; ++i)
    USART0_QueueIn(s[i]);
  if (usart0_tx_buffer_size > 0)
    UCSR0B |= 1 << UDRIE0;
}

/* Sendung eines Befehls über der Ringpuffer zum USART1 */
static void USART1_Send(const char *s)
{
  int i;
 
  for (i = 0; s[i] != 0; ++i)
    USART1_QueueIn(s[i]);
  if (usart1_tx_buffer_size > 0)
    UCSR1B |= 1 << UDRIE1;
}


/* Verarbeitung eines Befehls */
static void ProcessCommand(void)
{
  int i;
  int x;
  int y;
  char x_moteur[12];
  char y_moteur[12];

 
  /* Extraktion von X und Y */
  for (i = 0; i < usart_command_size; ++i)
    if (usart_command[i] == ',')
      break;

  if (i <= 0 || i >= usart_command_size - 1)
  {
    /* Man hat kein Kommazeichen in Mitte des Strings gefunden -> Fehler */
    USART0_Send("\x15");  /* NAK, Sendung hat nicht geklappt. */
    usart_command_size = 0;
    return;
  }
  /* Ich wandle x und y in Integer um, um Berechnung durchzuführen, wenn es nötig ist */
    usart_command[i] = 0;
    usart_command[usart_command_size] = 0;
    x = atoi(usart_command);
    y = atoi(usart_command + i + 1);
    usart_command_size = 0;
   itoa(x, x_moteur, 10);
    itoa(y, y_moteur, 10);

   /* Sendung Koordinatenposition x_moteur */
  USART1_Send("#3s");
  USART1_Send(x_moteur);
  USART1_Send("\r");
  UCSR1B = (1<<RXCIE1);

  USART1_Send("#3A\r"); // Aktivierung der Sendung von x_moteur über USART1
  UCSR1B = (1<<RXCIE1);
 
  /* Sendung Koordinatenposition y_moteur */
  USART1_Send("#2s");
  USART1_Send(y_moteur);
  USART1_Send("\r");
  UCSR1B = (1<<RXCIE1);
   
  USART1_Send("#2A\r");  // Aktivierung der Sendung von y_moteur über USART1
  UCSR1B = (1<<RXCIE1);

  USART1_Send("#3C\r"); // Aktuelle position der Platine nach Bewegung auslesen
  UCSR1B = (1<<RXCIE1);

  USART1_Send("#2C\r"); // Aktuelle position der Platine nach Bewegung auslesen
  UCSR1B = (1<<RXCIE1);
 
  }

/* La fonction d´interruption de reception du byte */
/* Cette fonction est active lorsque RXCIE0 = 1 */
ISR(USART0_RX_vect)
{
  char data;
  data = UDR0;

  if (data == '\r')
  {
    /* Verarbeitung des Befehls -->("/n X,Y /r") */
   /* X = x_moteur und Y = y_moteur */
     ProcessCommand();
         
   }
  else if (data == '\n')
  {
    /* Erzeugung eines neuen Befehls */
    usart_command_size = 0;
  }

  else
  {
    /* Als man weder \r, noch \n empfängt, speichert man
   die Koordinatenposition(X,Y) in einem Befehl */
    if (usart_command_size < usart_command_max_size)
    {
      usart_command[usart_command_size] = data;
      ++usart_command_size;
    }
  }
}

/* Dieser ISR dient zum Empfang von Antwort des Motortreibers.
Der Motortreiber sendet Rückmeldung zum Mikrocontroller
via USART1 automatisch, wenn er Befehl empfängt  */
ISR(USART1_RX_vect)
{
 char stringresponse[30] ;
 stringresponse[30] = UDR1;

 switch(stringresponse[30])
 {
   case '3c\r':
   stringresponse[0] = '\0'; // String entleeren
   UCSR1B = (0<<RXCIE1); // Deaktivierung von Empfangsinterrupt
   break;

   case '2c\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '3p2\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '2p2\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '3sx_moteur\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '3A\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '2sy_moteur\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '2A\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '3C\r':
   stringresponse[0] = '\0';
   UCSR1B = (0<<RXCIE1);
   break;

   case '2C\r':
   stringresponse[0] = '\0';
 /* Rückmeldung zum pc, um die Sendung der nächsten
    Koordinatenposition (X,Y) zu freigeben */
   USART0_Send("\x06"); // "ACK"
   UCSR1B = (0<<RXCIE1);
   break;

   default:
 /* Rückmeldung zum pc, um die Sendung der nächsten
    Koordinatenposition (X,Y) zu verhindern */
   USART0_Send("\x15"); // "NAK" 

 }
 
}

ISR(USART0_UDRE_vect)
{
  UDR0 = USART0_QueueOut();
  /* S'il n'y a plus de données à envoyer on arrete l'emission */
  if (usart0_tx_buffer_size == 0)
    UCSR0B &= ~(1 << UDRIE0);
}

/* La fonction d´interruption d´envoi de byte */
/* Cette fonction est active lorsque UDRIE1 = 1 */
ISR(USART1_UDRE_vect)
{
  UDR1 = USART1_QueueOut();
  /* S'il n'y a plus de données à envoyer on arrete l'emission */
  if (usart1_tx_buffer_size == 0)
    UCSR1B &= ~(1 << UDRIE1);
}

void EinstellungMotor(void)
 {
   USART1_Send("#3c\r"); // Festlegen der Position der Platine als Ursprung auf die x-Achse
   UCSR1B = (1<<RXCIE1); // Aktivierung von Empfangsinterrupt USART1

   USART1_Send("#2c\r"); // Festlegen der Position der Platine als Ursprung auf die y-Achse
   UCSR1B = (1<<RXCIE1);
   
   USART1_Send("#3p2\r");// Arbeitsmodus: Absolut --> p = 2
   UCSR1B = (1<<RXCIE1);

   USART1_Send("#2p2\r"); // Arbeitsmodus: Absolut --> p = 2
   UCSR1B = (1<<RXCIE1);     
 }
 

int main (void)
{
  USART_Init(UBRR_VAL); // Initialisierung von USART0 and USART1
  EinstellungMotor(); // Initialisierung Motorsteuerung
  sei(); // Aktierung Interruptsfunktion
 
 
  while (1) // Endlosschleife
  {
      
  }
 
}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
loetadmin
Site Admin


Anmeldungsdatum: 31.12.2004
Beiträge: 1022

BeitragVerfasst am: Sa 13.Okt 2012 09:11:13    Titel: Bauteile finden Antworten mit Zitat

Abgesehen davon, dass ich keine französischen Kommentare lesen kann:

In den Interrupt-Routinen wird ja recht viel gemacht, unter anderem auch Ausgabe auf der Seriellen Schnittstelle, mit Warten auf freien Datenpuffer etc.
Auch wird in der Funktion process_command irgendwas mit atoi und itoa gemacht, das sind recht langsame Funktionen und die gehören nicht in eine ISR.

Das solltest Du also mal anders lösen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
truth



Anmeldungsdatum: 12.10.2012
Beiträge: 5

BeitragVerfasst am: Mo 12.Nov 2012 13:08:51    Titel: Bauteile finden Antworten mit Zitat

Guten Tag,

ich habe meine Empfangsinterrupt-Funktion anders strukturiert und führt jetzt das Senden von Befehle in der main-Funktion aus.

Nach dieser Änderung kann ich schritt für schritt die Befehle senden. Aber wenn ich auf einmal alle Befehle sende, dann führt der Mikrocontroller höchsten drei Befehle aus. Was mache ich noch falsch ?

Ich wäre sehr dankbar, wenn jemand mir hilft.

Danke im Voraus.
Die Änderung sieht folgendermaße aus:
Code:


volatile uint8_t command_ready = 0;

// Interruptsfunktion für das Empfangen von Byte
// Diese Funktion ist High, wenn RXCIE0 = 1 
ISR(USART0_RX_vect)
{
  char data;
  data = UDR0;

 // Verarbeitung des Befehls -->("D X,Y F")
    // X = x_moteur und Y = y_moteur
  if (data == 'F')
  {   
    command_ready = 1;     
   }

  else if (data == 'D')
  {
    // Erzeugung eines neuen Befehls
    usart_command_size = 0;
  }

  else
  {
    // Als man weder F, noch D empfängt, speichert man
    //die Koordinatenposition(X,Y) in einem Befehl
    if (usart_command_size < usart_command_max_size)
    {
      usart_command[usart_command_size] = data;
      ++usart_command_size;
    }
  }
}

int main (void)
{
  USART_Init(UBRR_VAL); // Initialisierung von USART0 and USART1
  VorEinstellungMotor(); // Initialisierung Motorsteuerung
  sei(); // Aktierung Interruptsfunktion
 
 
  while (1) // Endlosschleife
  {
   if(command_ready)
    {
      ProcessCommand();
      command_ready = 0;
     
    }   
  }
 
}

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Anzeige






Verfasst am: Heute 00:50:10    Titel: Bauteile finden

Nach oben
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    loetstelle.net Foren-Übersicht -> Mikrocontroller Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum nicht herunterladen


Powered by phpBB 2.x © 2001, 2002 phpBB Group

Sie sind Besucher Nr. 1220906
©opyright by Markus Vohburger 2005 All Rights reserved