Knowledge Base Nr: 00010 SetGetLineStatusRS232.cpp - http://www.swe-kaiser.de

Downloads:

linux: rs232 steuerleitungen abfragen und setzen.

  
//benutzt um 24V signal von einer SPS über spannungsteiler unter linux einzulesen.
//zustand der CD (carrier detect) leitung an der rs232 abfragen und DTR/RTS setzen löschen.
//root rechte müssen vorhanden sein. der zugriff von verscheiedenen prozessen aus ist möglich
//da kein filehandle o.ä. benötigt wird.
//die tastatur wird nicht-blockierend abgefragt.
//beschaltung: spannungsteiler je 3kOhm; ende an pin5 (GND) und mitte an pin1 (CD) (DSub9)
// an freiem ende 24V signal.
//anzeigen des status unter linux: cat /proc/tty/driver/serial | less

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#include <fcntl.h>

#include <curses.h>

const int IOBASE = 0x2f8;
const unsigned char CD = 0x80;
const unsigned char DTR = 0x01;
const unsigned char RTS = 0x02;

int main(int argc, char *argv[])
{
initscr();
cbreak();

printf("get rs232 line status (press 0/1 to toggle RTS) ...\r\n");

int nErr = ioperm(IOBASE, 8, 1);
printf("ioperm(0x%04X): %d\r\n", IOBASE, nErr);

fcntl(fileno(stdin), F_SETFL, fcntl(fileno(stdin), F_GETFL) | O_NONBLOCK);

while(1)
{
//tastendruck einlesen und io setzen
char c = 0;
int r = fread(&c, 1, 1, stdin);

if (r>0)
{
int nDoSet = 0;

switch (c)
{
case '0':
nDoSet = 0;
break;
case '1':
nDoSet = 1;
break;
default:
printf("????\r\n");
continue;
}

unsigned char ucOut = inb(IOBASE+4);
if (nDoSet)
ucOut |= RTS;
else
ucOut &= ~RTS;

printf("\r\n***cmd::set line to %d %02X\r\n", nDoSet, ucOut); fflush(stdout);
outb(ucOut, IOBASE+4); //f.e. 0x2fc
printf("\r\n***after cmd::set line to %d %02X\r\n", nDoSet, ucOut); fflush(stdout);
}

volatile unsigned char ucStatus = inb(IOBASE+6); //f.e. 0x2fe
printf("cd status: cd=%s\r\n", (ucStatus & CD) ? "on" : "off");

fflush(stdout);
usleep(1000 * 1000); //200ms
}

return EXIT_SUCCESS;
}