Forum: PC-Programmierung RS232 Windows Api C++ DTR und RTS takten


von Barth (Gast)


Lesenswert?

Hallo Zusammen.
Ich habe mich wie schon viele hier jetzt auch mit der RS232 beschäftigt.
Ein paar Daten
OS: Windows XP
Compiler: Borland C++

Mein Ziel
Einen A/D Wandler auslesen.

Mein aktueller Stand.
Funktionstüchtiges Programm (mit minimaler Ausstattung, Sicherheit usw) 
um über die API Daten über die Datenleitung TxD zu senden.

Mein Anliegen.

Ich kann jetzt so zu sagen über Bitfolgen ein High und low senden, mit 
dem ich meinen AD wandler auslesen kann.
Allerdings brauch ich noch einen zweiten ausgang, den ich für die 
Wandlung der Daten 17mükrosekunden hochziehen kann.
Daher will ich die DTR leitung dafür nutzen.
Allerdings weis ich nicht genau wie ich sie geziehlt anspechen kann. Bei 
dem Start von meinem Programm wird sie hochgezogen, aber das wars dann 
auchs schon.
Es wäre schön wenn mir jemand einen link schicken kann um das nach zu 
lesen.

Zur Info.
Die Msdn links habe ich schon alle dazu gelesen und mehr bzw weniger gut 
verstanden. Borlandhilfe zu dcb habe ich auch schon durch, aber mir kam 
bis jetzt kein toller Gedanke.

Hier jetzt noch mein Programm. Nur die c++ unit
wenn ihr die oberfläch auch braucht, einfach bescheid sagen.
Vielen Dank für eure Hilfe




//---------------------------------------------------------------------- 
-----

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------- 
-----
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------- 
-----
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------- 
-----

DCB dcb;
HANDLE hCom;
int a=1,i=0;
DWORD BytesRead, BytesWrite, Dat;
int portid;
char *ComPort[] = {"none","COM1","COM2","COM3","COM4","COM5","COM6"};

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
WriteFile (
  hCom,
  &Dat,
  2,
  &BytesWrite,
  NULL);

a=a+1;
Label3->Caption=IntToStr(a);
}
//---------------------------------------------------------------------- 
-----


void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
Timer1->Enabled=SpeedButton1->Down;
}
//---------------------------------------------------------------------- 
-----


void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
portid=StrToInt(Edit1->Text);
Label2->Caption=IntToStr(portid);

hCom = CreateFile(ComPort[portid],
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     OPEN_EXISTING,
     0,
     NULL);

if (hCom == INVALID_HANDLE_VALUE)
{
  AnsiString error_1 = GetLastError();
  Application->MessageBoxA(error_1.c_str(), "Info");
}

dcb.BaudRate = CBR_256000;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl= RTS_CONTROL_DISABLE;
dcb.fInX = FALSE;

if (hCom == INVALID_HANDLE_VALUE)
{
  AnsiString error_1 = GetLastError();
  Application->MessageBoxA(error_1.c_str(), "Info");
}
}
//---------------------------------------------------------------------- 
-----

void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
{
CloseHandle( hCom);
}
//---------------------------------------------------------------------- 
-----

void __fastcall TForm1::Edit2Change(TObject *Sender)
{
Timer1->Interval=StrToInt(Edit2->Text);
}
//---------------------------------------------------------------------- 
-----

von Frank K. (fchk)


Lesenswert?

Schau Dir an:

http://msdn.microsoft.com/en-us/library/aa363214%28v=VS.85%29.aspx

und

http://msdn.microsoft.com/en-us/library/aa363436%28v=VS.85%29.aspx

Im Klartext:

dcb.fDtrControl = DTR_CONTROL_DISABLE; // bzw DTR_CONTROL_ENABLE
dcb.fRtsControl= RTS_CONTROL_DISABLE;  // bzw RTS_CONTROL_ENABLE
SetCommState(hCom,&dcb);

von Dietmar (Gast)


Lesenswert?

Die DTR-Leitung kannst du direkt über:
 EscapeCommFunction(com_port,SETDTR);
beinflussen. Wobei com_port ein HANDLE auf den Port ist, in deinem Fall 
hcom.

Gruß Dietmar

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Barth schrieb:
> Allerdings brauch ich noch einen zweiten ausgang, den ich für die
> Wandlung der Daten 17mükrosekunden hochziehen kann.
> Daher will ich die DTR leitung dafür nutzen.

