skicka seriell data med c++

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

skicka seriell data med c++

Inlägg av mullemeck »

Hej!

Någon som har erfarenhet av att skicka data seriellt från ett console c++ program via com-porten?

har lite problem å få igång det..


/mullemeck
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

kör du inp() och outp()??

Isf med vilket operativsystem?
Användarvisningsbild
axelsonic
EF Sponsor
Inlägg: 709
Blev medlem: 8 juni 2003, 20:56:03
Ort: Stockholm

Inlägg av axelsonic »

Precis som ovanstående talare så kan man med fördel använda sig av inpb(); samt outpb();. DOCK så fungerare detta inte om man använder ett operativsystem som är av modernare slag, ex. win2k, XP eller motsv.
Detta pga av NT-kärnan.

På Win9X, WinME och de tidigare versionerna går det utmärkt. Bara att ta reda på adressen tillporten och därefter skriva direkt till den outportb(adress, tal); eller om det var tvärtom =P .

Använder du Linux, så är det ännu enklare, här är lite exempelkod.
http://www.comptechdoc.org/os/linux/pro ... erial.html

Lycka till.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

mullemeck: Hur har du gjort det? Är det ett event-stryrt program som ligger och i en loop och läser av händelser med GetMessage()/PeekMessage(), eller är det kodat på "vanligt icke windows"-sätt utan events?


Hur som helst så burkar jag fylla i lämplig info i en DCB medlest BuildCommDBC(), öppna en filehandle till commporten med CreateFile() med READ+WRITE och EXISTING. Därefter kan det vara bra att sätta lite timouts och bufferstorlekar och sådant med SetCommState(), SetupComm() och SetCommTimeout(). Kanske man inte ska glömma att slå på DTR/RTS med EscapeCommFunction() heller.

Därefter är det bara att köra WriteFile() och ReadFile() på den handle som man fick av CreateFile().

Hur långt har du kommit med det hela? Och vart skiter det sig nånstans?
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Tror även att det går att köra dessa funktioner om man använder sig av ioport.dll
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Fast varför skulle man vilja använda kernel32-rutinerna om man har en hjälp-dll som ioport.dll (som väl gör det åt en)? Det känns som antingen så är kernel32-anropen onödiga eller så är ioport.dll det.

Eller får man massa extra trevlig funktionalitet av ioport.dll?
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Grejen är väl den att dessa funktioner inp() och outp() använder sig av instruktionerna in och out. Dessa instruktioner är tydligen inte tillåtna att köra om man inte är i supervisor mode. Därav får man man nåt fel i stil med "priviliged instruction bla bla bla" då man kör programmet.

Tror att den här ioport.dll fixar så att man får använda dessa.
Jag har själv aldrig testat ioport.dll. Har bara läst nåt sånt.

XP, NT och 2000 ska ju ha sån kontroll på all hårdvara så man blir snart lite elak! :wink:
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Ok, då förstår jag. "dessa funktioner" åsfyftade inp/outp och intte kernel32-rutinerna.

Fast jag misstänker att inp/outp är mera praktiska för LPT än COM. Detta med tanke på att man bör sätta upp en interrupthanterad mottagning med en cirkulär buffer för mottagning på kommporten, annars riskerar man att tappa tecken om det kommer in en burst med tecken i hög hastighet. På printerporten har man oftast inte sådana problem eftersom det är mestadels ett ut-device.

Man skulle förvisso kunna sätta upp en cirkulär interruptstyrd rx-buffer manuellt med hjällp av ioport.dll (eller det kanske till och med finns färdigimplementerat i den?), men då tror jag nästan att det blir enklare, stabilare och mer portabelt med OpenFile-metoden.
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

Inlägg av mullemeck »

Förlåt, jag uttryckte mig nog lite knapphänt i första inlägget..

det jag vill göra är att skicka ut 150 byte, ett byte i taget till com-porten i 2400 baud.

de värden jag vill skicka ut ligger i en array..

jag kör med bloodshead devc++ under window xp.


jag är ganska newbie på c++ så jag skulle uppskatta lite exempelkod.
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Okej, Matseng. Ser nu att det blev lite oklart där med mitt inlägg när det kom ett annat inlägg emellan.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Ett snabbt hophackat exempel på att skicka en sträng till serieporten, det borde räcka för att få igång dig.

Jag kan förressten rekommendera PORTMON från SysInternals http://www.sysinternals.com/ntw2k/utilities.shtml , med det kan man spionera på allt dom har med porten att göra. Alla inställningar som görs, data, events osv. Mycket praktiskt.

Nåväl, här är mitt 5-minuters exempel-hack:

Kod: Markera allt

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>


int main(int argc, char* argv[]) {
	char sTmp[100]; 
	HANDLE	hPort;
	DCB dcb;
	BOOL bResult;
	char data[250];
	unsigned long datalen;
	unsigned long byteswritten;

	// Öppna porten
	hPort=CreateFile("COM3:",
	    GENERIC_READ|GENERIC_WRITE,
	    0,
	    NULL,
	    OPEN_EXISTING, 
	    FILE_ATTRIBUTE_NORMAL, 
	    0);

	if (hPort==INVALID_HANDLE_VALUE) {
		perror("CreateFile");
	                return 1;
	}
	

	// Bygg upp en inställningstruktur
	ZeroMemory(&dcb,sizeof(DCB)); 
	strcpy(sTmp,"baud=2400 parity=N data=8 stop=1"); 
	if (!BuildCommDCB((char*)&sTmp,&dcb)) {
		perror("BuildcommDCB");
		return 1;
	}

	// Peta in inställningarna på porten
	bResult=SetCommState(hPort,&dcb);
	if (!bResult) {
		perror("SetCommState");
		return 3;
	}


	// Slå på DTR/RTS
	EscapeCommFunction(hPort, SETDTR);
	EscapeCommFunction(hPort, SETRTS);

	// Skicka lite data till porten
	strcpy(data,"ALLAN TAR KAKAN I 2400 BAUD\n");
	datalen=strlen(data);
	bResult=WriteFile(hPort,data,datalen,&byteswritten,NULL);
	if (!bResult) {
		perror("WriteFile");
		return 5;
	}

	printf("Skrev %ld av %ld bytes\n",byteswritten,datalen);

	// Stäng porten
	CloseHandle(hPort);
	
	printf("done\n");
	return 0;
}
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

Inlägg av mullemeck »

okej. tack så jättemycket.. ska försöka göra något vettigt av det...
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

Inlägg av mullemeck »

Tack igen för koden matseng, funkar prima nu. bara lite kringarbete så kommer det bli super sen..
Användarvisningsbild
fredde76
Inlägg: 117
Blev medlem: 28 oktober 2003, 21:17:40
Ort: Uppsala

Inlägg av fredde76 »

Kan ge ett litet tips om ett färdigt klasspaket för dem som använder C++.
http://www.bbdsoft.com/downloads/win32/comport.zip

Fantastiskt smidigt och enkelt!!
Skriv svar