简体   繁体   English

编程Linux串口,ttyS0

[英]Programming Linux serial port, ttyS0

I'm trying to learn how to program the ttyS0 serial port in Linux using C. I have another machine connected to my serial port sending alternating hex values of 5f and 6f about every two seconds. 我正在尝试学习如何使用C对Linux中的ttyS0串口进行编程。我的另一台机器连接到我的串口,大约每两秒发送5f和6f的交替十六进制值。 I've verified with other port monitoring apps that these values are appearing at the port. 我已经与其他端口监控应用程序验证了这些值是否出现在端口上。 In my code I'm using a blocking read() into a 10 char length buffer. 在我的代码中,我使用阻塞read()到10个字符长度的缓冲区中。 Even though my other machine is still sending data, read() blocks forever. 即使我的其他机器仍在发送数据, read()也会永久阻止。 If I include the line fcntl(fd, F_SETFL, FNDELAY); 如果我包含行fcntl(fd,F_SETFL,FNDELAY); which sets read() to non-blocking read() always returns with a value of -1, meaning no data was in the UART buffer, and my for loop code just prints out random values that are in the buffer. 将read()设置为非阻塞read()始终返回值为-1,这意味着UART缓冲区中没有数据,而我的for循环代码只打印出缓冲区中的随机值。 So in short my assumption is that my code is not reading ttyS0 and I have no idea why. 所以简而言之,我的假设是我的代码不是读取ttyS0而我不知道为什么。 Below is my code, hopefully someone will see what's causing my problem and set me straight. 下面是我的代码,希望有人会看到是什么导致了我的问题并让我直截了当。 By the way, I'm using Scientific Linux, I believe ttyS0 is com port 1, as it is in RedHat and Fedora. 顺便说一句,我正在使用Scientific Linux,我相信ttyS0是com端口1,就像在RedHat和Fedora中一样。 Aslo below is the output when i run the code. 以下是我运行代码时的输出。 It seems to be writing to the COM port with no problems, but for a read it says its unavailable. 它似乎是写入COM端口没有问题,但对于读取它说它不可用。 Also it's clear that the buffer I'm printing out is just random values not data that's been read in. Thanks 另外很明显,我打印出的缓冲区只是随机值,而不是已读入的数据。谢谢

console output 控制台输出

hello world
hi again
write error: : Success
 wrote 4 bytes
number of bytes read is -1
read error:: Resource temporarily unavailable
4  8  120  -99  -73  -65  41  -120  4  8  
should of put something out

Code

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

int main()
{
    printf("hello world\n");
    int n;
    int fd;
    char c;
    int bytes;

    char buffer[10];
    char *bufptr;
    int nbytes;
    int tries;
    int x;
    struct termios options;


    fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd == -1)
    {
        perror("open_port: Unable to open:");
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("hi again\n");
    }

    tcgetattr(fd, &options);

    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
    options.c_iflag &= ~(IXON | IXOFF | IXANY );
    options.c_oflag &= ~OPOST;

    tcsetattr(fd, TCSANOW, &options);


    write(fd, "ATZ\r",4);
    printf(" wrote\n");
    bufptr = buffer;


    fcntl(fd, F_SETFL, FNDELAY);
     bytes = read(fd, bufptr, sizeof(buffer));
    printf("number of bytes read is %d\n", bytes);
    perror ("read error:");

    for (x = 0; x < 10 ; x++)
    {
        c = buffer[x];
        printf("%d  ",c);
    }
    close(fd);

    //puts(buffer[0]);
    printf("\nshould of put something out \n");

    return (0);
}

The following line will cause problems: 以下行将导致问题:

options.c_cflag &= CSTOPB;

It will reset all other bits of the c_cflag. 它将重置c_cflag的所有其他位。

If you want to use 1 stop bit, then use: 如果要使用1个停止位,则使用:

options.c_cflag &= ~CSTOPB;

If you want to use 2 stop bits, then use: 如果要使用2个停止位,则使用:

options.c_cflag |= CSTOPB;

EDIT: 编辑:

Also the following line cause problems: 以下行也会导致问题:

fcntl(fd, F_SETFL, 0);

It will reset several important flags. 它会重置几个重要的标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM