Uebertragung von Inhalt einer Textdatei über einen seriellen port RS232
-
Hallo esrtmal,
ich bin anfänger im Gebiete WinApi und brauche ihre Unterstützung, um mein C++-Code zu beenden.
Ich arbeite unter Windows XP und möchte die Positionen x und y von meiner Textdatei zu einem Mikrocontroller atmega644p über der serielle Port RS232 senden. Die Textdatei enthält die positionen x, y und andere Symbole. Für meine Arbeit beschäftige ich mich nur mit jeder Position x und y. Die andere Symbole sind unwichtig. In der Textdatei befinden sich die Positionen x und y in Ascii-Form.
Ich habe versucht, ein c++-Code zu schreiben, damit man die Textdatei Zeile für zeile ausliest. Dann ich habe mit Hilfe der Funktion CreateFile versucht, der serielle Port RS232 zu oeffnen, um später jede Position x und y in Byte-Form ueber die serielle Schnittstelle zu uebertragen.
Ich habe mein C++-Code debuggt und habe folgender Fehlermeldung auf mein Consol bekommen : " "Fehler: Die Oeffnung der serielle Port RS232 ist unmöglich" " .
Warum bekomme ich diese Fehlermeldung ?Bitte, was soll ich noch in meinem programm ändert, damit ich mit Erfolg jede Position x und y von der Textdatei auf dem seriellen Port RS232 uebertrage.
Danke im voraus.
mfg arthurdubois
Mein C++-Code lautet:
[cpp]
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>#include <Windows.h>
using namespace std;
int main(void)
{
ifstream file("koordinaten.txt", ios::in | ios::binary);
string line;if (!file)
{
cout << "Fehler: Die Oeffnung der Textdatei in Modus Auslesen ist unmöglich" << endl;
return 1;
}// Oeffung der Port COM1
HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
{
cout << "Fehler: Die Oeffnung der serielle Port RS232 ist unmöglich" << endl;
return 1;
}DCB dcb = { 0 };
BOOL dcbOk = GetCommState(h, &dcb);
dcb.BaudRate = CBR_115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = TWOSTOPBITS;
dcb.fOutxCtsFlow = FALSE; // Warum das und dann ein manueller Test von CTS ?
dcbOk = SetCommState(h, &dcb);// Auslesen Zeile pro Zeile
while (getline(file, line))
{
int x ; // x, y von Textdatei
int y ;
int x_steps; // x, y in Motorschritt
int y_steps;
stringstream input; // Eingangsfluss (Eine Zeile von Text)
stringstream output_x; // Ausgangsfluss (Ein Paar von Koordinaten)
stringstream output_y;// Eine Zeile wird ein Eingangsfluss
input.str(line);
// Extraktion von X und von Y.
if (input.get() != 'X')
continue;
input >> x;
//cout << x << endl;
if (input.get() != 'Y')
continue;
input >> y;
//cout << y << endl ;
// cout << x << ", " << y << endl;// Konversion der Positionen x und y in Motorschritt
x_steps = (x * 127) / 500;
//cout << x_steps << endl ;
y_steps = (y * 127) / 500;
//cout << x_steps << ", " << y_steps << endl;// Uebertragung von Koordinaten (x,y) ueber der serielle Port RS232
DWORD written = 0;
output_x << x_steps; // TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
WriteFile(h, output_x.str().c_str(), output_x.str().size(), &written, 0);
output_y << y_steps; // TODO: Ne manque-t-il pas un terminateur ou un cadrage ?
WriteFile(h, output_y.str().c_str(), output_y.str().size(), &written, 0);
// TODO: Et là, il ne faut pas attendre un retour ?
}
CloseHandle(h);
return 0;
}[\cpp]
Meine Textdatei sieht folgendermaße aus:
[/code]
%
M48
M72
T01C0.0320
T02C0.0394
T03C0.0400
T04C0.0440
T05C0.0512
T06C0.1181
%
T01
X21101Y24101
X10851Y16601
X13851Y19101
X10851Y22851
X11851Y22851
X12851Y22851
X12351Y24851
X11351Y24851
X10351Y24851
X9351Y24851
X8351Y24851
X7351Y24851
X6351Y24851
X16101Y22601
X18101Y22601
T04
X23351Y15101
X25351Y15101
X27351Y15101
X29351Y15101
X29351Y19101
X27351Y19101
X25351Y19101
X23351Y19101
X23351Y21601
X23351Y25601
X25351Y25601
X27351Y25601
X29351Y25601
X29351Y21601
X27351Y21601
X25351Y21601
T05
X33611Y6609
X33611Y8609
X33611Y10609
X33611Y12609
X33611Y14609
X33611Y16609
X33611Y18609
X33611Y20609
X33611Y22609
X33611Y24609
X24109Y6841
X26109Y6841
X28109Y6841
X30109Y6841
T06
X2101Y2101
X2101Y29601
X37101Y2351
X37351Y29601
M30[code]
-
Statt Ausgabe einer eigenen, möglicherweise falschen Meldung, besser mit GetLastError() die Fehlernummer holen.
Per FormatMessage kann man sich den Fehlertext dazu besorgen.
Alternativ die Fehlernummer selbst nachschauen:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381%28v=vs.85%29.aspxGibt es COM1 auf deinem System?
-
Hi,
Mein Pc hat die Schnittstelle "COM1".
mfg
arthurdubois
-
Nimm für cpp-/code-Tags doch lieber die Buttons, die verwechseln auch nicht Slash und Backslash.
-
Das gibt Dir den Fehler als Fehlernummer und im Klartext.
Dann weißt Du was nicht stimmt.char *fmsg = NULL; int fehler = 0; // Oeffung des Port COM1 HANDLE h = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (h == INVALID_HANDLE_VALUE) { fehler = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, fehler, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fmsg, 0, NULL ); cout << "Fehler: " << GetLastError() << endl << fmsg << endl; return 1; }
-
noergel schrieb:
Das gibt Dir den Fehler als Fehlernummer und im Klartext.
Dann weißt Du was nicht stimmt.Und wenn man es macht dann natürlich immer ...
BOOL dcbOk = GetCommState(h, &dcb); if (!dcbOk) { printf ("GetCommState failed with error %d.\n", GetLastError()); return (2); }
dcbOk = SetCommState(h, &dcb); if (!dcbOk) { printf ("SetCommState failed with error %d.\n", GetLastError()); return (3); }
siehe: Configuring a Communications Resource
http://msdn.microsoft.com/en-us/library/aa363201.aspxMöglicherweise sollte man auch auf die neue Schreibweise umstellen:
To specify a COM port number greater than 9, use the following syntax: "\\.\COM10". This syntax works for all port numbers ...
Baudrate und Bytesize sehen vertraut aus, allerdings sind 2 Stopbits eher unüblich.
Da es sich vermutlich um eine Nullmodem-Verbindung (ohne Hardware Handshake)
handelt würde mich die Verwendung von CTS und DTS wundern.Wenn es COM1 gibt und das erwartet Gerät wirklich angeschlossen ist sollte man
mit einem Schnittstellentester oder Skope mal nachsehen ob was übertragen wird.Beim Senden gegen Ende habe ich Bedenken ob das zuverlässich klappt. Wenn man
die X und Y Koordinaten mit variabler Länge ohne Trennzeichen als Text
hintereinander sendet wie soll der Empfänger das zuverlässlich trennen ?!! Wie man der beigelegten Koordinatenliste auch schon entnehmen kann werden mal
4 und mal 3 Byte gesendet!!DWORD written = 0; output_x << x_steps; // TODO: Ne manque-t-il pas un terminateur ou un cadrage ? WriteFile(h, output_x.str().c_str(), output_x.str().size(), &written, 0); output_y << y_steps; // TODO: Ne manque-t-il pas un terminateur ou un cadrage ? WriteFile(h, output_y.str().c_str(), output_y.str().size(), &written, 0); "
Und der Kommentar "attendre un retour ?" ist auch unbedingt zu beachten.
Bei einer Nullmodemverbindung ist es ratsam (und üblich) sich den Empfang
bestätigen zu lassen bevor man weitere Daten sendet. Der PC ist wohl erheblich
schneller als die meisten Microcontroller.Insbesondere:
Wenn der Microcontroller WIRKLICH so langsam ist, das er ZWEI Stoppbits
braucht ...(PS: Viele Grüsse nach Frankreich ...)
-
merano schrieb:
Da es sich vermutlich um eine Nullmodem-Verbindung (ohne Hardware Handshake) handelt würde mich die Verwendung von CTS und DTS wundern.
Was meinst du mit Nullmodem-Verbindung? Den Begriff verwendet man doch nur wenn man etwas was man normalerweise mit Modem macht, ohne Modem macht. Also z.B. zwei PCs über ein ausgekreuztes Kabel miteinander plaudern zu lassen.
Und wieso sollte "Nullmodem-Verbindung" "ohne Hardware Handshake" implizieren?Die meisten Geräte die man so an die serielle Schnittstellen anhängt können Hardware Handshake. Und wenn sie es können, dann sollte man es auch verwenden.
Bei einer Nullmodemverbindung ist es ratsam (und üblich) sich den Empfang
bestätigen zu lassen bevor man weitere Daten sendet. Der PC ist wohl erheblich
schneller als die meisten Microcontroller.Siehste, aus dem Grund verwendet man ja auch Hardware Handshake
-
hustbaer schrieb:
Und wieso sollte "Nullmodem-Verbindung" "ohne Hardware Handshake" implizieren?
Die meisten Geräte die man so an die serielle Schnittstellen anhängt können Hardware Handshake.
Und wenn sie es können, dann sollte man es auch verwenden.... , aus dem Grund verwendet man ja auch Hardware Handshake
Genau so ist es; hatte ich auch nicht anders behauptet. Es macht nur keinen
Sinn, wenn eines der beiden angeschlossenen Geräte keine Hardwareflusskontrolle
unterstützt.Im konkreten Fall geht es um die Verbindung eines PCs mit einem Microcontroller.
Dort ist es üblich 3-Draht-Nullmodem Verbindungen zu nutzen.Wenn Du mal einen Blick in das vom Fragesteller verwendete Datasheet vom
ATmega644 wirfst, wirst Du gleich auf der ersten Seite unter Features
"Byte-oriented Two-wire Serial Interface" finden.BTW: In meiner beruflichen Praxis setze ich serielle 3-Draht Verbindungen seit
den 80ern bevorzugt ein, weil der Aufwand für Full-Handshake meist nicht lohnt.
In Verbindung mit Nicht-PCs geht es meist garnicht anders.
Mit einem Software Handshake kann man oft flexibler auf Probleme reagieren.
-
Oh, Sorry, hatte nicht gesehen dass da ein Typ angegeben war.
Ja, OK, wenn Hardware Handshake nicht unterstützt wird, sollte man es natürlich auch eher nicht aufdrehen - wäre ja bloss verwirrend für jmd. der den Code später liest.
-
Moin nochmal,
ich habe mein Programm verbessert, aber meine Übertragungsfunktion EnvoieCommande(), die die Positionen X und Y von der Textdatei in Richtung der serielle Schnittstelle RS232 sendet, läuft nicht einwandfreie.
Mein verbessertes Programm lautet:
#include <fstream> #include <string> #include <iostream> #include <sstream> #include <Windows.h> using namespace std; // Sendet ein Auftrag Charakter pro Charakter und prüft das Empfangen von ACK static bool EnvoieCommande(HANDLE h, const char *s) { DWORD dummy; char c; // Wenn es gab, ab dem letzten Auftrag Antworten zu lesen, dann zu spät, //man löscht die Antworten PurgeComm(h, PURGE_RXCLEAR); for (int i = 0; s[i] != 0; ++i) if (!WriteFile(h, s + i, 1, &dummy, 0)) return false; if (!ReadFile(h, &c, 1, &dummy, 0)) return false; // Time-out return c == '\x06'; // ACK ---> in AScii x06 } int main(void) { ifstream file("koordinaten.txt", ios::in | ios::binary); string line; if (!file) { cout << "Fehler: Öffnung der Textdatei in Modus Lesen ist unmöglich" << endl; return 1; } char *fmsg = NULL; int fehler = 0; // Öffnung der serielle Port COM1Ouverture du port COM HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (h == INVALID_HANDLE_VALUE) { fehler = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, fehler, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &fmsg, 0, NULL ); cout << "Fehler: " << GetLastError() << endl << fmsg << endl; cout << "Fehler: Öffnung der serielle Port unmöglich" << endl; return 1; } DCB dcb = { 0 }; BOOL dcbOk = GetCommState(h, &dcb); dcb.BaudRate = CBR_115200; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = TWOSTOPBITS; dcbOk = SetCommState(h, &dcb); COMMTIMEOUTS timeouts = { 0 }; timeouts.ReadIntervalTimeout = 100; timeouts.ReadTotalTimeoutMultiplier = 100; timeouts.ReadTotalTimeoutConstant = 100; timeouts.WriteTotalTimeoutMultiplier = 100; timeouts.WriteTotalTimeoutConstant = 100; if (!SetCommTimeouts(h, &timeouts)) { cout << "Fehler: SetCommTimeouts" << endl; return 1; } if (!dcbOk) { printf ("GetCommState failed with error %d.\n", GetLastError()); return (2); } if (!dcbOk) { printf ("SetCommState failed with error %d.\n", GetLastError()); return (3); } // Lesen Zeile pro Zeile while (getline(file, line)) { int x; // x, y von Textdatei int y; int x_steps; // x, y in Schrittmotor int y_steps; stringstream input; // Eingangsfluss (Eine Zeile von Textdatei) stringstream output; // Ausgangsfluss (Ein Paar von Koordinaten) // Eine Zeile wird einen Eingangsfluss input.str(line); // Extraktion von X und Y. if (input.get() != 'X') continue; input >> x; if (input.get() != 'Y') continue; input >> y; // Konversion von Positionen X und Y in Schrittmotor x_steps = x * 127 / 500; y_steps = y * 127 / 500; // Sendung von koordinaten über der serielle port RS232 output << '\n'; output << x_steps; output << ','; output << y_steps; output << '\r'; cout << "Sendung von : " << output.str() << endl; if (EnvoieCommande(h, output.str().c_str())) cout << "OK" << endl; else cout << "Fehler" << endl; } CloseHandle(h); return 0; }
Die Fehlermeldung lautet:
Sendung von :
5359,6121
Fehler
Sendung von :
2756,4216
FehlerDie Sendefunktion EnvoieCommande() schickt kurz gesagt keine Daten . Meine Sendefunktion macht eigentlich nicht seine Aufgabe.
Bitte, kann jemand mir sagen, was in meinem Programm schiefläuft. Ich komme einfach nicht klar !! Ich bin auch für Korrektur offen.
Danke im Vorraus.
mfg
-
Wenn WriteFile/ReadFile fehlschlagen, sollte man eigentlich
GetLastError
aufrufen, um der Sache auf den Grund zu gehen. Du weißt so ja nicht mal, welche der beiden Funktionen fehlschlägt, geschweige denn, was im Detail schiefläuft.
-
Vielen Dank für deine Rückmeldung _matze .
Ich habe deine Anweisung befolgt und habe festgestellt, dass der Fehler nicht von meinem C++-Programm kommt, sondern von meinem µC. Weil der µC statt "ACK" komische Antwort zum PC zurückschickt. Deswegen hatte zum ersten mal meine Funktion EnvoieCommande() nicht funktioniert.
mfg
-
Hallo,
ich bin´s noch. Es geht immer über die Übertragung Zeile pro Zeile von Postionskoordinaten meiner Textdatei von PC zu den Mikrocontroller.
Eigentlich habe ich ein Kommunikationsproblem. Ich habe mein PC-Code geschrieben, so dass der PC Positionskoordinaten von der Textdatei zeile pro Zeile zum Mikrocontroller senden soll. Wenn der PC die erste Positionskoordinaten(X,Y) zum Mikrocontroller sendet, dann soll der PC auf eine Benachrichtigung der Mikrocontroller warten, bevor er die nächste Positionskoordinaten(X,Y) schickt.
Wenn ich die Positionskoordinaten(X,Y) der Textdatei Zeile pro Zeile (Schritt für Schritt) zum Mikrocontroller sende, läuft alles wunderbar.
Aber wenn ich auf einmal alle Positionskoordinaten der Textdatei zum Mikrocontroller sende, wird nur ein, zwei oder höchstens drei Positionskoordinaten ausgeführt. Aber die Andere Positionskoordinaten(X,Y) von Textdatei werden nicht gesendet.Woran kann das liegen ? Habe ich zufällig ein Problem von Handschake-Signal (RTS/CTS)? Wenn ja, wie soll ich das einsetzen.
Bemerkung: Der Mikrocontroller empfängt die Positionskoordinaten(X,Y), die vom PC gesendet wurde, mit Hilfe der Funktion ISR(USART0_RX_vect). Dann wird später in der Funktion ProcessCommand() eine Benachrichtigung zum PC gesendet, damit der PC die nächste Positionskoordinaten sendet.
Ich wäre sehr dankbar, wenn sie mir helfen.
Danke im Voraus.
C++-Code:
#include <fstream> #include <string> #include <iostream> #include <sstream> #include <Windows.h> using namespace std; // Senden eines Befehls Charakter pro Charakter und man prüft das Empfangen eines ACK, bevor die Sendung der nächsten Positionskoordinaten static bool SendungBefehl(HANDLE h, string s) { DWORD length; char c; // Wenn es seit dem letzten Befehl Antorten zu lesen gab, // Zu spät, alles muss gelöscht werden. PurgeComm(h, PURGE_RXCLEAR); if (!WriteFile(h, s.c_str(), s.size(), &length, 0) || length != s.size()) { cout << "Error von WriteFile" << endl; return false; } if (!ReadFile(h, &c, 1, &length, 0) || length != 1) { cout << "Error von ReadFile (time-out)" << endl; return false; } cout << "Antwort : " << (int)c << endl; return c == '\x06'; // ACK } int main(void) { ifstream file("koordinaten.txt", ios::in | ios::binary); string line; if (!file) { cout << "Error: Die Öffnung der Textdatein in Lesen-Modus ist unmöglich" << endl; return 1; } // Öffnung des seriellen Ports COM1 HANDLE h = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (h == INVALID_HANDLE_VALUE) { cout << "Error: Öffnung der seriellen Port ist unmöglich" << endl; return 1; } DCB dcb = { 0 }; BOOL dcbOk = GetCommState(h, &dcb); dcb.BaudRate = CBR_9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcbOk = SetCommState(h, &dcb); COMMTIMEOUTS timeouts = { 0 }; timeouts.ReadIntervalTimeout = 100; timeouts.ReadTotalTimeoutMultiplier = 100; timeouts.ReadTotalTimeoutConstant = 100; timeouts.WriteTotalTimeoutMultiplier = 100; timeouts.WriteTotalTimeoutConstant = 100; if (!SetCommTimeouts(h, &timeouts)) { cout << "Erreur: SetCommTimeouts" << endl; return 1; } // Lesen Zeile pro Zeile while (getline(file, line)) { int x; // x, y von der Textdatei int y; int x_steps; // x, y in Schrittmotor int y_steps; stringstream input; // Eingangsfluß (Eine Zeile der Textdatei) stringstream output; // Ausgangsfluß (Ein Koordinatenpaar) // Eine Zeile wird ein Eingangsfluß sein input.str(line); // Extraktion von X et du Y. if (input.get() != 'X') continue; input >> x; if (input.get() != 'Y') continue; input >> y; // Konvertierung von Positionkoordinaten(X,Y) in Schrittmotor x_steps = x * 127 / 500; y_steps = y * 127 / 500; // Sendung der PositionsKoordinaten Zeile pro Zeile über der serielle Port (COM1) output << 'D'; output << x_steps; output << ','; output << y_steps; output << 'F'; cout << "Sendung von : " << output.str() << endl; if (SendungBefehl(h, output.str())) cout << "OK" << endl; else cout << "ERROR" << endl; } CloseHandle(h); return 0; }
Mikrocontroller-Code:
#include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> # define F_CPU 3686400UL #include <util/delay.h> #define FOSC 7372000 // Clock Speed #define BAUD 9600UL #define UBRR_VAL ((FOSC+BAUD*8)/(BAUD*16)-1) // clever runden /////////////////////////////////////////////////////////////////// #define usart_buffer_max_size 512u #define usart_command_max_size 20 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; ///////////////////////////////////////////////////////////////////// volatile uint8_t command_ready = 0; ///////////////////////////////////////////////////////////////////// // 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; } else { usart0_tx_buffer_size = 0; } } // 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; } else { usart1_tx_buffer_size = 0; } } // 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]; 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 // Extraktion von X und Y 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 position x_moteur USART1_Send("#1s"); USART1_Send(x_moteur); USART1_Send("\r"); USART1_Send("#1A\r"); // Losfahren der Platine auf die x-Achse // _delay_ms(30000); // Warten 15000ms --> 15s // Sendung position y_moteur USART1_Send("#2s"); USART1_Send(y_moteur); USART1_Send("\r"); USART1_Send("#2A\r"); // Losfahren der Platine auf die y-Achse _delay_ms(30000); // Warten 30000ms --> 30s USART0_Send("\x06"); // ACK --> Freigage: PC kann nächste Data senden. } // 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; } else { usart_command_size = 0; } } } // Interruptsfunktion für Byte-Übertragung // Diese Funktion ist an, wenn UDRIE1 = 1 ISR(USART0_UDRE_vect) { UDR0 = USART0_QueueOut(); // Sendung stoppen, wenn es keine Daten mehr gibt zu senden if (usart0_tx_buffer_size == 0) UCSR0B &= ~(1 << UDRIE0); } // Interruptsfunktion für Byte-Übertragung // Diese Funktion ist an, wenn UDRIE1 = 1 ISR(USART1_UDRE_vect) { UDR1 = USART1_QueueOut(); // Sendung stoppen, wenn es keine Daten mehr gibt zu senden if (usart1_tx_buffer_size == 0) UCSR1B &= ~(1 << UDRIE1); } void VorEinstellungMotor(void) { //USART1_Send("#1|0\r"); // Deaktivierung von Antwort der Motorsteuerung Nr 1 //USART1_Send("#2|0\r"); // Deaktivierung von Antwort der Motorsteuerung Nr 2 //USART1_Send("#1:baud=7"); // Baudrate = 9600 //USART1_Send("#2:baud=7"); // Baudrate = 9600 USART1_Send("#1D0\r"); // Festlegen der Position der Platine als Ursprung auf die x-Achse USART1_Send("#2D0\r"); // Festlegen der Position der Platine als Ursprung auf die y-Achse USART1_Send("#1p2\r"); // Modus: Absolut Positionierung --> p=2 USART1_Send("#2p2\r"); // Modus: Absolut Positionierung --> p=2 } 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; } } }