Ik heb goede kennis van C++ en speel ook wat met VC++. Maar ik wil graag via een serialport of een parallelport data verzenden naar een microcontroller.

Ik heb VC++ 6.0, maar in de bibliotheek heb ik alle boeken nagecheckt en kan niks vinden over serialport of parallelport. Alleen maar hoe je Dialogbox of die andere met menus enz. kunt maken en codes aan buttons koppelen enz. Of hoe je zelf een internetpagina kunt maken of geluiden kunt afspelen en nog meer van die multimedia gedoe.

Kan iemand mij misschien helpen hoe ik zoiets moet aanpakken en hoe ik m.b.v. klasse kan aangeven dat ik bijv. 9600 baud wil hebben zonder pariteitsbit enz.?

Tot gauw!

Beste mensen, kan echt niemand mij helpen? :'(

Je zou het eens in de Discussiegroepen van Google kunnen proberen. Daar staat vaak een schat van informatie over dit soort problemen, het is een kwestie van zoeken. Tijdens mijn stage heb ik hier ook veel info over VC++ kunnen halen...

De serieele poort gebruiken vanuit VisualStudio gaat vrij eenvoudig.

Het volgende komt rechtstreeks uit de MSDN.


/* A sample program to illustrate setting up a serial port. */

#include <windows.h>

int
main(int argc, char *argv[])
{
  DCB dcb;
  HANDLE hCom;
  BOOL fSuccess;
  char *pcCommPort = "COM2";

  hCom = CreateFile( pcCommPort,
                     GENERIC_READ | GENERIC_WRITE,
                     0,    // comm devices must be opened w/exclusive-access
                     NULL, // no security attributes
                     OPEN_EXISTING, // comm devices must use OPEN_EXISTING
                     0,    // not overlapped I/O
                     NULL  // hTemplate must be NULL for comm devices
                     );

  if (hCom == INVALID_HANDLE_VALUE) {
      // Handle the error.
      printf ("CreateFile failed with error %d.\n", GetLastError());
      return (1);
    }

  // We will build on the current configuration, and skip setting the size
  // of the input and output buffers with SetupComm.

  fSuccess = GetCommState(hCom, &dcb);

  if (!fSuccess) {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n", GetLastError());
      return (2);
    }

  // Fill in the DCB: baud=57,600 bps, 8 data bits, no parity, and 1 stop bit.

  dcb.BaudRate = CBR_57600;     // set the baud rate
  dcb.ByteSize = 8;             // data size, xmit, and rcv
  dcb.Parity = NOPARITY;        // no parity bit
  dcb.StopBits = ONESTOPBIT;    // one stop bit

  fSuccess = SetCommState(hCom, &dcb);

  if (!fSuccess) {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n", GetLastError());
      return (3);
    }

  printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
  return (0);
}

In het voorbeeld wordt de serieele poort geopend en geconfigureerd. Hierna kan je er met ReadFile() en WriteFile() naar lezen en schrijven.

De parallele poort is een heel ander verhaal. Hier moet je gebruik maken van een driver, bijvoorbeeld portio.dll.

Jeroen Koeter,

Heel tof van je dat je de moeite hebt genomen een stukje code voor me te checken, maar heb toch nog een klein vraagje.

Stel ik heb een Dlgboxje gemaakt met daarin een Edit-veld waarin ik kan typen. Als ik in dat Edit-veld typ dan verschijnt er op de LC-display dat aan m'n microcontroller hangt de getypte letters. Hoe kan ik dan in VC++ 't Edit-veld koppelen aan de functie van WriteFile()?

Ik ben nog niet zo goed in VC++, want soms zie ik door de bomen het bos niet. Normaal koppel je bijv. een button aan een functie die weer van een klasse is dat zich in de Library bevindt (als ik het goed begrijp). Hoe kan ik de een instantie van een serialportklasse maken (om parameters in te stellen) en functie aanroepen om bijv. data te versturen?

Geloof me, ik heb een tijdje geleden daarover informatie gezocht op het net en dat was zo moeilijk, tot ik hier terecht kwam. Ik word hier goed geholpen, alleen zijn er sommige zaken die weinig jongens kennen (niet beledigend bedoeld ;)).

