用C语言初始化、读写linux串口设备

Emb*_*bed 5 c linux serial-port tty

我正在开发一个新项目,我想与连接到我的 debian 机器的 FTDI 建立连接。我打算用 C 编写代码,而不是 C++。我的问题就在这里。我找到的所有示例都不完整,或者是为 c++ 编译器而不是 GCC 编译器制作的。

目标是与连接到 FTDI 的微控制器进行通信。为了调试,我想开始构建一个 Linux 应用程序,它能够:

  • 在启动时使用 ttyUSB1 初始化串行连接
  • 发送一个字符串
  • PC接收到字符串后显示
  • 将通信保存到 .txt 文件

是否有任何示例代码或教程可以实现此目的?

如果我成功了,我会将代码放在这里,以便新观众可以使用它!

编辑:

就像我说的,如果我有代码,我会发布代码,这对我有用:

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

#define MODEM "/dev/ttyUSB0"
#define BAUDRATE B115200    

int main(int argc,char** argv)
{   
    struct termios tio;
    struct termios stdio;
    struct termios old_stdio;
    int tty_fd, flags;
    unsigned char c='D';
    tcgetattr(STDOUT_FILENO,&old_stdio);
    printf("Please start with %s /dev/ttyS1 (for example)\n",argv[0]);
    memset(&stdio,0,sizeof(stdio));
    stdio.c_iflag=0;
    stdio.c_oflag=0;
    stdio.c_cflag=0;
    stdio.c_lflag=0;
    stdio.c_cc[VMIN]=1;
    stdio.c_cc[VTIME]=0;
    tcsetattr(STDOUT_FILENO,TCSANOW,&stdio);
    tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio);
    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);       // make the reads non-blocking
    memset(&tio,0,sizeof(tio));
    tio.c_iflag=0;
    tio.c_oflag=0;
    tio.c_cflag=CS8|CREAD|CLOCAL;           // 8n1, see termios.h for more information
    tio.c_lflag=0;
    tio.c_cc[VMIN]=1;
    tio.c_cc[VTIME]=5;
    if((tty_fd = open(MODEM , O_RDWR | O_NONBLOCK)) == -1){
        printf("Error while opening\n"); // Just if you want user interface error control
        return -1;
    }
    cfsetospeed(&tio,BAUDRATE);    
    cfsetispeed(&tio,BAUDRATE);            // baudrate is declarated above
    tcsetattr(tty_fd,TCSANOW,&tio);
    while (c!='q'){
        if (read(tty_fd,&c,1)>0){
            write(STDOUT_FILENO,&c,1); // if new data is available on the serial port, print it out
            printf("\n");
        }
        if (read(STDIN_FILENO,&c,1)>0){
            write(tty_fd,&c,1);//if new data is available on the console, send it to serial port
            printf("\n");
        }
    }
    close(tty_fd);
    tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

大部分代码来自http://en.wikibooks.org/wiki/Serial_Programming/Serial_Linux,但我也使用了下面发布的代码中的一些代码。

rfe*_*rmi 3

处理串行端口(适用于 Linux 操作系统):
- 要打开通信,您将需要一个描述符,它将作为串行端口的句柄。
- 设置标志来控制通信方式。
- 将命令写入此句柄(确保正确格式化输入)。
- 得到答案。(确保您要阅读所需的信息量)
- 关闭手柄。看起来会像这样:

int fd; // file descriptor
int flags; // communication flags
int rsl_len; // result size
char message[128]; // message to send, you can even dinamically alocate.
char result[128]; // result to read, same from above, thanks to @Lu

flags = O_RDWR | O_NOCTTY; // Read and write, and make the job control for portability
if ((fd = open("/dev/ttyUSB1", flags)) == -1 ) {
  printf("Error while opening\n"); // Just if you want user interface error control
  return -1;
}
// In this point your communication is already estabilished, lets send out something
strcpy(message, "Hello");
if (rsl_len = write(fd, message, strlen(message)) < 0 ) {
  printf("Error while sending message\n"); // Again just in case
  return -2;
}
if (rsl_len = read(fd, &result, sizeof(result)) < 0 ) {
  printf("Error while reading return\n");
  return -3;
}
close(fd);
Run Code Online (Sandbox Code Playgroud)

请注意,您必须关心要写什么和读什么。在奇偶校验控制、停止位、波特率等情况下可以使用更多标志。