Adjunto 'comSerial.cpp'
Descargar 1 /****************************************************************************/
2 /* comSerial.cpp (c++) */
3 /*--------------------------------------------------------------------------*/
4 /* Licencia GPL */
5 /* Libreria para comunicaciones serie. */
6 /****************************************************************************/
7 /* Juan González. Agosto-2002 */
8 /* Marco Alvarez Reyna. Mayo-2007 mail: marcoalrey@gmail.com */
9 /****************************************************************************/
10
11 #include "comSerial.h" /* Archivo de cabecera */
12
13 static char error_serie[10][80]={
14 {"Error al hacer TIOCGSERIAL"}, /* 1 */
15 {"Error al hacer TIOCSSERIAL"}, /* 2 */
16 {"Error al hacer TCGEST"}, /* 3 */
17 {"Error al hacer TCSETSF"}, /* 4 */
18 {"----------------------"}, /* 5 */
19 {"Error en TIOCMSET"}, /* 6 */
20 {"Error en TIOCMSET"}, /* 7 */
21 {"Error en TCGETATTR"}, /* 8 */
22 {"Error en TCFLUSH"}, /* 9 */
23 {"Error en TCSETATTR"}, /* 10 */
24 };
25
26 char *ComSerial::getserial_error()
27 /***************************************************************/
28 /* Devolver la cadena de error del ultimo error producido */
29 /***************************************************************/
30 {
31 if (nerror==0) return NULL;
32 if (nerror==5) return (char *)strerror(errno); /* Error en open */
33 else return (char *)&error_serie[nerror-1]; /* Otro error */
34 }
35
36 int ComSerial::setup_serial()
37 /************************************************************************/
38 /* Configurar la estructura termios para trabajar con el puerto serie. */
39 /* Configurar para 8 bits de datos y sin paridad. */
40 /************************************************************************/
41 {
42 struct termios newtermios;
43
44 /* Leer atributos del puerto */
45 if (tcgetattr(fd,&oldtermios)==-1) {
46 nerror=8;
47 return 0;
48 }
49
50 newtermios.c_cflag= CBAUD | CS8 | CLOCAL | CREAD;
51 newtermios.c_iflag=IGNPAR;
52 newtermios.c_oflag=0;
53 newtermios.c_lflag=0;
54 newtermios.c_cc[VMIN]=1;
55 newtermios.c_cc[VTIME]=0;
56
57 /* Vaciar buffer de entrada */
58 if (tcflush(fd,TCIFLUSH)==-1) {
59 nerror=9;
60 return 0;
61 }
62
63 /* Vaciar buffer de salida */
64 if (tcflush(fd,TCOFLUSH)==-1) {
65 nerror=9;
66 return 0;
67 }
68
69 if (tcsetattr(fd,TCSANOW,&newtermios)==-1) {
70 nerror=10;
71 return 0;
72 }
73 return 1;
74 }
75
76 int ComSerial::baudios(int vel)
77 /*******************************************/
78 /* Configurar la velocidad de transmision */
79 /*******************************************/
80 {
81 speed_t baud;
82 struct termios mytermios;
83
84 /* Leer atributos del puerto */
85 if (tcgetattr(fd,&mytermios)==-1) {
86 nerror=8;
87 return 0;
88 }
89
90 switch(vel) {
91 case 1200 : baud=B1200; break;
92 case 7680 : baud=B38400; break;
93 case 9600 : baud=B9600; break;
94 default : baud=B9600; break;
95 }
96
97 cfsetospeed(&mytermios,baud);
98 cfsetispeed(&mytermios,baud);
99
100 if (tcsetattr(fd,TCSANOW,&mytermios)==-1) {
101 nerror=10;
102 return 0;
103 }
104 return 1;
105 }
106
107 int ComSerial::vaciar_buffer_tx()
108 /**************************************/
109 /* Vaciar el buffer de transmision */
110 /**************************************/
111 {
112 if (tcflush(fd,TCOFLUSH)==-1) {
113 nerror=5;
114 return 0;
115 }
116 return 1;
117 }
118
119 int ComSerial::vaciar_buffer_rx()
120 /**************************************/
121 /* Vaciar el buffer de recepcion */
122 /**************************************/
123 {
124 if (tcflush(fd,TCIFLUSH)==-1) {
125 nerror=5;
126 return 0;
127 }
128 return 1;
129 }
130
131 /***************************************/
132
133 int ComSerial::enviar_break()
134 /*******************************/
135 /* Enviar una senal de BREAK */
136 /*******************************/
137 {
138 if (tcsendbreak(fd,1)==-1) {
139 nerror=5;
140 return 0;
141 }
142 return 1;
143 }
144
145 int ComSerial::enviar_bloque(char *cad, int tam)
146 /********************************************/
147 /* Enviar una cadena por el puerto serie */
148 /********************************************/
149 {
150 if (write(fd,cad,tam)==-1) {
151 nerror=5;
152 return 0;
153 }
154 return 1;
155 }
156
157 int ComSerial::enviar_car(char car)
158 /*******************************************/
159 /* Enviar un caracter por el puerto serie */
160 /*******************************************/
161 {
162 if (write(fd,&car,1)==-1) {
163 nerror=5;
164 return 0;
165 }
166 return 1;
167 }
168
169 int ComSerial::car_waiting()
170 /*********************************************************************/
171 /* Detectar si hay caracteres esperando a ser leidos. Se devuelve */
172 /* 0 si no hay caracteres esperando. En cualquier otro caso se */
173 /* devuelve el numero de caracteres esperando en el buffer de */
174 /* recepcion. */
175 /*********************************************************************/
176 {
177 int n;
178 if (ioctl(fd,TIOCINQ,&n)==0) {
179 return n;
180 }
181 return 0;
182 }
183
184 int ComSerial::bufftx_waiting()
185 /***************************************************************/
186 /* Detectar si hay caracteres pendientes de ser enviados. La */
187 /* Funcion devuelve el numero de caracteres pendientes de */
188 /* transmision. Devuelve 0 si se han enviado todos los datos */
189 /***************************************************************/
190 {
191 int n;
192 if (ioctl(fd,TIOCOUTQ,&n)==0) {
193 return n;
194 }
195 return 0;
196 }
197
198 char ComSerial::leer_car()
199 /******************************************************************/
200 /* Leer un caracter del buffer de recepcion. Si no hay ninguno */
201 /* se espera hasta que venga */
202 /******************************************************************/
203 {
204 char c;
205
206 while (!car_waiting());
207 read(fd,&c,1);
208 return c;
209 }
210
211 char ComSerial::leer_car_plazo(int plazo, int *timeout)
212 /***********************************************************************/
213 /* Leer un caracter del buffer de recepcion. Si el caracter no se ha */
214 /* recibido dentro del plazo establecido se devuelve un valor disinto */
215 /* de cero en timeout. En caso de llegar un caracter dentro del plazo */
216 /* indicado se devuelve el caracter y se devuelve 0 en timeout */
217 /* */
218 /* El plazo de tiempo esta especificado en microsegundos */
219 /***********************************************************************/
220 {
221 fd_set leer;
222 struct timeval tout;
223 int n;
224 char c;
225
226 tout.tv_sec=0;
227 tout.tv_usec=plazo;
228
229 FD_ZERO(&leer);
230 FD_SET(fd,&leer);
231
232 n=select(fd+2,&leer,NULL,NULL,&tout);
233 if (n==0) {
234 *timeout=1;
235 return 0;
236 }
237 *timeout=0;
238 read(fd,&c,1);
239 return c;
240 }
241
242 int ComSerial::wait_break(int plazo)
243 /***********************************************************************/
244 /* Esperar la senal de break durante el plazo especificado. El plazo */
245 /* tiene unidades de microsegundos. La funcion devuelve: */
246 /* 0 Timeout */
247 /* 1 Ha llegado la senal de break */
248 /***********************************************************************/
249 {
250 char c;
251 int timeout;
252
253 c=leer_car_plazo(plazo,&timeout);
254 if (timeout) return 0;
255 if (c!=0) return 0;
256 else return 1;
257 }
258
259 int ComSerial::getdtr()
260 /*******************************/
261 /* Devolver el estado del DTR */
262 /*******************************/
263 {
264 int arg;
265
266 ioctl(fd,TIOCMGET,&arg);
267 /* return arg&TIOCM_DTR;*/
268 if ((arg&TIOCM_DTR)==0) return 0;
269 else return 1;
270 }
271
272 int ComSerial::dtr_on()
273 /********************/
274 /* Activar el DTR */
275 /********************/
276 {
277 int flag=0;
278 int status;
279
280 flag=TIOCM_DTR;
281 status = ioctl(fd,TIOCMBIS,&flag);
282 if (status !=0) {
283 nerror=6;
284 return 0;
285 }
286 return 1;
287 }
288
289 int ComSerial::dtr_off()
290 /**********************/
291 /* Desactivar el DTR */
292 /**********************/
293 {
294 int flag=0;
295 int status;
296
297 flag=TIOCM_DTR;
298 status = ioctl(fd,TIOCMBIC,&flag);
299 if (status !=0) {
300 nerror=7;
301 return 0;
302 }
303 return 1;
304 }
305
306 int ComSerial::getdsr()
307 /*******************************/
308 /* Devolver el estado del DSR */
309 /*******************************/
310 {
311 int arg;
312
313 ioctl(fd,TIOCMGET,&arg);
314 /* return arg&TIOCM_DSR;*/
315 if ((arg&TIOCM_DSR)==0) return 0;
316 else return 1;
317 }
318
319 int ComSerial::getrts()
320 /*******************************/
321 /* Devolver el estado del RTS */
322 /*******************************/
323 {
324 int arg;
325
326 ioctl(fd,TIOCMGET,&arg);
327 /* return arg&TIOCM_RTS;*/
328 if ((arg&TIOCM_RTS)==0) return 0;
329 else return 1;
330 }
331
332 int ComSerial::rts_on()
333 /********************/
334 /* Activar el RTS */
335 /********************/
336 {
337 int flag=0;
338 int status;
339
340 flag=TIOCM_RTS;
341 status = ioctl(fd,TIOCMBIS,&flag);
342 if (status !=0) {
343 nerror=6;
344 return 0;
345 }
346 return 1;
347 }
348
349 int ComSerial::rts_off()
350 /**********************/
351 /* Desactivar el RTS */
352 /**********************/
353 {
354 int flag=0;
355 int status;
356
357 flag=TIOCM_RTS;
358 status = ioctl(fd,TIOCMBIC,&flag);
359 if (status !=0) {
360 nerror=7;
361 return 0;
362 }
363 return 1;
364 }
365
366 int ComSerial::getcts()
367 /*******************************/
368 /* Devolver el estado del CTS */
369 /*******************************/
370 {
371 int arg;
372
373 ioctl(fd,TIOCMGET,&arg);
374 /* return arg&TIOCM_CTS;*/
375 if ((arg&TIOCM_CTS)==0) return 0;
376 else return 1;
377 }
378
379 int ComSerial::getserial_fd()
380 /***************************************************************/
381 /* Devolver el descriptor del fichero del puerto serie abierto */
382 /***************************************************************/
383 {
384 return fd;
385 }
386
387 void ComSerial::cerrar_puerto_serie()
388 /*****************************/
389 /* Cerrar el puerto serie */
390 /*****************************/
391 {
392 /* Reestablecer antiguos atributos */
393 if (tcsetattr(fd,TCSANOW,&oldtermios)==-1) {
394 printf ("Error en TCSETATTR\n");
395 //exit(1);
396 }
397
398 close (fd);
399 }
400
401 int ComSerial::abrir_puerto_serie(int puerto)
402 /*****************************************************************/
403 /* Abrir el puerto serie para trabajar con el. */
404 /* El parametro puerto indica el puerto serie que se quiere */
405 /* abrir: */
406 /* 0 --> COM1 (ttyS0) */
407 /* 1 --> COM2 (ttyS1) */
408 /* */
409 /* Por defecto se abre a la velocidad de 7680 */
410 /*****************************************************************/
411 {
412 char disp[15];
413
414 switch(puerto){
415 case 0 :strcpy(disp,"/dev/ttyS0"); break; /* COM1 */
416 case 1 :strcpy(disp,"/dev/ttyS1"); break; /* COM2 */
417 default :strcpy(disp,"/dev/ttyS1");
418 }
419
420 printf("Abriendo puerto: %i -> %s\n", puerto, disp);
421
422 fd = open(disp,O_RDWR | O_NOCTTY | O_NONBLOCK); /* Abrir puerto serie */
423 if (fd==-1) {
424 nerror=5;
425 return 0;
426 }
427
428 if (setup_serial()==0) return 0; /* Configurar puerto serie */
429 return 1;
430 }
431
432 void ComSerial::accion_rxcar()
433 /*****************************************************************/
434 /* Codificacion pendiente */
435 /*****************************************************************/
436 {
437 }
438
439 void ComSerial::accion_break()
440 /*****************************************************************/
441 /* Codificacion pendiente */
442 /*****************************************************************/
443 {
444 }
Archivos adjuntos
Para referirse a los adjuntos de una página, usa attachment:nombredelarchivo, como se muestra abajo en la lista de archivos. NO uses la URL del enlace [get], ya que puede cambiar fácilmente y dejar de funcionar.No tienes permisos para adjuntar un archivo a esta página.