我正在尝试通过C中的串行线发送数据。我怀疑我的问题在于我设置的选项,但我无法弄明白。
在下面的程序中,我发送字节0x79,0x80,0x81,但在另一端,我收到0x86,0x06,0x00
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
/*
* 'open_port()' - Open serial port 1.
*
* Returns the file descriptor on success or -1 on error.
*/
char SERIAL_DEVICE[] = {"/dev/ttyUSB0"};
struct termios options;
void open_port(int* fd)
{
*fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if (*fd == -1){
/* Could not open the port. */
perror("open_port: Unable to open serial port - ");
} else
fcntl(*fd, F_SETFL, 0);
}
void send(int message[], size_t bytes_to_send, int* fd){
int n,i;
for(i=0;i<bytes_to_send;i++){
printf("%x", message[i]);
}
n = write(*fd, message, bytes_to_send);
if (n < 0)
fputs("write() failed!\n", stderr);
}
int main(){
int fd; /* File descriptor for the port */
int message[] = {0x79, 0x80, 0x81};
// load the options structure with the cuurent port options
tcgetattr(fd, &options);
cfsetispeed(&options, B19200); // set in baudrate
cfsetospeed(&options, B19200); // set out baudrate
options.c_cflag |= (CLOCAL | CREAD);
// No Parity 8N1
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_iflag |= (IGNPAR | ISTRIP);
//raw input and output
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
// Flush buffers and set new options
tcsetattr(fd, TCSAFLUSH, &options);
open_port(&fd);
int array_length = sizeof(message) / sizeof(message[0]);
int i;
for(i=0;i<array_length;i++){
printf("%x", message[i]);
}
send(message, array_length, &fd);
close(fd);
return 0;
}
答案 0 :(得分:2)
你所有的termios东西都是无效的。您正在更改随机文件描述符的终端特征(fd
未初始化),因为您在执行tcsetattr
后打开串行端口。如果您在tcgetattr
和tcsetattr
来电时检查了错误,那么您会发现这一点。另外,如果你注意编译器发出的警告,你就会发现它。
然后,您的send
功能存在两个问题:
send
系统调用具有相同的名称。这在技术上是正常的,因为你的send
覆盖了来自libc的send
并且一切正常,但它令人困惑(当我第一次阅读我认为你使用send
系统调用的代码时)并且危险(如果您在程序的其他地方使用send
系统调用)。int
s的数组传递给write
,但write
需要一个字节数组。因此,当您尝试写入0x79时,最终会写入4字节0x00 0x00 0x00 0x79(对于big-endian 32位平台)或0x79 0x00 0x00 0x00(对于little-endian 32位平台)。