linux串口示例

最近看了下linux的串口,发现还是蛮容易的

做一些总结和记录

这篇文章也重在备份和记录,代码都是套用别人的 ,所以基本只是罗列了些代码,但保证代码可用

其实串口操作也就那么几步

1.       打开串口

2.       设置参数

3.       发送接收

4.       按需关闭

而根据函式提供的形式,

一般设置参数分两步进行【其实就是那么配置下,分几步都行,只是配合后面的代码了】

[1]设置波特率

[2]设置数据格式

下面还是罗列一些代码

打开串口


int OpenDev(char *Dev)
{
    
int fd = open( Dev, O_RDWR );           
    
if (-1 == fd)   
    {           
        perror(
"Can't Open Serial Port");
        
return -1;      
    }   
    
else    
        
return fd;
}

O_RDWR就是可读写的意思
设置波特率

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
                    B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  30038400,  
                    
19200,  9600480024001200,  300, };
void set_speed(int fd, int speed){
    
int   i; 
    
int   status; 
    
struct termios   Opt;
    tcgetattr(fd, 
&Opt); 
    
for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 
        
if  (speed == name_arr[i]) {     
            tcflush(fd, TCIOFLUSH);     
            cfsetispeed(
&Opt, speed_arr[i]);  
            cfsetospeed(
&Opt, speed_arr[i]);   
            status 
= tcsetattr(fd, TCSANOW, &Opt);  
            
if  (status != 0) {        
                perror(
"tcsetattr fd1");  
                
return;     
            }    
            tcflush(fd,TCIOFLUSH);   
        }  
    }
}

 

设置参数是用到了一个专用的结构体struct termios其实也没啥说的,就是通过它去配置串口参数罢了

注意tcflush,他是清空buffer用的,关于buffer这东西,里面其实挺饶,这里不多说明,只是要注意它清空的buffer并不是printf那类函式中所谓的缓冲。

另外那两个数组,其实可以弄的简单些,只不过懒得改了

有点像画刷的使用,旧的一般都爱保存起来,最后还要还原。

 

设置数据格式


int set_Parity(int fd,int databits,int stopbits,int parity)

    
struct termios options; 
    
if  ( tcgetattr( fd,&options)  !=  0) { 
        perror(
"SetupSerial 0");     
        
return -1;  
    }
    options.c_cflag 
&= ~CSIZE; 
    
switch (databits) 
    {   
    
case 7:     
        options.c_cflag 
|= CS7; 
        
break;
    
case 8:     
        options.c_cflag 
|= CS8;
        
break;   
    
default:    
        fprintf(stderr,
"Unsupported data size"n");
 
return -1;  
    }
switch (parity) 
{   
    
case 'n':
    
case 'N':    
        options.c_cflag 
&= ~PARENB;    
        options.c_iflag 
&= ~INPCK;     
        
break;  
    
case 'o':   
    
case 'O':     
        options.c_cflag 
|= (PARODD | PARENB);  
        options.c_iflag 
|= INPCK;              
        
break;  
    
case 'e':  
    
case 'E':   
        options.c_cflag 
|= PARENB;      
        options.c_cflag 
&= ~PARODD;   
        options.c_iflag 
|= INPCK;        
        
break;
    
case 'S'
    
case 's':   
        options.c_cflag 
&= ~PARENB;
        options.c_cflag 
&= ~CSTOPB;break;  
    
default:   
        fprintf(stderr,
"Unsupported parity"n");    
        
return -1;  
    }  
 
switch (stopbits)
{   
    
case 1:    
        options.c_cflag 
&= ~CSTOPB;  
        
break;  
    
case 2:    
        options.c_cflag 
|= CSTOPB;  
       
break;
    
default:    
         fprintf(stderr,
"Unsupported stop bits"n");  
         
return -1

if (parity != 'n')   
    options.c_iflag 
|= INPCK; 
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] 
= 150
options.c_cc[VMIN] 
= 0;
if (tcsetattr(fd,TCSANOW,&options) != 0)   

    perror(
"SetupSerial 3");   
    
return -1;  

return 0;  
}

 

和前面的函式不同这里直接对struct termios进行操作,进而配置了数据位长度,校验位,停止位,超时等信息

最后整合下,列出一个测试用例


#include     <stdio.h>      
#include     
<stdlib.h>     
#include     
<unistd.h>     
#include     
<sys/types.h>  
#include     
<sys/stat.h>   
#include     
<fcntl.h>      
#include     
<termios.h>  
#include     
<errno.h>      

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
                    B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  30038400,  
                    
19200,  9600480024001200,  300, };
void set_speed(int fd, int speed){
    
int   i; 
    
int   status; 
    
struct termios   Opt;
    tcgetattr(fd, 
&Opt); 
    
for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 
        
if  (speed == name_arr[i]) {     
            tcflush(fd, TCIOFLUSH);     
            cfsetispeed(
&Opt, speed_arr[i]);  
            cfsetospeed(
&Opt, speed_arr[i]);   
            status 
= tcsetattr(fd, TCSANOW, &Opt);  
            
if  (status != 0) {        
                perror(
"tcsetattr fdl");  
                
return;     
            }    
            tcflush(fd,TCIOFLUSH);   
        }  
    }
}
 
