PROGRAMACION PUERTO SERIE EN C

Al igual que python podemos usar un control del puerto serie mediante el envio y recepcion de bytes y tambien control individual de cada una de sus patitas.

Para poder compilar estos programas deberemos  tener instalado el compilador en C   gcc que cada uno podra instalar desde su distribucion de Linux que este usando.

Para Puppy bastara con tener instalado el paquete devx_xxxx.sfs correspondiente a version de Puppy que este utilizando.

Primero vamos a ver un porgrama en el que podemos ver el control de las patitas de salida DTR y RTS mediante el programa que viene a continuacion:

Decir que siguiente codio lo adapte de la pagina web:

http://www.embeddedlinux.org.cn/EmbLinux/ch06lev1sec2.htm

Para el manejo de este programa hacemos uso de la estructura termios.

Para compilar este programa deberemos copiar el siguiente codigo en un archivo  y llamarlo  controlbits

y luego compilarlo mediante:

gcc -o controlbits controlbits.c

 

/*archivo controlbits.c

Para compilara el programa
gcc -o controlbits controlbits.c
*/

#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>

struct termios tio;

int main(int argc, char *argv[])
{
int fd;
int status;

if (argc != 4)
   {

   printf(“Para ejecutar el programa  controlbits /dev/ttyS0 \n”);

   printf(“Para ejecutar el programa  controlbits /dev/ttyUSB0 \n”);
  return 1 ;
   }

if ((fd = open(argv[1],O_RDWR)) < 0)
   {
    printf(“No se puede abri el perto \n”,argv[1]);
   return 1;
   }
tcgetattr(fd, &tio);                           /*Consigue informacion del puerto*/
tio.c_cflag &= ~HUPCL;                /* Resetea el bit HUPCL */
tcsetattr(fd, TCSANOW, &tio);  /* set the termio information */

ioctl(fd, TIOCMGET, &status); /* Consigue el status del puerto serie */

if ( argv[2][0] == ‘1’ )      /* Pon a uno la linea  DTR  */
           status &= ~TIOCM_DTR;
      else
          status |= TIOCM_DTR; /* Si no a cero  */

if ( argv[3][0] == ‘1’ )      /* pon a uno la linea RTS */
          status &= ~TIOCM_RTS;
     else
          status |= TIOCM_RTS;  /* Si no a cero  */

ioctl(fd, TIOCMSET, &status); /* Varia al nuevo status las lineas del puerto serie */

close(fd);                    /* Cierra el puerto serie */
}

 

Bueno una vez  ya tenemos el archivo copiado y copilado vemos que nos aparece un fichero ejecutable que es controlbits.

Bueno vamos a tener en cuenta las siguiente imagen antes de ejecutar nada.

pines

En esta diagrama de pines de salida del puerto serie vemos que las lineas DTR y RTS corresponden a las lineas 4 y 7 respectivamente del puerto serie.

Asi que al igual que lo que haciamos en la programacion en python podemos coger un conector hembra DB9 al que tengamos acceso a los pines donde se sueldan los cables, conectaremos este conector al conector de salida del puerto serie del ordenador o en mi caso a un cable convertidor de USB-RS232, con las conexiones accesible de soldar por el otro lado.

Bueno ponemos con un polimetro midiendo tension en escala de 20 V en continua, la punta de masa a la masa del conector hembra o pin 5 de Signal Ground. y la otra punta positiva al pin 4 de DTR.

 

Y ejecutaremos desde el terminal el programa de la siguiente forma:

# controlbits /dev/ttyUSB0 0 0

Veremos que si los las tensiones del los pines para valores negativos oscilan entre  -3 y -15 voltios que corresponderia al valor True o alto y para tensiones positivas entre +3 y +15 voltios que corresponden al valor bajo o False.

En la anterior orden como le hemos dado la orden se ponga a cero o False la tension en el pin 4 de DTR estara en valor positivo osea entre +3 y +15 voltios, y lo mismo para el pin 7 o RTS.

Si ahora volvemos a ejecutar la orden:

# controlbits /dev/ttyUSB0 1 1

Veremos que la tension en ambas patas 4 y 7 basculan a tensiones negativas. y asi podemos hacer un control de las dos o individualmente  altenando los valors 0 0 , 0 1 ,  1 0 , 1 1.

Bueno al igual que la programacion en python , alguien podria estar preguntandose ahora para que programar las lineas individuales del puerto serie y la contestacion es la misma, bueno pues se pueden hacer circuitos muy interesantes y sencillos a niveles de pines, sin necesidad de utilizar el famoso max232, y ningun microcontrolador posterior.

Aunque si efectivamente se tiene mucho mas control y mucha mas versatilidad utilizando el puerto serie con un microcontrolador.