Ik hoop dat jullie me verder kunnen helpen en Jeroen errrrug bedankt!

Op 6 november 2003 22:08:32 schreef Nordin:
Stel ik heb een Dlgboxje gemaakt met daarin een Edit-veld waarin ik kan typen. Als ik in dat Edit-veld typ dan verschijnt er op de LC-display dat aan m'n microcontroller hangt de getypte letters. Hoe kan ik dan in VC++ 't Edit-veld koppelen aan de functie van WriteFile()?

In een programma kan je event-funkties hangen aan bepaalde events van een Edit-control. Hier kan je bijvoorbeeld aan een WM_CHAR message (die gegenereerd wordt zodra er een karakter in de Edit-control komt) een funktie hangen die het karakter naar de serieele poort stuurt. Kijk maar eens in de class-wizzard.

Succes, Jeroen.

Ok bedankt Jeroen,

Ik zal checken of ik die kan vinden in de ClassWizzard. Mochten anderen daar ook nog iets van weten, dan kom maar met jullie reacties, want hoe meer info hoe beter thanx you all!

Hi Jeroen,

Dat stukje code die je hebt gepost moet ik eigenlijk bij de initialisatie voegen toch? Want als ik het goed begrijp, zodra ik het programma start moet ie gelijk ingesteld worden op com2 en instelling zoals 9600 Baud (voor microcontrollers), dat is wat ik wil.

Zijn dat nou standaard codes die je uit bepaalde documenten kan halen, of hoort een programmeur dat uit het hoofd te kennen (wat me nogal sterk lijkt)?

Stel dat ik bijvoorbeeld de functie readfile() gebruik, hoe krijg ik dan de ASCII code weergegeven? Want ik moet toch wel de data aan een variabele toekennen om die vervolgens weer te geven (bijv. in Static- of Editveldje). Als dat te veel is om uit te leggen, zou ik anders graag dat MSDN-pagina willen weten waar die codes staan. Ik heb namelijk me suf gezocht, maar kan geen serial port documentatie vinden, ik krijg enkel wat info daarover in Visual CE.

Bedankt!

Op 12 november 2003 11:25:22 schreef Nordin:
Dat stukje code die je hebt gepost moet ik eigenlijk bij de initialisatie voegen toch? Want als ik het goed begrijp, zodra ik het programma start moet ie gelijk ingesteld worden op com2 en instelling zoals 9600 Baud (voor microcontrollers), dat is wat ik wil.

Je kan de code eigenlijk overal zetten waar je wilt, als het maar uitgevoerd wordt voordat je de serieele poort nodig hebt. In het algemeen komt het er inderdaad op neer dat je het in je initialisatie routine plaatst.

Zijn dat nou standaard codes die je uit bepaalde documenten kan halen, of hoort een programmeur dat uit het hoofd te kennen (wat me nogal sterk lijkt)?

Welke codes bedoel je? Het stukje code wat ik eerder gepost heb is redelijk standaard, en na een tijdje zal je dat soort dingen dan ook uit je hoofd weten. Dat hoeft natuurlijk niet, maar het maakt het leven van een programmeur wel een stuk gemakkelijker (en sneller). Overigens komt die code uit de MSDN. En ook hiervoor geldt dat het wel makkelijk is dat je ongeveer weet waar je naar moet zoeken. Zelf zocht ik even op CBR_9600, omdat ik weet dat dat een standaard communicatie-snelheid is, en die me wel (in de buurt van) de juiste pagina brengt.

Stel dat ik bijvoorbeeld de functie readfile() gebruik, hoe krijg ik dan de ASCII code weergegeven? Want ik moet toch wel de data aan een variabele toekennen om die vervolgens weer te geven (bijv. in Static- of Editveldje).

Als je ReadFile() opzoelkt in de MSDN zie je dat dat het volgende prototype heeft:

