gpt4 book ai didi

c - Linux串口编程

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:07:51 26 4
gpt4 key购买 nike

我想用开发板上的RS232接口(interface)与PC机通讯。我知道我可以为此目的使用 "dev/ttyS0"

我可以使用write() 函数打开数据并将数据写入PC。但问题是我无法从“dev/ttyS0”读取。每次我使用读取功能时,我都会得到“资源暂时不可用”。你们能告诉我如何解决这个问题吗?

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

int main()
{
int n = 0, fd = 0, bytes = 0;
char ch = 0;

char buffer[10], *bufPtr;
int nBytes = 0, tries = 0, x = 0;

struct termios term;

fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);

if (fd == -1)
{
perror("open");
return;
}
else
{
fcntl(fd, F_SETFL, 0);
perror("Port");
}

if (n = tcgetattr(fd, &term) == -1)
{
perror("tcgetattr");
return;
}

if (n = cfsetispeed(&term, B115200) == -1)
{
perror("cfsetispeed");
return;
}

if (n = cfsetospeed(&term, B115200) == -1)
{
perror("cfsetospeed");
return;
}

term.c_cflag |= (CLOCAL | CREAD);
term.c_cflag &= ~PARENB;
term.c_cflag &= ~CSTOPB;
term.c_cflag &= ~CSIZE;
term.c_cflag |= CS8;
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
term.c_iflag &= ~(IXON | IXOFF | IXANY);
term.c_cflag &= ~CRTSCTS;
term.c_oflag &= ~OPOST;

if (n = tcsetattr(fd, TCSANOW, &term) == -1)
{
perror("tcsetattr");
return;
}

write(fd,"LINUX",5);
perror("write");

fcntl(fd, F_SETFL, FNDELAY);
perror("fcntl");
bytes = read(fd, buffer, sizeof(buffer));
perror("read");
printf("Bytes : %d and data: %s\n", bytes, buffer);
}

最佳答案

你的测试是什么?您是否将 RS232 DB9 连接器的针脚 2 和针脚 3 短路了?

否则,如果没有要读取的数据,read 将始终返回 -1。

这就是您的代码使用 O_NDELAY 标志打开串行线时应该执行的操作。

要避免在没有数据可读时读取,可以使用select。在你的情况下:

struct timeval tv;
fd_set rset;
int retV;
int timeout = 5000; // 5 seconds

tv.tv_usec = (timeout * 1000) % 1000000;
tv.tv_sec = timeout / 1000;

FD_ZERO ( &rset );
FD_SET ( fd, &rset );
retV = select ( fd+1, &rset, NULL, NULL, &tv );

if( retV == 0 )
{
// timeout stuff
}
else if( retV < 0 )
{
// Error stuff. Read errno to see what happened
}
else
{
// read data
}

编辑

删除 fcntl(fd, F_SETFL, FNDELAY);如果您想要正常的阻塞读取,请取消设置该标志。

在您的代码中,您还假设 read 将返回所有发送的字符,但事实并非如此。 read 将返回可供读取的字符。这意味着如果您发送“LINUX”,可能会请求读取 5 次以读取发送的所有 5 个字符。

最后一件事

printf("Bytes : %d and data: %s\n", bytes, buffer);

Undefined Behavior因为 buffer 不是以 NULL 结尾的字符串。您可以解决它在接收到的字符上循环并以 %c 格式打印它,或者 NULL 终止您的缓冲区:

if (bytes > 0)
buffer[bytes] = '\0';

char stringToSend[] = "LINUX";
size_t len = strlen(stringToSend) +1 ;

write(fd,"LINUX", len);
perror("write");

size_t receivedBytes = 0;
bytes = 0;
while (receivedBytes<len)
{
bytes = read(fd, &buffer[receivedBytes], sizeof(buffer)-1);
perror("read");

if (bytes > 0)
receivedBytes += bytes;
}

printf("Bytes : %d and data: %s\n", receivedBytes, buffer);

关于c - Linux串口编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35032069/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com