He escrito un programa que puede enviar y luego recibir el mensaje que acaba de enviarse desde el puerto UART y he conectado el TXD a RXD juntos del mismo puerto UART. Tiene tres partes, que son la función principal, la función utilizada para abrir el dispositivo UART y la función que se usa para configurar las funciones del dispositivo. El código es el siguiente: La función principal:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
/********************************************************************
This app can open a serial device which is the first parameter
delivered to the main function,
and send a string, then, receive it.
version: 1.3
*******************************************************************/
int open_uart(char* port_name);
int UART_initialize(int fd, speed_t speed, int flow_ctrl, int
data_bits, int stop_bits, int parity );
int main(int argc, char*argv[])
{
int fd;
char rev_buff[1023];//read
char send_buff[1023];//write
char flag='y';
int rev_len;
int send_len;
fd= open_uart(argv[1]);
if(fd == 0)
{
fprintf(stderr,"open serial terminal failed...\n");
return -1;
}
tcflush(fd,TCIOFLUSH);
UART_initialize(fd,B115200,0,8,1,2);
while(flag=='y'||flag=='Y')
{
printf("Please type in the charactors you want to send~\t:");
scanf("%s",send_buff);
fflush(stdin);
send_len=write(fd,send_buff,strlen(send_buff)+1);
if(send_len<0)
{
fprintf(stderr,"send failed!\n");
send_buff[0]='/******************************open the
terminal***********************************
name: open_uart
input: char* port_name: the path to the serial device.
output: file descripter: fd ------> the termianl device.
********************************************************************/
int open_uart(char* port_name)
{
int fd;//the number standing for the uart port
//did I open the device successfully
fd=open(port_name, O_RDWR|O_NOCTTY|O_NDELAY);//not block
if(fd == -1)
{
printf("can't open the tty port!\n");
return 0;
}
//whether the device is blocked
if(fcntl(fd, F_SETFL, 0) <0)
{
printf("fcntl failed!\n");
return(0);
}
else
{
printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
}
//whether the device is a tty?
if(isatty(fileno(stdin))==0)
{
printf("standard input is not a terminal device\n");
return(0);
}
else
{
printf("the stnadard input is a tty!\n");
}
printf("fd->tty_device=%d\n",fd);
return fd;
}
/*********************************************************/
';
continue;
}
printf("you have sent:\t%s(%dbytes)\n",send_buff,send_len);
send_buff[0]='/***********************************************************
name: UART_initialize
function: set the number of bits in one data unit, the stoping bit
and the
verifying bit
input: fd(int): the file descripter pointing to the device
speed(speed_t):the speed of the termianl
flow_ctrl: RTS\CTS
data_bits: the number of the bits in a data unit 7 or 8
stop_bits:
parity: verifying type
output: successful: 1 unsuccessful:0
*************************************************/
int UART_initialize(int fd, speed_t speed, int flow_ctrl, int
data_bits, int stop_bits, int parity)
***************************************
{
struct termios options;
if(tcgetattr(fd,&options))
{
perror("SetupSerial 1");
return(0);
}
//set bps
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
///////
options.c_cflag |= CLOCAL;
options.c_cflag |= CREAD;
switch(flow_ctrl)
{
case 0 ://不使用流控制
options.c_cflag &= ~CRTSCTS;break;
case 1 ://使用硬件流控制
options.c_cflag |= CRTSCTS;break;
case 2 ://使用软件流控制
options.c_cflag |= IXON | IXOFF | IXANY;break;
}
//set the number of bits
options.c_cflag &= ~CSIZE;//reset the bits mark bits except the
former ones
switch(data_bits)
{
case 5: options.c_cflag |= CS5;break;
case 6: options.c_cflag |= CS6;break;
case 7: options.c_cflag |= CS7;break;
case 8: options.c_cflag |= CS8;break;
default: fprintf(stderr,"Unsupported data size\n");
return 0;
}
//parity bit
switch(parity)
{
case 0:// no parity bit
options.c_cflag &=~PARENB;
options.c_cflag &=~INPCK;
break;
case 1://odd number
options.c_cflag |=(PARODD|PARENB);
options.c_cflag |=INPCK;
break;
case 2://even number
options.c_cflag |=(PARENB|INPCK);
options.c_cflag &=~PARODD;
break;
}
switch(stop_bits)
{
case 1://1 stop bit
options.c_cflag &=~CSTOPB;
break;
case 2://2 stop bits
options.c_cflag |=CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return(0);
}
//close special output mode
options.c_oflag &= ~OPOST;
//input mode
options.c_iflag &=~BRKINT;
options.c_iflag &=~IGNBRK;//break until NULL
//wait time and minmum number of "bytes"
options.c_cc[VTIME]= 1;//wait for 0.1s
options.c_cc[VMIN]= 1;//read at least 1 byte
//if flush, receive the data do not read
tcflush(fd,TCIFLUSH);
//set options
if(tcsetattr(fd,TCSANOW,&options)!=0)
{
perror("tty set error!\n");
return 0;
}
return 1;
}
';
tcflush(fd,TCOFLUSH);
printf("start receive\n");
rev_len=read(fd,rev_buff,1024);
tcflush(fd,TCIFLUSH);
if(rev_len<0)
{
fprintf(stderr,"receive failed");
rev_buff[0]='#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
/********************************************************************
This app can open a serial device which is the first parameter
delivered to the main function,
and send a string, then, receive it.
version: 1.3
*******************************************************************/
int open_uart(char* port_name);
int UART_initialize(int fd, speed_t speed, int flow_ctrl, int
data_bits, int stop_bits, int parity );
int main(int argc, char*argv[])
{
int fd;
char rev_buff[1023];//read
char send_buff[1023];//write
char flag='y';
int rev_len;
int send_len;
fd= open_uart(argv[1]);
if(fd == 0)
{
fprintf(stderr,"open serial terminal failed...\n");
return -1;
}
tcflush(fd,TCIOFLUSH);
UART_initialize(fd,B115200,0,8,1,2);
while(flag=='y'||flag=='Y')
{
printf("Please type in the charactors you want to send~\t:");
scanf("%s",send_buff);
fflush(stdin);
send_len=write(fd,send_buff,strlen(send_buff)+1);
if(send_len<0)
{
fprintf(stderr,"send failed!\n");
send_buff[0]='/******************************open the
terminal***********************************
name: open_uart
input: char* port_name: the path to the serial device.
output: file descripter: fd ------> the termianl device.
********************************************************************/
int open_uart(char* port_name)
{
int fd;//the number standing for the uart port
//did I open the device successfully
fd=open(port_name, O_RDWR|O_NOCTTY|O_NDELAY);//not block
if(fd == -1)
{
printf("can't open the tty port!\n");
return 0;
}
//whether the device is blocked
if(fcntl(fd, F_SETFL, 0) <0)
{
printf("fcntl failed!\n");
return(0);
}
else
{
printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
}
//whether the device is a tty?
if(isatty(fileno(stdin))==0)
{
printf("standard input is not a terminal device\n");
return(0);
}
else
{
printf("the stnadard input is a tty!\n");
}
printf("fd->tty_device=%d\n",fd);
return fd;
}
/*********************************************************/
';
continue;
}
printf("you have sent:\t%s(%dbytes)\n",send_buff,send_len);
send_buff[0]='/***********************************************************
name: UART_initialize
function: set the number of bits in one data unit, the stoping bit
and the
verifying bit
input: fd(int): the file descripter pointing to the device
speed(speed_t):the speed of the termianl
flow_ctrl: RTS\CTS
data_bits: the number of the bits in a data unit 7 or 8
stop_bits:
parity: verifying type
output: successful: 1 unsuccessful:0
*************************************************/
int UART_initialize(int fd, speed_t speed, int flow_ctrl, int
data_bits, int stop_bits, int parity)
***************************************
{
struct termios options;
if(tcgetattr(fd,&options))
{
perror("SetupSerial 1");
return(0);
}
//set bps
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
///////
options.c_cflag |= CLOCAL;
options.c_cflag |= CREAD;
switch(flow_ctrl)
{
case 0 ://不使用流控制
options.c_cflag &= ~CRTSCTS;break;
case 1 ://使用硬件流控制
options.c_cflag |= CRTSCTS;break;
case 2 ://使用软件流控制
options.c_cflag |= IXON | IXOFF | IXANY;break;
}
//set the number of bits
options.c_cflag &= ~CSIZE;//reset the bits mark bits except the
former ones
switch(data_bits)
{
case 5: options.c_cflag |= CS5;break;
case 6: options.c_cflag |= CS6;break;
case 7: options.c_cflag |= CS7;break;
case 8: options.c_cflag |= CS8;break;
default: fprintf(stderr,"Unsupported data size\n");
return 0;
}
//parity bit
switch(parity)
{
case 0:// no parity bit
options.c_cflag &=~PARENB;
options.c_cflag &=~INPCK;
break;
case 1://odd number
options.c_cflag |=(PARODD|PARENB);
options.c_cflag |=INPCK;
break;
case 2://even number
options.c_cflag |=(PARENB|INPCK);
options.c_cflag &=~PARODD;
break;
}
switch(stop_bits)
{
case 1://1 stop bit
options.c_cflag &=~CSTOPB;
break;
case 2://2 stop bits
options.c_cflag |=CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return(0);
}
//close special output mode
options.c_oflag &= ~OPOST;
//input mode
options.c_iflag &=~BRKINT;
options.c_iflag &=~IGNBRK;//break until NULL
//wait time and minmum number of "bytes"
options.c_cc[VTIME]= 1;//wait for 0.1s
options.c_cc[VMIN]= 1;//read at least 1 byte
//if flush, receive the data do not read
tcflush(fd,TCIFLUSH);
//set options
if(tcsetattr(fd,TCSANOW,&options)!=0)
{
perror("tty set error!\n");
return 0;
}
return 1;
}
';
tcflush(fd,TCOFLUSH);
printf("start receive\n");
rev_len=read(fd,rev_buff,1024);
tcflush(fd,TCIFLUSH);
if(rev_len<0)
{
fprintf(stderr,"receive failed");
rev_buff[0]='%pre%';
}
else if (rev_len==0)
{
fprintf(stderr,"the port doesn't received any data!\n");
}
else
{
printf("you have received:%s\n(%dbytes)",rev_buff,rev_len);
}
printf("Do you want to continue?(y/n):");
scanf("%c",&flag);
fflush(stdin);
getchar();
}
close(fd);
}
';
}
else if (rev_len==0)
{
fprintf(stderr,"the port doesn't received any data!\n");
}
else
{
printf("you have received:%s\n(%dbytes)",rev_buff,rev_len);
}
printf("Do you want to continue?(y/n):");
scanf("%c",&flag);
fflush(stdin);
getchar();
}
close(fd);
}
La función utilizada para abrir el dispositivo:
%pre%La función utilizada para configurar las características del dispositivo
%pre%El problema que encontré es que escribí una cadena corta en la línea de cmd, como "¡Hola!", el programa pareció "detenerse" después de comenzar a recibir la impresión con el indicador led de txd y rxd seguir emitiendo luz. Supongo que el dispositivo envía la cadena repetidamente. Pero, ¿qué es exactamente lo que causa el problema? ¿Puedes ayudarme?
Aquí están mis dos intentos con el programa. En el primer intento, conecté el RXD y el TXD juntos, mientras que en el segundo intento no los conecté simplemente dejándolos suspendidos. Aquí está mi línea de comando:
Losdosintentaronambospausadosenelmismolugar.Sinembargo,enelprimerintento,losLEDdeenvíoyrecepcióncontinuaronencendiéndose,así:
mientras que los LED estaban apagados después de un corto encendido. Además, utilicé un osciloscopio y descubrí que en el primer intento, el TXD sigue enviando datos, mientras que en el segundo intento, el TXD simplemente envía un dato muy corto y no envía nada.