int set_Parity(int fd,int databits,int stopbits,int parity)

    
struct termios options; 
    
if  ( tcgetattr( fd,&options)  !=  0) { 
        perror(
"SetupSerial 1");     
        
return -1;  
    }
    options.c_cflag 
&= ~CSIZE; 
switch (databits)
{   
    
case 7:     
        options.c_cflag 
|= CS7; 
        
break;
    
case 8:     
        options.c_cflag 
|= CS8;
        
break;   
    
default:    
        fprintf(stderr,
"Unsupported data size"n"); return 0;  
    }
switch (parity) 
{   
    
case 'n':
    
case 'N':    
        options.c_cflag 
&= ~PARENB;   
        options.c_iflag 
&= ~INPCK;     
        
break;  
    
case 'o':   
    
case 'O':     
        options.c_cflag 
|= (PARODD | PARENB); 
        options.c_iflag 
|= INPCK;            
        
break;  
    
case 'e':  
    
case 'E':   
        options.c_cflag 
|= PARENB;     
        options.c_cflag 
&= ~PARODD;     
        options.c_iflag 
|= INPCK;             
  
break;
    
case 'S'
    
case 's':  
        options.c_cflag 
&= ~PARENB;
        options.c_cflag 
&= ~CSTOPB;break;  
    
default:   
        fprintf(stderr,
"Unsupported parity"n");    
        
return -1;  
    }  
switch (stopbits)
{   
    
case 1:    
        options.c_cflag 
&= ~CSTOPB;  
        
break;  
    
case 2:    
        options.c_cflag 
|= CSTOPB;  
       
break;
    
default:    
         fprintf(stderr,
"Unsupported stop bits"n");  
         
return -1

if (parity != 'n')   
    options.c_iflag 
|= INPCK; 
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] 
= 150;   
options.c_cc[VMIN] 
= 0
if (tcsetattr(fd,TCSANOW,&options) != 0)   

    perror(
"SetupSerial 3");   
    
return -1;  

return 0;  
}
int OpenDev(char *Dev)
{
    
int fd = open( Dev, O_RDWR );        
    
if (-1 == fd)   
    {           
        perror(
"Can't Open Serial Port");
        
return -1;      
    }   
    
else    
        
return fd;
}
int main(int argc, char **argv){
    
int fd;
    
int nread;
    
char buff[6];
    
char *dev  = "/dev/ttyS0"
    fd 
= OpenDev(dev);
    set_speed(fd,
9600);
    
if (set_Parity(fd,8,1,'N'== FALSE)  {
        printf(
"Set Parity Error"n");
        exit (
0);
    }
while (1) {   
    write(fd,
"hello",5);
    nread 
= read(fd, buff, 5);
    tcflush(fd,TCIOFLUSH);
    buff[nread
+1= '"0';   
    printf( 
"%s", buff);   
}
    
//close(fd);  
    
// exit (0);
}
这个测试将发送hello字符并接受,主要是为了测试自发自收用的
如果有串口的话,可以使用跳线帽将2,3脚端接来完成此测试
可以看到终端中不断出现hellohello……就对了!
我的是现代化的笔记本。。。。。XD怎会有串口的存在
所以整了张卡,据说比usb转接线稳定,目前还没发现稳定到哪里去,如图


原文地址:https://www.cnblogs.com/bingyun84/p/1565717.html