Linux 串口读取
https://blog.csdn.net/wabil/article/details/118610070
- #include <stdlib.h>
- #include <fcntl.h>
- #include "stdio.h"
- #include "termios.h"
- #include "unistd.h"
- #include "limits.h"
- #include <stdint.h>
- #include "time.h"
- //===================
- #include <sys/select.h>
- #include <sys/time.h>
- //===================
-
-
- #define UART_DEV "/dev/ttyUSB0" //根据电脑插入的串口号定义
-
-
- void main()
- {
- int fd =0;
- int RxLen=0;
- uint8_t RxBuff[1024]={0};
-
- //==========串口打开============//
- fd = open(UART_DEV ,O_RDWR|O_NOCTTY);
- if(fd<0){
- printf("COM (%s) Open Fail ! \n",UART_DEV); //必须要权限.
- return;
- }
-
-
- printf("COM (%s) Open Success ! Watting recv...\n\n",UART_DEV);
- //==========配置串口============//
- struct termios opt; //配置串口的属性定义在结构体struct termios中
- tcgetattr(fd, & opt); //获取终端控制属性
-
- cfsetispeed(& opt, B115200); //指定输入波特率(若不设置系统默认9600bps)
- cfsetospeed(& opt, B115200); //指定输出波特率(若不设置系统默认9600bps)
-
- /* c_lflag 本地模式 */
- opt.c_cflag &= ~ INPCK; //不启用输入奇偶检测
- opt.c_cflag |= (CLOCAL | CREAD); //CLOCAL忽略 modem 控制线,CREAD打开接受者
-
- /* c_lflag 本地模式 */
- opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //ICANON启用标准模式;ECHO回显输入字符;ECHOE如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词;ISIG当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号
-
- /* c_oflag 输出模式 */
- opt.c_oflag &= ~ OPOST; //OPOST启用具体实现自行定义的输出处理
- opt.c_oflag &= ~(ONLCR | OCRNL); //ONLCR将输出中的新行符映射为回车-换行,OCRNL将输出中的回车映射为新行符
-
- /* c_iflag 输入模式 */
- opt.c_iflag &= ~(ICRNL | INLCR); //ICRNL将输入中的回车翻译为新行 (除非设置了 IGNCR),INLCR将输入中的 NL 翻译为 CR
- opt.c_iflag &= ~(IXON | IXOFF | IXANY); //IXON启用输出的 XON/XOFF流控制,IXOFF启用输入的 XON/XOFF流控制,IXANY(不属于 POSIX.1;XSI) 允许任何字符来重新开始输出
-
- /* c_cflag 控制模式 */
- opt.c_cflag &= ~ CSIZE; //字符长度掩码,取值为 CS5, CS6, CS7, 或 CS8,加~就是无
- opt.c_cflag |= CS8; //数据宽度是8bit
- opt.c_cflag &= ~ CSTOPB; //CSTOPB设置两个停止位,而不是一个,加~就是设置一个停止位
- opt.c_cflag &= ~ PARENB; //PARENB允许输出产生奇偶信息以及输入的奇偶校验,加~就是无校验
-
- /* c_cc[NCCS] 控制字符 */
- opt.c_cc[VTIME] = 0 ; //等待数据时间(10秒的倍数),每个单位是0.1秒 若20就是2秒
- opt.c_cc[VMIN] = 0 ; //最少可读数据,非规范模式读取时的最小字符数,设为0则为非阻塞,如果设为其它值则阻塞,直到读到到对应的数据,就像一个阀值一样,比如设为8,如果只接收到3个数据,那么它是不会返回的,只有凑齐8个数据后一齐才READ返回,阻塞在那儿
- /* new_cfg.c_cc[VMIN] = 8;//DATA_LEN;
- new_cfg.c_cc[VTIME] = 20;//每个单位是0.1秒 20就是2秒
- 如果这样设置,就完全阻塞了,只有串口收到至少8个数据才会对READ立即返回,或才少于8个数据时,超时2秒也会有返回
- 另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数*/
-
- /*TCIFLUSH 刷清输入队列
- TCOFLUSH 刷清输出队列
- TCIOFLUSH 刷清输入、输出队列*/
- tcflush(fd, TCIOFLUSH); //刷串口清缓存
- tcsetattr(fd, TCSANOW, &opt); //设置终端控制属性,TCSANOW:不等数据传输完毕就立即改变属性
-
- while(1)
- {
- //==========串口接收(字符串)============//
- while( ((RxLen = read(fd, RxBuff,sizeof(RxBuff))) > 0) )
- {
- RxBuff[RxLen] = 0;
- printf( "%s",RxBuff);
-
- }
-
- }
-
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <unistd.h>
-
-
-
- /**
- * @brief set_baudrate 设置波特率
- * @param opt
- * @param baudrate
- */
- static void set_baudrate (struct termios *opt, unsigned int baudrate)
- {
- cfsetispeed(opt, baudrate);
- cfsetospeed(opt, baudrate);
- }
-
- /**
- * @brief set_data_bit 设置数据位
- * @param opt
- * @param databit
- */
- static void set_data_bit (struct termios *opt, unsigned int databit)
- {
- opt->c_cflag &= ~CSIZE;
- switch (databit) {
- case 8:
- opt->c_cflag |= CS8;
- break;
- case 7:
- opt->c_cflag |= CS7;
- break;
- case 6:
- opt->c_cflag |= CS6;
- break;
- case 5:
- opt->c_cflag |= CS5;
- break;
- default:
- opt->c_cflag |= CS8;
- break;
- }
- }
-
- /**
- * @brief set_parity 设置奇偶校验位
- * @param opt
- * @param parity
- */
- static void set_parity (struct termios *opt, char parity)
- {
- switch (parity) {
- case 'N': /* no parity check */
- opt->c_cflag &= ~PARENB;
- break;
- case 'E': /* even */
- opt->c_cflag |= PARENB;
- opt->c_cflag &= ~PARODD;
- break;
- case 'O': /* odd */
- opt->c_cflag |= PARENB;
- opt->c_cflag |= ~PARODD;
- break;
- default: /* no parity check */
- opt->c_cflag &= ~PARENB;
- break;
- }
- }
-
- /**
- * @brief set_stopbit 设置停止位
- * @param opt
- * @param stopbit
- */
- static void set_stopbit (struct termios *opt, const char *stopbit)
- {
- if (0 == strcmp (stopbit, "1")) {
- opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
- } else if (0 == strcmp (stopbit, "1")) {
- opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
- } else if (0 == strcmp (stopbit, "2")) {
- opt->c_cflag |= CSTOPB; /* 2 stop bits */
- } else {
- opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
- }
- }
-
- int set_port_attr (
- int fd,
- int baudrate, // B1200 B2400 B4800 B9600 .. B115200
- int databit, // 5, 6, 7, 8
- const char *stopbit, // "1", "1.5", "2"
- char parity, // N(o), O(dd), E(ven)
- int vtime,
- int vmin )
- {
- struct termios opt;
- tcgetattr(fd, &opt);
- //设置波特率
- set_baudrate(&opt, baudrate);
- opt.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
- //设置数据位
- set_data_bit(&opt, databit);
- //设置校验位
- set_parity(&opt, parity);
- //设置停止位
- set_stopbit(&opt, stopbit);
- //其它设置
- opt.c_oflag = 0;
- opt.c_lflag |= 0;
- opt.c_oflag &= ~OPOST;
- opt.c_cc[VTIME] = vtime;
- opt.c_cc[VMIN] = vmin;
- tcflush (fd, TCIFLUSH);
- return (tcsetattr (fd, TCSANOW, &opt));
- }
-
-
- int main(int argc, char **argv)
- {
-
- printf("=========BuildTime:[%s %s]============\n",__DATE__,__TIME__ );
-
- //通过指令 ls /dev/* 查看电脑硬件设备
- //一般 ttyS0 等价于Windows的COM1 ,以此类推
- //可用MobaXterm软件在Windows下运行linux程序
-
- char *devPath = "/dev/ttyS25";
- int fd = open(devPath ,O_RDWR);
- long baud = 115200;
-
- if(fd < 0){
- printf("[ERROR] uart [%s] open file failed .", devPath );
- return -1;
- }
-
- set_port_attr(fd,baud,8,"N",'1',0,0);
-
- printf("uart [%s] open sucess,baud=%d bps.\n",devPath , baud );
-
- char buf[1024*5] = {0};
- int max_size = sizeof(buf);
- int len = 0;
-
- while(1) //Ctrl+C 结束终端
- {
- memset(buf,0,max_size);
- len = read(fd, buf,max_size);
- if(len<=0)
- {
- usleep(1000);
- continue;
- }
- printf("Length:%d,Text:%s\r\n",len,buf);
- //printf("%s",buf);
- }
-
- close( fd );
- printf("Quit main program.\n");
-
-
- }