BOOL ReadFile(
  HANDLE hFile,                // handle to file
  LPVOID lpBuffer,             // data buffer
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // number of bytes read
  LPOVERLAPPED lpOverlapped    // overlapped buffer
);

1 byte lezen gaat dan als volgt:

BOOL bResult;
unsigned char myByte;
DWORD bytesRead;

bResult = ReadFile(hCom, myByte, 1, &bytesRead, NULL);
if (bResult)
{
    // Alles OK
} else {
    // Fout opgetreden
}

Hier is hFile de handle die je hebt gekregen bij het openen van de compoort, lpBuffer het adres van de variabele waar je de data wilt hebben, nNumberOfBytesToRead spreekt voor zich, lpNumberOfBytesRead is het adres van een variabele waarin het werkelijk aantal gelezen bytes komt en lpOverlapped kan je NULL maken.

Als dat te veel is om uit te leggen, zou ik anders graag dat MSDN-pagina willen weten waar die codes staan. Ik heb namelijk me suf gezocht, maar kan geen serial port documentatie vinden, ik krijg enkel wat info daarover in Visual CE.

Al deze informatie kan je vinden in de MSDN. Overigens vind ik het niet erg mensen dingen uit te leggen hoor. Meestal is mijn stelling: zolang de moderators het goed vinden ga ik door. En anders kan je me altijd nog direct mailen.

Jeroen.

Jeroen, je bent echt hartstikke top!
Ik vind het echt super dat je de tijd neemt om me wat over VC++ uit te leggen. En als je het niet erg vindt, zal ik je nog een tijdje lastig vallen in de toekomst met vragen stellen.

Tot gauw ;)

Beste Jeroen,

Ik heb m'n VC++ boek geraadpleegd, maar zoals zoveel andere VC++ boeken, staat er niet alles wat je nodig hebt.
Dus heb ik een aantal vragen voor je als je me kunt helpen.

1) Wat houdt de klasse DCB precies in?
Ik weet dat DCB afkorting is van Device Control Block, maar voor de rest wordt ook niet echt duidelijk aangegeven.

2) Wat is HANDLE precies?
Is het een klasse of een datatype?
Want na HANDLE hCom; krijg je vervolgens de code:
hCom = CreateFile(), dan is hCom toch geen instantie van de "klasse" HANDLE. En wat voor returnwaarde kan zo een functie als CreateFile hebben?

3)Bij fSuccess = GetCommState(hCom, &dcb); moet dcb een ampersand & ervoor hebben, omdat het een instantie van een klasse of een object betreft? Ik weet uit theorie van C++ dat & het geheugenadres is van een variabele en * de inhoud van een geheugenadres.

4)Deze code kun je toch niet toepassen als je DialogBox-applicatie gaat maken?
printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
Printf gebruik je toch bij een console-applicatie en niet bij MFCAppWizard(.exe) toch? Ik zou dus daarvoor in de plaats een MessageBox moeten zetten.

5)Ik zie een aantal codes in hoofdletters:

BOOL ReadFile(  HANDLE hFile, // handle to file
LPVOID lpBuffer,    // data buffer
DWORD nNumberOfBytesToRead,  // number of bytes to read
LPDWORD lpNumberOfBytesRead, // number of bytes read
LPOVERLAPPED lpOverlapped    // overlapped buffer);

LPVOID, DWORD, LPDWORD...enz. wat zijn dat voor benamingen. Zoals jij hebt aangegeven zou LPVOID unsigned char moeten zijn, hoe zit dat nou?

Dat zijn een hoop vragen, maar in ieder geval erg bedankt als je me helpt!

1) Wat houdt de klasse DCB precies in?
Ik weet dat DCB afkorting is van Device Control Block, maar voor de rest wordt ook niet echt duidelijk aangegeven.

Een DCB is geen klasse maar een structuur (struct) waarin je de eigenschappen van een serieele poort kan ovragen en opgeven.

2) Wat is HANDLE precies?
Is het een klasse of een datatype?
Want na HANDLE hCom; krijg je vervolgens de code:
hCom = CreateFile(), dan is hCom toch geen instantie van de "klasse" HANDLE. En wat voor returnwaarde kan zo een functie als CreateFile hebben?