Du wirst nicht ansatzweise an 17 µs Dauer herankommen, bestenfalls wirst 
Du im einstelligen Millisekundenbereich landen.

Die serielle Schnittstelle für "bitbanging" zu verwenden, ist mit PCs 
und den darauf üblicherweise laufenden Betriebssystemen ein 
Designfehler.

von Barth (Gast)


Lesenswert?

Hallo Leute.
Vielen Dank für euren kompetenten Antworten. Ihr habt mir sehr weiter 
geholfen. Ich habe es jetzt mit der Funktion 
EscapeCommFunction(com_port,SETDTR);
gelöst.
Einfach in meinen Timer eingebaut.
Danke schon mal.

@Rufus Τ. Firefly
Mir ist klar das Windows nicht echzeitfähig ist und das bei einem RS232 
USB umsetzer bei meiner Methode Windows ohne Datenverkehr im 
schlechtesten fall 20 ms von einer bis zur nächsten Abfrage braucht, 
obwohl die daten schon längst an der Schnitstelle sind.
Wenn ich jetzt aber eine PCI Karte benutze ist dies doch IO mapped und 
ich müsste da doch schneller zu greifen können oder?
Hast du da erfahrungen?

Ansich hat mein Projekt bis jetzt noch keine richtige Anwendung, bis 
auch das dass ich ein bischen Programmieren lernen will und mir das 
ganze evlt für mein Studium was bringt.

Ist Linux in der hinsicht "Echtzeit" fähiger als windows?
Oder ist die RS232 für solche sachen gänzlich ungeeignet?

Wie machen das AD Wandler Hersteller. Messen die so oft wie der Ad 
wandler kann, buffern das in einem Hardwarezwischenspeicher und Mitteln 
das ganze und übersenden dann an die rs232?

Danke noch mal für eure Antworten.
Ist echt ein super Forum hier

von Εrnst B. (ernst)


Lesenswert?

Barth schrieb:
> Ist Linux in der hinsicht "Echtzeit" fähiger als windows?
Nicht wirklich. Gibt natürlich spezialisierte Linux-Abkömmlige mit 
Echtzeiterweiterungen...

> Oder ist die RS232 für solche sachen gänzlich ungeeignet?

Genau. Ist schon immer als Serielle Schnittstelle gedacht gewesen, nicht 
als "Satz von Bitwackel-GPIOs".

> Wie machen das AD Wandler Hersteller. Messen die so oft wie der Ad
> wandler kann, buffern das in einem Hardwarezwischenspeicher und Mitteln
> das ganze und übersenden dann an die rs232?

Die nehmen einen µC der auf der einen Seite den ADC bedient, auf der 
anderen über RS232 die Daten weiterreicht. Klappt dann ohne 
Timing-Probleme immer und überall, auch über USB->Rs232 Wandler.

von Barth (Gast)


Lesenswert?

Wow, schnelle Antwort.
Ok das verstehe ich soweit. Aber wenn ich den uc dann wieder an windows 
anstöpsle war das doch fast "umsonst" da ich ja dann meine daten wieder 
nicht schneller bekomme oder? Ich meine klar ich kann meine Daten gut 
auslesen, habe somit einen leichteren Datenverkehr. Das ist ja dann 
eigentlich wieder recht lahm. So gesehn für eine Dokumentation recht 
gut, aber nicht aum auf Messdaten zu reagieren bzw zu regeln.
Aber das ist jetzt hier warscheinlich offtopic.

Also ich habe jetzt an meinem Oszi 10 ms pulse. Meint ihr das man da 
noch mehr rausholen kann?

von Christian R. (supachris)


Lesenswert?

Naja, der Datentransfer muss dann sinnvollerweise in Blöcken erfolgen, 
damit siend gerade bei den USB Wandler viel höhere Datenraten möglich, 
als bei Byteweise Übertragung. Im Normalfall wird das Messsignal durch 
den µc äquidistant abgetastet und zwischengespeichert und dann zum PC 
übertragen. Bei Streaming-Anforderungen nimmt man dazu sinnvollerweise 
FIFO Speicher. Natürlich muss dann die Datenrate zum PC immer schneller 
sein als die Datenrate am ADC, denn der PC mit OS macht gerne mal 
Pausen.

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
Noch kein Account? Hier anmelden.