2024年Linux最新linux下串口使用

文章详细描述了如何在Linux中配置串口,包括设置奇偶校验、停止位、输出模式等,并提供了安全的串口读写函数,以及使用select进行多路I/O处理。
摘要由CSDN通过智能技术生成
{
    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;

}


5、关闭串口



int uart_close(int fd)
{
assert(fd);
close(fd);

/\*可以在这里做些清理工作\*/

最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

资料预览

给大家整理的视频资料:

给大家整理的电子书资料:

如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!

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

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

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值