Een HANDLE is een datatype (kijk maar eens in windows.h). Eigenlijk is het een pointer naar een stukje geheugen. Handles worden binnen Windows vaak gebruikt als een pointer naar een of ander object.

3)Bij fSuccess = GetCommState(hCom, &dcb); moet dcb een ampersand & ervoor hebben, omdat het een instantie van een klasse of een object betreft? Ik weet uit theorie van C++ dat & het geheugenadres is van een variabele en * de inhoud van een geheugenadres.

Omdat je de CommState wilt ophalen, en Windows deze ergens in moet zetten, geef je het adres van de dcb-variabele mee als argument. Het heeft hier dus niks met class-es of references te maken.

4)Deze code kun je toch niet toepassen als je DialogBox-applicatie gaat maken?
printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
Printf gebruik je toch bij een console-applicatie en niet bij MFCAppWizard(.exe) toch? Ik zou dus daarvoor in de plaats een MessageBox moeten zetten.

Deze code kan je ook gebruiken bij dialog-applicaties. Hier moet je geen printf() gebruiken, maar sprintf(). Deze print naar een string inplaats van naar de console. Kijk voor de details over de sprintf() maar in de MSDN. Een Messagebox() kan natuurlijk ook.

5)Ik zie een aantal codes in hoofdletters:

BOOL ReadFile(  HANDLE hFile, // handle to file
LPVOID lpBuffer,    // data buffer
DWORD nNumberOfBytesToRead,  // number of bytes to read
LPDWORD lpNumberOfBytesRead, // number of bytes read
LPOVERLAPPED lpOverlapped    // overlapped buffer);

LPVOID, DWORD, LPDWORD...enz. wat zijn dat voor benamingen. Zoals jij hebt aangegeven zou LPVOID unsigned char moeten zijn, hoe zit dat nou?

Die datatypen in hoofdletters zijn #typedefs die in windows.h staan. Types die beginnen met LP zijn adressen (Long Pointer). LPVOID staat voor void *. Een pointer naar een void. Dit wordt gedaan omdat je een void naar elk willkeurig type can 'casten'. Ik cast het dan ook naar een unsigned char *. Overigens kan je al die typen ook in de MSDN opzoeken.

Ik hoop dat je er wat verder mee komt. Ik wil anders wel een keer naar je code kijken maar die moet je me dan maar even mailen (zie profiel).

Jeroen.

Bedankt Jeroen,

Ik heb op MSDN gezocht, maar dat is echt moeilijk zoeken. Ik krijg het in ieder geval niet voor elkaar, maar ik heb heel gelukkig wel een hele goeie site gevonden, namelijk functionx.com Ik probeer zoveel mogelijk tijd in te steken om de basisdingen grondig te bestuderen. Bij de meeste VC++ boeken staan niks over die afkortingen, alleen maar hoe je een dialoogbox creëert, hoe je buttons enz. kan plaatsen en die vervolgens zelfgemaakte codes kan toevoegen. In ieder geval, vaak informatie dat niet zo relevant is voor mij.

Maar bij functionx.com staat er bij de link Win32 veel basisinfo waarbij ik dan een goede basis heb en niet voor een raadsel sta wat bepaalde codes betekenen. Uiteraard zal ik niet zoveel over weten, maar ik denk genoeg om mee verder te gaan.

Ik zal zelf een stukje code maken voor seriele communicatie (zoals je me eerder hebt uitgelegd) en dan zal ik die naar je mailen. Ik wil 't gebruiken om m'n microcontroller aan te sturen die vervolgens een bepaalde handeling verricht. Ik zal als eerst heel simpel beginnen met aan en uit schakelen van een Led. Vervolgens wil ik analoge waardes van een sensor aflezen en daarna iets doen met camera op een robot ;)

Ik zou graag ook wat willen vragen aan je over UML in VC++.
Ik vind 't belangrijk om een duidelijk overzicht te kunnen krijgen wat ik precies heb gedaan. Maar dat is als je tijd voor hebt.

