Het gebruik van de seriële poort op een Windows PC.

© Harry Broeders.

Deze pagina is bestemd voor studenten van de Haagse Hogeschool - TH Rijswijk/Academie voor Engineering.

Introductie.

Een goede introductie over het programmeren van de seriële poort kun je vinden op: http://www.robbayer.com/files//serial-win.pdf. Dit is voldoende voor PROS2.

Voorbeeldprogramma.

Het onderstaande Windows programma winserial.c verstuurt een 'S' via de seriële poort COM1 9600-7-E-1 en zet daarna alle binnenkomende karakters op het scherm totdat een 'Q' wordt ontvangen.

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

HANDLE InitCom1() {
    DCB dcb;
    HANDLE hCom;
    BOOL fSuccess;
    hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hCom == INVALID_HANDLE_VALUE) {
        MessageBox(0, "Fout: De seriële poort kan niet geopend worden!", "Fout", MB_OK|MB_ICONEXCLAMATION);
        exit(-1);
    }
    fSuccess = GetCommState(hCom, &dcb);
    if (!fSuccess) {
        MessageBox(0, "Fout: De instellingen van de seriële poort kunnen niet gelezen worden!", "Fout", MB_OK|MB_ICONEXCLAMATION);
        exit(-1);
    }
    dcb.fParity = TRUE;
    dcb.BaudRate = CBR_9600;
    dcb.ByteSize = 7;
    dcb.Parity = EVENPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity = FALSE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    fSuccess = SetCommState(hCom, &dcb);
    if (!fSuccess) {
        MessageBox(0, "Fout: De instellingen van de seriële poort kunnen niet aangepast worden!", "Fout", MB_OK|MB_ICONEXCLAMATION);
        exit(-1);
    }
    return hCom;
}

char ReadCom1(HANDLE hCom) {
    char inBuffer[2]=" ";
    unsigned long nBytesRead;
    ReadFile(hCom, &inBuffer, 1, &nBytesRead, NULL);
    if (nBytesRead!=1) {
        MessageBox(0, "Fout: De seriële poort kan niet uitgelezen worden!", "Fout", MB_OK|MB_ICONEXCLAMATION);
        exit(-1);
    }
    return inBuffer[0];
}

void WriteCom1(HANDLE hCom, char c) {
    char outBuffer[2]=" ";
    unsigned long nBytesWritten;
    outBuffer[0]=c;
    WriteFile(hCom, &outBuffer, 1, &nBytesWritten, NULL);
    if (nBytesWritten!=1) {
        MessageBox(0, "Fout: De seriële poort kan niet beschreven worden!", "Fout", MB_OK|MB_ICONEXCLAMATION);
        exit(-1);
    }
}

int main() {
    HANDLE hCom;
    char in;

    hCom = InitCom1();
    printf("Er wordt nu een S verstuurd.\n");
    WriteCom1(hCom, 'S');
    printf("Ontvangen karakters worden op het scherm gezet totdat een Q wordt ontvangen.\n");
    do {
        in = ReadCom1(hCom);
        if (in!='Q') {
            putchar(in);
        }
    } while (in!='Q');
    printf("\nEINDE.\n");
    getchar();
    return 0;
}

Het onderstaande ATmega16 programma avrserial.c wacht tot er een 'S' binnekomt via de seriële poort 9600-7-E-1 en verstuurt daarna de tekst "HalloQ" via de seriële poort.

#include <avr/io.h>

int main() {
    char c;
    // 9600-7-E-1
    UCSRA=0x00;
    UCSRB=0x18;
    UCSRC=0xA4;
    UBRRH=0;
    UBRRL=23;
    while(1) {
        while (~UCSRA & 1<<RXC);
        if (UCSRA & (1<<FE|1<<DOR|1<<PE)) {
            c=UDR;
            while (~UCSRA & 1<<UDRE);
            UDR='?';
        }
        else {
            c=UDR;
            if (c=='S') {
                char s[]="HalloQ";
                int i;
                for (i=0; s[i]!='\0'; i++) {
                    while (~UCSRA & 1<<UDRE);
                    UDR=s[i];
                }
            }
        }
    }
    return 0;
}

Als de "SPARE" seriële poort van het STK500 practicumbord verbonden wordt met COM1 van de PC dan geeft het windowsprogramma de volgende uitvoer:

Als de COM1 poort bezet is (door een ander programma) verschijnt de volgende foutmelding:

Details.

Alle details kun je vinden op de MSDN site (Microsoft Developers Network).