rs232 port

Planering och tankar kring eventuella framtida projekt.
toli91
Inlägg: 140
Blev medlem: 27 januari 2006, 12:56:57

rs232 port

Inlägg av toli91 »

hej alla som läser det här

jag undrar hur man gör för att styra rs232 porten för vad jag har fattat så är den inte lika lätt att kommaåt som lpt porten då är det ju bara skicka datan till addresen och så är det det som kommer ut i lpt.

så då undrar jag om det är så att man måste göra någon sorts "setup" innan man kan börja läsa in data och kunna skicka out data??

programmet ska vara för windows xp och sak skrivas i C.

tack på förhand //Tobbe
Användarvisningsbild
Stinrew
Inlägg: 954
Blev medlem: 20 augusti 2006, 03:14:41
Ort: Motala
Kontakt:

Inlägg av Stinrew »

Vad är det för typ av data som du vill sända till/via serieporten??

Normalt sett så ställer man in dataformat, paritetsbit, stoppbitar och baudrate och skickar seriella dataflöden över en tråd.
macgyver
Inlägg: 321
Blev medlem: 8 juni 2005, 00:24:09
Ort: Göteborg
Kontakt:

Inlägg av macgyver »

Ja man får använda WinAPI, jag har kod i c++ som löser det om du vill ha, den bör vara enkel att porta till c
toli91
Inlägg: 140
Blev medlem: 27 januari 2006, 12:56:57

Inlägg av toli91 »

ja tack jag tar gärna imot den
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det är extremt enkelt att komma åt en serieport: man öppnar helt enkelt den befintliga filen "COM1" (eller 2, 3, 4 eller vilken port som helst). Det är avsevärd enklare än parallellporten, speciellt under XP.

Jag gör såhär för att kolla vilka portar som finns (BCB6):

Kod: Markera allt

  char Text[20];
  for(Counter = 1;Counter <= 9;Counter++)
    {
    sprintf(Text,"COM%u",Counter);
    Handle = CreateFile(Text,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
    if(Handle != INVALID_HANDLE_VALUE)
      {
      cbbCOMport->Items->Add(Text); // cbbCOMport is a drop-down select list
      PurgeComm(Handle,PURGE_RXABORT);
      CloseHandle(Handle);
      }
    else
      {
      if(GetLastError() == 5) // Is there but used by other application
        {
        cbbCOMport->Items->Add(Text);
        }
      }
    }
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31441
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Inlägg av MadModder »

Precis.

Nu är det iofs inte windows, men i min styrdator i serverskåpet fick jag slut på indatapinnar i parallellporten, så jag använde helt enkelt de i serieportarna också. :)
Finns fyra stycken per port.
Utpinnar man kan styra som de i parallellporten, finns det två av per serieport.
toli91
Inlägg: 140
Blev medlem: 27 januari 2006, 12:56:57

Inlägg av toli91 »

Icecap: Vilka includes behövs för att den ska funka?
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Hurså?

Jag använder förvisso TPApro men de kall jag visade är rena API-kall, cbbCOMport är en ComboBox och Handle är definierat:
HANDLE Handle;

Man kanske måste lägga till "stdio.h" för definitionen av fil-värden.
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Allt finns i Win32-API dokumentationen.
Man kan börja att läsa på många ställen, men t.ex här :
http://msdn2.microsoft.com/en-us/library/aa363194.aspx
Om du sedan googlar på några av funktionerna så
hittar du säkert flera kompletta kodexempel...

Om det gäller enkel kommunikation så kan de vanliga open/read/write/close
funktionerna fungera. Med API'erna kan man göra lite mer...
Mr M
Inlägg: 165
Blev medlem: 20 januari 2006, 21:35:14

Inlägg av Mr M »

Så här ser den kod ut som jag använder. Har moddat ett C++ exempel från nätet så det går köra i C.

Kod: Markera allt

#include "rs232.h"

int main(int argc, char *argv[])
{
	rs232 com_port;
	unsigned char b;
	
	rs232_open(&com_port, "COM1", 9600, spNONE);
	
	rs232_write_byte(&com_port, 'A');
	
	while(rs232_bytes_waiting(&com_port) < 1)
	{
		;
	}
	
	b = rs232_read_byte(&com_port);
	
	rs232_close(&com_port);
	return 0;
}

Kod: Markera allt

/*
	rs232.h

	Ett samling funktioner för att kunna använda serieporten.

	av Mr M 2005-04-18

*/

#ifndef _rs232_H_
#define _rs232_H_

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

typedef enum { spNONE, spODD, spEVEN } serial_parity;

