linux 串口uart的使用详解

1.对于在uart在linux上面的使用有几个地方需要注意的

a.输入数据格式的设置(使用read()函数时)

设置方式:

 /*Canonical Input*/
 //termios_new.c_lflag |= (ICANON | ECHO | ECHOE);
 /*Raw Input*/
 //termios_new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

这两个方式有很大的差别:

Raw Inpu模式:基本就是跟普通单片机一样Rx端接收到什么直接返回到用户空间的read函数里面。

Canonical Input模式:Rx端接收到数据之后不会直接反馈给用户态的read函数而是要一直等到一个回车,才会将数据发送到用户空间,还有一个地方需要注意的是,Rx上面接收到的每一个字符都会通过Tx发送出去,这个是由内核控制的,不受用户态控制,这个模式的典型应用就是linux的console。

2.VTIME和VMIN 决定了read()函数什么时候返回

    1.当VTIME>0,VMIN>0时。read调用将保持阻塞直到读取到第一个字符,读到了第一个字符之后开始计时,此后若时间到了VTIME或者时间未到但已读够了VMIN个字符则会返回;若在时间未到之前又读到了一个字符(但此时读到的总数仍不够VMIN)则计时重新开始。

    2. 当VTIME>0,VMIN=0时。read调用读到数据则立即返回,否则将为每个字符最多等待VTIME时间。

    3. 当VTIME=0,VMIN>0时。read调用一直阻塞,直到读到VMIN个字符后立即返回。

    4. 若在open或fcntl设置了O_NDELALY或O_NONBLOCK标志,read调用不会阻塞而是立即返回,那么VTIME和VMIN就没有意义,效果等同于与把VTIME和VMIN都设为了0。

VTIME 和  VMIN


VTIME  定义要求等待的零到几百毫秒的值(通常是一个8位的unsigned char变量)。
VMIN 定义了要求等待的最小字节数, 这个字节数可能是0。
只有设置为阻塞时这两个参数才有效,仅针对于读操作。
说起来比较复杂,举个例子吧,设置为阻塞状态,写操作未进行实验,这里仅讨论读操作,
read(fd,&buf,8); // 读串口


1、


options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
VMIN = 0,当缓冲区字节数 >= 0 时进行读操作,实际上这时读串口操作并未被阻塞,因为条件始终被满足。


2、
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
VMIN = 1,当缓冲区字节数 >= 1 时进行读操作,当没有数据时读串口操作被阻塞。


3、


options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 4;
VMIN = 4,当缓冲区字节数 >= 4 时进行读操作,否则读串口操作被阻塞。每次读出的最大字节数由read函数中第三个参数决定。直到缓冲区剩下的数据< read 第三个参数 并且< 4 (如果这时read第三参数为 1 则进行4次读操作直至读完缓冲区,如read第三参数为2,连续进行读操作,直至缓冲区空或还剩一个字符)。没有设置VTIME,剩下的字符没有确定的期限,直到下次满足读条件的时候才被读出。



4
options.c_cc[VTIME] = 10; //单位百毫秒
options.c_cc[VMIN] = 4;
同3的区别就是,没满足条件或读缓冲区中剩下的数据会在1秒(10百毫秒)后读出。另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数,即,使用read(fd,&buf,2);,以上设置变为:
options.c_cc[VTIME] = 10;
options.c_cc[VMIN] = 2;

下面给一个example code:将开发板的tx,rx分别接到pc端usb转串口的rx,tx端,通过串口助手将数据发送到开发板上面,开发板会将接收到的数据返回给串口助手。

参考:https://blog.csdn.net/qq_21593899/article/details/52281034


#include <stdio.h>
#include <fcntl.h>   /* File Control Definitions           */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h>  /* UNIX Standard Definitions 	   */
#include <errno.h>   /* ERROR Number Definitions           */

