Hallo, habe mir einen Parallel-Programmer für den AT90S8535 gebaut, an dem eine Erweiterungsplatine für die serielle Kommunikation über RS-232 angeschlossen ist. Die Erweiterungsplatine habe ich, wie im "AVR-Tutorial-6. Das UART" http://www.mikrocontroller.net/tutorial6.htm beschrieben, aufgebaut. Für den Funktionstest Zwischen Controller und PC verwende ich das Controller-Programm http://people.freenet.de/atavr/ser.asm Dieses Programm empfängt über RS-232 eine Textdatei vom PC und sendet sie wieder zurück. Auf dem PC läuft HyperTerminal. Auf dem Bildschirm im Fenster des HyperTerminal erscheint der Inhalt dieser Textdatei. Soweit funktioniert alles gut. Nun meine Frage: Ich möchte statt HyperTerminal ein C-Programm für den PC schreiben, das genau das oben beschriebene ermöglicht. Das Programm sollte es möglich machen, eine Datei (oder über die Tastatur eingegebene Zeichen)an den Controller senden und empfangen zu können(Anzeige auf dem Bildschirm oder auf die Festplatte speichern). Kann mir da jemand helfen? jan_
Wenn Du das unter Windwos machen willst, musst Du die Funktionen ReadFile und WriteFile benutzen. Als Compiler bietet sich der gcc an. Die IDE von dev-c++ ist sehr gut und kostenlos. Beides kannst Du unter www.bloodshed.net runterladen. Hiermit habe ich schon Software geschrieben, die vom PC zu externen MC-gesteuerten Geräten Datensätze sendet und empfängt. Hoffe hiermit ist Dir erstmal weiter geholfen. Grüße Andreas
Hallo Andreas, Danke dir für die Antwort. Am liebsten würde ich das unter Linux mit gcc bzw. gtk+ schreiben, kann aber auch für Windows sein. Vielleicht hat jemand ein paar Code-Beispiele zu dem speziellen Problem. Schöne Grüße jan_
Habe das wie ich es unter windows mit dem gcc gemacht habe nicht mehr gefunden, da ich das Programm mittlerweile geändert habe. Ich habe es für den Borland Builder erweitert. Insofern mußt Du Dir die entsprechenden Sachen hier rauskopieren. Fehlerabfrage beim Empfang/Senden muss auch noch ergänzt werden. Hier die Routinen um den Com-Port zu öffnen: #ifdef _BORLANDC_ COMMTIMEOUTS CommTimeouts; #else LPCOMMTIMEOUTS CommTimeouts; #endif char sComNo[20]; sprintf(&sComNo[0],"Com%d",ComPort); iCommId = CreateFile(sComNo, /* lpFileName */ GENERIC_READ | GENERIC_WRITE, /* dwDesiredAccess */ 0, /* dwShareMode */ NULL, /* lpSecurityAtributes */ OPEN_EXISTING, /* dwCreationDistribution */ 0, /* dwFlagsAndAttributes */ /* dwFlagsAndAttributes */ 0); /* hTemplateFile */ if (iCommId < 0) return false; else { GetCommState(iCommId, &fDCB); // fDCB.Flags=0; /* Setze die Flags im DCB */ fDCB.fBinary = ON; if (fHWFlowOptions == chwfUseRTS) fDCB.fRtsControl == ON; if (fHWFlowOptions == chwfUseDTR) fDCB.fDtrControl == ON; if (fHWFlowOptions == chwfRequireCTS) { fDCB.fOutX = ON; fDCB.fInX = ON; } // if (fHWFlowOptions == chwfRequireDSR) // SetDCBFlag(dcbfOutxDsrFlow); fDCB.XoffChar=cXOffChar; fDCB.XonChar=cXOnChar; fDCB.XonLim=iXonLimit; fDCB.XoffLim=iXoffLimit; // if (set::of(cswfBoth,cswfReceive, eos).has(SWFlowOption)) SetDCBFlag(dcbfInX); // if (set::of(cswfBoth,cswfTransmit, eos).has(SWFlowOption)) SetDCBFlag(dcbfOutX); fDCB.BaudRate=iBaudrate; fDCB.ByteSize=iDatabits; switch (fStopbits) { case csb1 : fDCB.StopBits=ONESTOPBIT; break; case csb1_5 : fDCB.StopBits=ONE5STOPBITS; break; case csb2 : fDCB.StopBits=TWOSTOPBITS; break; } fDCB.Parity=fParity; // if (fParity>cpNone) SetDCBFlag(dcbfParity); /* Setze DCB */ if(!SetCommState(iCommId,&fDCB)) throw("COMM - Error : SetCommState"); SetupComm(iCommId,iInSize,iOutSize); GetCommTimeouts(iCommId,&CommTimeouts); #ifdef _BORLANDC_ CommTimeouts.WriteTotalTimeoutMultiplier=1; CommTimeouts.WriteTotalTimeoutConstant=iSendTimeoutLength; CommTimeouts.ReadIntervalTimeout=10; CommTimeouts.ReadTotalTimeoutMultiplier=1; CommTimeouts.ReadTotalTimeoutConstant=iReceiveTimeoutLength; #else CommTimeouts->WriteTotalTimeoutMultiplier=1; CommTimeouts->WriteTotalTimeoutConstant=iSendTimeoutLength; CommTimeouts->ReadIntervalTimeout=10; CommTimeouts->ReadTotalTimeoutMultiplier=1; CommTimeouts->ReadTotalTimeoutConstant=iReceiveTimeoutLength; #endif SetCommTimeouts(iCommId,&CommTimeouts); return true; } Hiermit wird ein Zeichen gesendet: void SendChar(char Ch) { DWORD dWrCount; WriteFile(iCommId,&Ch,1,&dWrCount,NULL); } Hiermit ein ganzer String: void SendData(string& Str) { WriteFile(iCommId,&Str[1],Str.length(),&dWrCount,NULL); } einzelnes Zeichen einlesen: ( beim mehreren Zeichen cCharacter ändern und "iCommId,&cCharacter,X,...") char GetChar() { char cCharacter; DWORD iReadCount; bool bResult; bResult=ReadFile(iCommId,&cCharacter,1,&iReadCount,NULL); if (bResult) if (iReadCount==0) iLastError = CE_TIMEOUT; else iLastError = CE_OK; else iLastError = GetCommError(); if (iReadCount>0) return cCharacter; else return '\0'; } Ganz zum Schluss wieder Schliessen: if(CloseHandle(iCommId)) return true; else return false;
Hier findest Du die nötigen Informationen: http://www.fokus.gmd.de/linux/HOWTO/Serial-Programming-HOWTO/ Als Beispiel (zwar alt, aber immer noch gültig): http://www.linux-magazin.de/Artikel/ausgabe/1999/08/Messen/messen.html Ansonsten, wenn es simpel sein soll und Du keine Extrafunktionen brauchst, kannst Du ja mal ein man fopen/fclose/fgets/fwrite machen.
Hallo, habe mir das Linux Serial-Programming-HOWTO angeschaut und zum Testen in dort vorgestelltes Programm für meinen Zweck modifiziert: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #define MODEMDEVICE "/dev/ttyS0" main() { int fd, c, res, k; struct termios oldtio, newtio; char buf[255]; char buf1[]="123456789test1_test2_test3"; fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); if (fd < 0){perror (MODEMDEVICE); exit(-1)} tcgetattr(fd, &oldtio); bzero(&newtio, sizeof(newtio)); newtio.c_cflag = CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_lflag = 0; newtio.c_cc[VTIME] = 1; // 1/10 s auf Zeichen warten newtio.c_cc[VMIN] = 0; cfsetospeed(&newtio, B9600); cfsetispeed(&newtio, B50); // Fehlerfreier Empfang mit 50 Baud tcsetattr(fd, TCSANOW, &newtio); write(fd, buf1, sizeof(buf1)); for (k=0; k<30 k++) { res = read(fd, buf, sizeof(buf1)); buf[res] = 0; printf ("%s\n, buf"); } tcsetattr(fd, TCSANOW, &oldtio); close(fd); } //----------------------------------------- Es ergeben sich neue Fragen: 1. Vom PC wird über die serielle Schnittstelle zum Controller ein String buf1="123456789test1_test2_test3" geschickt. Das Controllerprogramm schickt ihn wieder zum PC zurück. Die 'Controller-Baudrate' ist , wie aus dem Controller-Assembler-Programm ersichtlich, auf 9600 Baud eingestellt. Wähle ich aber die gleiche Übertragungsrate im C-Programm (PC) mit Hilfe von cfsetospeed(&newtio, 9600) bzw. cfsetispeed(&newtio, 9600) aus, dann funktoniert der Empfang nicht fehlerfrei. Es treten folgende Fehler auf: PC-Baudrate, Senden/Empfangen 9600 Baud Die gesendeten und empfangenen Zeichen stimmen nicht überein. PC-Baudrate, Senden 9600 Baud/Empfangen 4800 Baud Erste 4 Bytes werden überhaupt nicht empfangen, völlig andere Zeichen bei ca. jedem dritten Empfangsversuch. PC-Baudrate, Senden 9600 Baud/Empfangen 1200 Baud erste 2 Bytes werden überhaupt nicht empfangen. Die restlichen Zeichen werden korrekt empfangen. PC-Baudrate, Senden 9600 Baud/Empfangen 50 Baud Alle Zeichen werden korrekt empfangen Wie kann ich das Programm(C unter Linux) ändern (oder neu schreiben?), um bei einer höheren Übertragungsrate(Empfang), a l l e Zeichen korrekt zu empfangen? Viele Grüße jan_
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.