typedef struct {
	char              port[10];                     
    int               rate;
    serial_parity     parityMode;
    HANDLE            serial_handle;           
} rs232;

int rs232_open( rs232 *o, char *port_arg, int rate_arg, serial_parity parity_arg );
void rs232_close( rs232 *o );
unsigned char rs232_read_byte( rs232 *o );
void rs232_write_byte( rs232 *o, unsigned char b );
int rs232_bytes_waiting( rs232 *o );

#endif

Kod: Markera allt

/* 

	rs232.c

	Ett samling funktioner för att kunna använda serieporten.

	av Mr M 2005-04-18

*/

#include "rs232.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>

int rs232_open( rs232 *o, char *port_arg, int rate_arg, serial_parity parity_arg )
{
	int erreur;
	DCB  dcb;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };

	erreur = 0;

    if ( port_arg != 0 )
    {
        strncpy(o->port, port_arg, 10);
        o->rate      = rate_arg;
        o->parityMode= parity_arg;
        memset( &dcb, 0, sizeof(dcb) );

        dcb.DCBlength	= sizeof( dcb );                   

        dcb.BaudRate	= o->rate;

        switch( o->parityMode )
        {
            case spNONE:
                            dcb.Parity      = NOPARITY;
                            dcb.fParity     = 0;
                            break;
            case spEVEN:
                            dcb.Parity      = EVENPARITY;
                            dcb.fParity     = 1;
                            break;
            case spODD:
                            dcb.Parity      = ODDPARITY;
                            dcb.fParity     = 1;
                            break;
        }


        dcb.StopBits        = ONESTOPBIT;
        dcb.ByteSize        = 8;
        
        dcb.fOutxCtsFlow    = 0;
        dcb.fOutxDsrFlow    = 0;
        dcb.fDtrControl     = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = 0;
        dcb.fRtsControl     = RTS_CONTROL_DISABLE;
        dcb.fOutX           = 0;
        dcb.fInX            = 0;
        
        dcb.fErrorChar      = 0;
        dcb.fBinary         = 1;
        dcb.fNull           = 0;
        dcb.fAbortOnError   = 0;
        dcb.wReserved       = 0;
        dcb.XonLim          = 2;
        dcb.XoffLim         = 4;
        dcb.XonChar         = 0x13;
        dcb.XoffChar        = 0x19;
        dcb.EvtChar         = 0;
        

        o->serial_handle    = CreateFile( o->port, GENERIC_READ | GENERIC_WRITE,
                               0, 0, OPEN_EXISTING, 0, 0 );

        if ( o->serial_handle != INVALID_HANDLE_VALUE )
        {
            if( !SetCommMask( o->serial_handle, 0 ) )
                erreur = 1;

            if( !SetCommTimeouts( o->serial_handle, &cto ) )
                erreur = 2;

            if( !SetCommState( o->serial_handle, &dcb ) )
                erreur = 4;
        }
        else
            erreur = 8;
    }
    else
        erreur = 16;

    if ( erreur != 0 )
    {
        CloseHandle( o->serial_handle );
        o->serial_handle = INVALID_HANDLE_VALUE;
    }
    return( erreur );	
}

void rs232_close( rs232 *o )
{
	if ( o->serial_handle != INVALID_HANDLE_VALUE )
	{
        CloseHandle( o->serial_handle );
	}
    o->serial_handle = INVALID_HANDLE_VALUE;
}

unsigned char rs232_read_byte( rs232 *o )
{
    unsigned long bytes_read;
	unsigned char b;
    bytes_read = 0;
    if ( o->serial_handle != INVALID_HANDLE_VALUE )
    {
        ReadFile( o->serial_handle, &b, 1, &bytes_read, NULL );
    }
    return(b);
}

void rs232_write_byte( rs232 *o, unsigned char b )
{
	unsigned long result;

    if ( o->serial_handle != INVALID_HANDLE_VALUE )
	{
        WriteFile( o->serial_handle, &b, 1, &result, NULL );
	}
}

int rs232_bytes_waiting( rs232 *o)
{
	struct _COMSTAT status;
    int             n;
    unsigned long   etat;

    n = 0;

    if ( o->serial_handle != INVALID_HANDLE_VALUE)
    {
        ClearCommError( o->serial_handle, &etat, &status );
        n = status.cbInQue;
    }

    return( n );
}
Håll till godo :wink:
toli91
Inlägg: 140
Blev medlem: 27 januari 2006, 12:56:57

Inlägg av toli91 »

tack så mycket det funkar nu med kodningen
Skriv svar