int uart_int(void)
{
    int fd;/*File Descriptor*/
    /*------------------------------- Opening the Serial Port -------------------------------*/

    fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY | O_NDELAY);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter  |O_NDELAY */
    /* O_RDWR   - Read/Write access to serial port       */
    /* O_NOCTTY - No terminal will control the process   */
    /* Open in blocking mode,read will wait              */



    if(fd == -1)						/* Error Checking */
    {
        printf("\n  Error! in Opening ttyUSB0  ");
        return -1;
    }
    else
    {
        printf("\n  ttyUSB0 Opened Successfully ");

    }
    /*---------- Setting the Attributes of the serial port using termios structure --------- */

    /*RX init*/
    struct termios SerialPortSettings;	/* Create the structure                          */

    tcgetattr(fd, &SerialPortSettings);	/* Get the current attributes of the Serial port */

    /* Setting the Baud rate */
    cfsetispeed(&SerialPortSettings, B115200); /* Set Read  Speed as 9600                       */
    cfsetospeed(&SerialPortSettings, B115200); /* Set Write Speed as 9600                       */

    /* 8N1 Mode */
    SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
    SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
    SerialPortSettings.c_cflag &= ~CSIZE;	 /* Clears the mask for setting the data size             */
    SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */

    SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow Control                         */
    SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines       */


    SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /* Disable XON/XOFF flow control both i/p and o/p */
    SerialPortSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* Non Cannonical mode                            */


    SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing   raw  format  output*/

    /* Setting Time outs */
    SerialPortSettings.c_cc[VMIN] = 0; /* Read at least 10 characters */
    SerialPortSettings.c_cc[VTIME] = 1; /* Wait indefinetly   */


    if((tcsetattr(fd, TCSANOW, &SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
        printf("\n  ERROR ! in Setting attributes");
    else
        printf("\n  BaudRate = 115200 \n  StopBits = 1 \n  Parity   = none");

    /*------------------------------- Read data from serial port -----------------------------*/

    tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer            */

    close(fd); /* Close the serial port */

    return 0;

}


int main(void)
{
    int fd;/*File Descriptor*/

    printf("\n +----------------------------------+");
    printf("\n |        Serial Port Read          |");
    printf("\n +----------------------------------+");

    uart_int();

    /*------------------------------- Opening the Serial Port -------------------------------*/

    fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY | O_NDELAY);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
    /* O_RDWR   - Read/Write access to serial port       */
    /* O_NOCTTY - No terminal will control the process   */
    /* Open in blocking mode,read will wait              */

    if(fd == -1)						/* Error Checking */
        printf("\n  Error! in Opening ttyUSB0  ");
    else
        printf("\n  ttyUSB0 Opened Successfully ");


    char read_buffer[32];   /* Buffer to store the data received              */
    int  bytes_read = 0;    /* Number of bytes read by the read() system call */
    int i = 0;



    while(1)
    {
        bytes_read = read(fd, &read_buffer, 32); /* Read the data                   */

        if(bytes_read > 0)
        {

            printf("\n\n  Bytes Rxed -%d", bytes_read); /* Print the number of bytes read */
            printf("\n\n  ");

            for(i = 0; i < bytes_read; i++)	 /*printing only the received characters*/
                printf("%c", read_buffer[i]);

            int  bytes_written  = 0;  	/* Value for storing the number of bytes written to the port */

            bytes_written = write(fd, read_buffer, bytes_read); /* use write() to send data to port                                            */
            /* "fd"                   - file descriptor pointing to the opened serial port */
            /*	"write_buffer"         - address of the buffer containing data	            */
            /* "sizeof(write_buffer)" - No of bytes to write             */
            printf("\n  %d Bytes written to ttyUSB0", bytes_written);
            printf("\n\n  Bytes Rxed -%d", bytes_read); /* Print the number of bytes read */
            printf("\n\n  ");

            printf("\n +----------------------------------+\n\n\n");

        }
        //sleep(1);

    }

 


 

 

 

 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值