linux下串口使用

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

{
    perror("tcgetattr error");
    return -1;
}

/\*设置输入输出波特率,两者保持一致\*/
switch(baude)
{
    case 4800:
        cfsetispeed(&options,B4800);
        cfsetospeed(&options,B4800);
        break;
    case 9600:
        cfsetispeed(&options,B9600);
        cfsetospeed(&options,B9600);
        break;
    case 19200:
        cfsetispeed(&options,B19200);
        cfsetospeed(&options,B19200);
        break;
    case 38400:
        cfsetispeed(&options,B38400);
        cfsetospeed(&options,B38400);
        break;
    default:
        fprintf(stderr,"Unkown baude!\n");
        return -1;
}

/\*设置控制模式\*/
options.c_cflag |= CLOCAL;//保证程序不占用串口
options.c_cflag |= CREAD;//保证程序可以从串口中读取数据

/\*设置数据流控制\*/
switch(c_flow)
{
    case 0://不进行流控制
        options.c_cflag &= ~CRTSCTS;
        break;
    case 1://进行硬件流控制
        options.c_cflag |= CRTSCTS;
        break;
    case 2://进行软件流控制
        options.c_cflag |= IXON|IXOFF|IXANY;
        break;
    default:
        fprintf(stderr,"Unkown c\_flow!\n");
        return -1;
}

/\*设置数据位\*/
switch(bits)
{
    case 5:
        options.c_cflag &= ~CSIZE;//屏蔽其它标志位
        options.c_cflag |= CS5;
        break;
    case 6:
        options.c_cflag &= ~CSIZE;//屏蔽其它标志位
        options.c_cflag |= CS6;
        break;
    case 7:
        options.c_cflag &= ~CSIZE;//屏蔽其它标志位
        options.c_cflag |= CS7;
        break;
    case 8:
        options.c_cflag &= ~CSIZE;//屏蔽其它标志位
        options.c_cflag |= CS8;
        break;
    default:
        fprintf(stderr,"Unkown bits!\n");
        return -1;
}

/\*设置校验位\*/
switch(parity)
{
    /\*无奇偶校验位\*/
    case 'n':
    case 'N':
        options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
        options.c_cflag &= ~INPCK;//INPCK:使奇偶校验起作用
        break;
    /\*设为空格,即停止位为2位\*/
    case 's':
    case 'S':
        options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
        options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位
        break;
    /\*设置奇校验\*/
    case 'o':
    case 'O':
        options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
        options.c_cflag |= PARODD;//PARODD:若设置则为奇校验,否则为偶校验
        options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
        options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
        break;
    /\*设置偶校验\*/
    case 'e':
    case 'E':
        options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
        options.c_cflag &= ~PARODD;//PARODD:若设置则为奇校验,否则为偶校验
        options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
        options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
        break;
    default:
        fprintf(stderr,"Unkown parity!\n");
        return -1;
}

/\*设置停止位\*/
switch(stop)
{
    case 1:
        options.c_cflag &= ~CSTOPB;//CSTOPB:使用1位停止位
        break;
    case 2:
        options.c_cflag |= CSTOPB;//CSTOPB:使用两位停止位
        break;
    default:
        fprintf(stderr,"Unkown stop!\n");
        return -1;
}

/\*设置输出模式为原始输出\*/
options.c_oflag &= ~OPOST;//OPOST:若设置则按定义的输出处理,否则所有c\_oflag失效

/\*设置本地模式为原始模式\*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/\*

*ICANON:允许规范模式进行输入处理
*ECHO:允许输入字符的本地回显
*ECHOE:在接收EPASE时执行Backspace,Space,Backspace组合
*ISIG:允许信号
*/

/\*设置等待时间和最小接受字符 否则就会阻塞 如果两个都是0就表示只要我去读就会返回\*/
options.c_cc[VTIME] = 0;//可以在select中设置
options.c_cc[VMIN] = 1;//最少读取一个字符

/\*如果发生数据溢出,只接受数据,但是不进行读操作\*/
tcflush(fd,TCIFLUSH);

/\*

激活配置
TCSANOW:立即执行而不等待数据发送或者接受完成。
TCSADRAIN:等待所有数据传递完成后执行。
TCSAFLUSH:Flush input and output buffers and make the change
*/
if(tcsetattr(fd,TCSANOW,&options) < 0)
{
perror(“tcsetattr failed”);
return -1;
}
return 0;
}


串口默认缓冲512个字节  
 4、串口读写



ssize_t safe_write(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;

ptr = vptr;
nleft = n;

while(nleft > 0)
{
if((nwritten = write(fd, ptr, nleft)) <= 0)
    {
        if(nwritten < 0&&errno == EINTR)
            nwritten = 0;
        else
            return -1;
    }
    nleft -= nwritten;
    ptr   += nwritten;
}
return(n);

}

ssize_t safe_read(int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;

ptr=vptr;
nleft=n;

while(nleft > 0)
{
    if((nread = read(fd,ptr,nleft)) < 0)
    {
        if(errno == EINTR)//被信号中断
            nread = 0;
        else
            return -1;
    }
    else
    if(nread == 0)
        break;
    nleft -= nread;
    ptr += nread;
}
return (n-nleft);

}

int uart_read(int fd,char *r_buf,size_t len)
{
ssize_t cnt = 0;
fd_set rfds;
struct timeval time;

/\*将文件描述符加入读描述符集合\*/
FD\_ZERO(&rfds);
FD\_SET(fd,&rfds);

/\*设置超时为15s\*/
time.tv_sec = 15;
time.tv_usec = 0;

/\*实现串口的多路I/O\*/
ret = select(fd+1,&rfds,NULL,NULL,&time);
switch(ret)
{
    case -1:
        fprintf(stderr,"select error!\n");
        return -1;
    case 0:
        fprintf(stderr,"time over!\n");
        return -1;
    default:
        cnt = safe\_read(fd,r_buf,len);
        if(cnt == -1)
        {
            fprintf(stderr,"read error!\n");
            return -1;
        }
        return cnt;
}

}

int uart_write(int fd,const char *w_buf,size_t len)
{
ssize_t cnt = 0;

cnt = safe\_write(fd,w_buf,len);
if(cnt == -1)
{
    fprintf(stderr,"write error!\n");
    return -1;
}

return cnt;

}

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  return -1;
}

return cnt;

}

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值