No obstante ahora mas adelante vamos a ver como enviar y recibir datos enteros o bytes atraves del puerto serie.

Pero por ejemplo utilizando de esta forma y mediante registros de desplazamiento podriamos crear buffer de datos  a transmitir o recibir por el puerto serie del tamaño que queramos,  8, 16 o mas bits.

Sin necesidad de crear una circuiteria muy compleja.

Yo tenia un articulo antiguo que mediante este metodo hacia contadores, capacimetro etc… si bien era mediante Visual Basic de Windows.

Hacer notar que yo utilizo un cable  USB convertidor de USB a RS232, aunque el ordenador que trabajo tiene puerto serie hoy en dia los ordenadores modernos ya no lo traen, con lo cual es necesario disponer de un cable de esto que por otro lado son muy baratos.

Si nos metemos en el directorio  /dev  veremos que nada mas conectar el cable  USB-RS232 al ordenador se nos aparece un archivo  ttyUSB0  y este archivo corresponde a este dispositivo, recordar que Linux utiliza todo como si fueran archivos.

Si conectaramos otro cable USB-RS232  nos apareceria otro archivo ttyUSB1 y asi sucesivamente.

Decir que los puertos serie de los ordenadores antiguos corresponden a los archivos  ttyS0 , ttyS1 , ttyS0  , o lo que corresponderia en windows los puertos Com0, Com1, Com2 etc..

Vamos a ver a hora la forma de leer los pines de entrada con el siguiente programa, que fue sacado del enlace que se muestra arriba:
/*
 Para compilarlo
gcc -o leer leer.c
 */

#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#define DSR ‘D’+’S’+’R’
#define CTS ‘C’+’T’+’S’
#define DCD ‘D’+’C’+’D’
#define RI  ‘R’+’I’

int main(int argc, char *argv[])
{
  int fd;
  int status;
  unsigned int whichSignal;

  if (argc != 3)
    {

   printf(“Para ejecutar el programa  lee /dev/ttyS0 DSR  ò CTS ó DCD ò RI  \n”);

   printf(“Para ejecutar el programa  lee /dev/ttyUSB0  DSR  ò CTS ó DCD ò RI  \n”);

    return 1;
    }

/* Abre el puerto serie */
  if ((fd = open(argv[1],O_RDONLY)) < 0) {
    printf(“No puedo abrir el puerto  %s\n”,argv[1]);
    return 1;
  }

/* Consigue el estado del puerto */
  ioctl(fd, TIOCMGET, &status);

  whichSignal = argv[2][0]  + argv[2][1] +  argv[2][2];
 
  status &= ~TIOCM_DTR;         /* Estas dos lineas hacen que la linea DTR se ponga a 1   */
  ioctl(fd, TIOCMSET, &status);    /* Esto es que haya una tension negativa.   */

  switch (whichSignal) {
    case  DSR:
      status&TIOCM_DSR ? printf(“0”):printf(“1”);
      break;
    case  CTS:
      status&TIOCM_CTS ? printf(“0”):printf(“1”);
      break;
    case  DCD:
      status&TIOCM_CAR ? printf(“0”):printf(“1”);
      break;
    case  RI:
      status&TIOCM_RNG ? printf(“0”):printf(“1”);
      break;
    default:
      printf(“valor  %s desconocido, utilice DSR, CTS, DCD o RI”,argv[2]);
      break;
  }
  printf(“\n”);

/* Cierra el puerto */
  close(fd);
}

Una vez copiado este programa en un archivo de texteo y llamado  lee.c lo compilaremos mediante

# gcc -o lee lee.c

Antes de ello la que haremos en en nuestro conector hembra lo sacararemos del puerto serie y soldaremos un cablecito entre el pin DTR y pin DSR, el pin DTR es salida y lo hemos puesto a uno o valor negativo de tension y el pint DSR es entrada.

Bueno si ahora ejecutamos desde el terminal el programa

# lee /dev/tttyUSB0 DSR

Veremos que nos da una entrada de DSR un valor  TRue o  “1”

Si variamos la la linea del codigo de programa y en ve de la linea    status &= ~TIOCM_DTR;     ponemos la linea:

status |= TIOCM_DTR;

Esto hace que la linea DTR se ponga a cero valor negativo de tension, salvamos el programa y lo volvemos a compilar:

# gcc -o lee lee.c

Volvemos a ejecutar el programa:

# lee /dev/tttyUSB0 DSR

Bueno ahora podemos ver que nos da una entrada de DSR un valor  False o  “0”

En la proxima entrega veremos como mandar y enviar bytes por el puerto serie.

 

Bueno esto es todo hasta ahora continuare:

 

 

 

 

 

 

 

 

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s