Tot mailens ;)

Zeg Jeroen,

Ik heb nog 1 vraagje voor ik ga beginnen met het maken van m'n programma. Met mijn microcontroller kan ik alleen asynchroon communiceren. Ik weet dat bij de pc allebei kan (synchroon en asynchroon), maar je moet toch kiezen, hoe geef je dat aan? Met Overlapped en NotOverlapped?

Dat overlapped of non-overlapped heeft daar niets mee te maken. Als je overlapped wilt gebruiken (is meer programmeerwerk en moeilijker) zou ik nog wel even in de MSDN kijken. Daar staan wat voorbeeldjes in.

Het eenvoudigste is om toch maar even synchroon te beginnen. Meeste programma's die met microcontrollers communiceren doen dat ook synchroon. Wat voor controller heb je? En draait daar een bekende monitor in?

Het gaat om de 68HC11 microcontroller, die heeft een synchrone en een asynchrone communicatie. Voor de synchrone communicatie is meer bedoeld voor communiceren van IC's onderling, waarbij je de I2C-protocol kunt toepassen. De asynchrone communicatie is voor de RS232. Want je kunt bijv. de RS232 verbinden met een modem, dan gebeurt dat asynchroon, want je kunt niet met de modem op afstand dezelfde klokfrequentie gebruiken als op de pc voor de RS232, vandaar asynchroon.

Wat betreft Overlap en Nonoverlap:


Serial Communications in Win32
Allen Denver
Microsoft Windows Developer Support
December 11, 1995
Applies to:
   Microsoft® Win32®
   Microsoft Windows®

Reading and Writing
Reading from and writing to communications ports in Win32
is very similar to file input/output (I/O) in Win32.
In fact, the functions that accomplish file I/O are the
same functions used for serial I/O. I/O in Win32 can be
done either of two ways: overlapped or nonoverlapped.
The Platform SDK documentation uses the terms asynchronous
and synchronous to connote these types of I/O operations.
This article, however, uses the terms overlapped and
nonoverlapped.
Nonoverlapped I/O is familiar to most developers because
this is the traditional form of I/O, where an operation is
requested and is assumed to be complete when the function
returns. In the case of overlapped I/O, the system may
return to the caller immediately even when an operation is
not finished and will signal the caller when the operation
completes. The program may use the time between the I/O
request and its completion to perform some "background"
work.

Reading and writing in Win32 is significantly different
from reading and writing serial communications ports in 16-
it Windows. 16-bit Windows only has the ReadComm and
WriteComm functions. Win32 reading and writing can involve
many more functions and choices. These issues are
discussed below.

Met de 68HC11 uC kan ik met een programma broncode naar de interne eeprom van de 68HC11 downloaden via de SERIELE poort. En dit gebeurt echt asynchroon!

Hoi,
Het synchroon/asynchroon van de Windows API heeft hier niets te maken met de synchrone/asynchrone communicatie van de HC11 die jij bedoelt.

Als je in Windows asynchroon gaat communiceren (overlapped) kan je funkties aanroepen (zoals WriteFile()) die dan meteen terugkeren. Op dat moment hoeft dus alle communicatie niet gedaan te zijn. Om te weten wanneer alle communicatie klaar is installeer je een completion routine. Dit is een funktie die aangeroepen wordt zodra Windows klaar is met het versturen van al je data.

Om alles eenvoudig te houden zou ik beginnen met alles (in Windows) synchroon te doen. Dus de non-overlapped aanroepen.

Jeroen

Ok Jeroen,

ik zal doen zoals jij het zegt, trouwens ik heb het al bijna af, maar wachtte eigenlijk op een respons van je.

Ik vond het eerlijk gezegd ook een beetje vreemd wat betreft 't verhaal over synchroon/asynchroon, aangezien de hardware van zo een seriële port bestaat uit een UART (tenminste op mijn pc wel) waarbij de afkorting UniversalAsynchroneReceiver TRansmitter is, dus het is zowiezo asynchroon. Ik zal het programmaatje naar je toe versturen en hopen maar dat je niks fouts vindt ;)