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

© Harry Broeders.

Deze pagina is bestemd voor studenten van de Haagse Hogeschool - Academie voor Technology, Innovation & Society Delft.

Introductie.

Een goede introductie over het programmeren van de seriële poort kun je vinden het door Robertson Bayer geschreven document Windows Serial Port Programming . Dit is voldoende voor MICPRG.

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 initCom(int comPortNumber) {
    DCB dcb;
    HANDLE hCom;
    BOOL fSuccess;
    char comPortName[20];
    sprintf(comPortName, "\\\\.\\COM%d", comPortNumber);
    hCom = CreateFileA(comPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hCom == INVALID_HANDLE_VALUE) {
        MessageBoxA(0, "Fout: De seriële poort kan niet geopend worden!", "Fout", MB_OK | MB_ICONEXCLAMATION);
        exit(-1);
    }
    fSuccess = GetCommState(hCom, &dcb);
    if (!fSuccess) {
        MessageBoxA(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) {
        MessageBoxA(0, "Fout: De instellingen van de seriële poort kunnen niet aangepast worden!", "Fout", MB_OK | MB_ICONEXCLAMATION);
        exit(-1);
    }
    return hCom;
}

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

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

void closeCom(HANDLE hCom) {
    CloseHandle(hCom);
}

int main(void) {
    HANDLE hCom;
    char in;
    hCom = initCom(1);
    printf("Er wordt nu een S verstuurd.\n");
    writeCom(hCom, 'S');
    printf("Ontvangen karakters worden op het scherm gezet totdat een Q wordt ontvangen.\n");
    do {
        in = readCom(hCom);
        if (in != 'Q') {
            putchar(in);
        }
    } while (in != 'Q');
    closeCom(hCom);
    printf("\nEINDE.\n");
    getchar();
    return 0;
}

Het onderstaande ATmega32 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(void) {
    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).