Linux 串口读取

#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");
	

}

  • 7
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值