1.串口配置
串口的配置主要是设置struct termios 结构体的各成员值,如下所示:
#include<termios.h>
struct termios
{
unsigned short c_iflag; //输入模式标志
unsigned short c_oflag; //输出模式标志
unsigned short c_cflag; //控制模式标志
unsigned short c_lflag; //本底模式标志
unsigned char c__line; //线路规程
unsigned char c_cc[NCC]; //控制特性
speed_t c_ispeed; //输入速度
speed_t c_ospeed; //输出速度
}
termios是在Posix规范重定义的标准接口,表示终端设备,因为串口是一种终端设备,所以通过终端编程接口对其进行配置和控制。
2.下边详细说明串口属性的基本流程
2.1保存原先串口配置
if(tcgetattr(fd,&old_cfg) != 0)
{
perror("tcgetattr");
return -1;
}
2.2激活选项
CLOCAL和CREAD分别用于本地连接和接收使能。
newtio.c_cflag |= CLOCAL | CREAD;
调用cfmakeraw()函数将终端设置为原始模式
cfmakeraw(&new_cfg);
2.3.设置波特率
用专门的函数设置终端的输入和输出波特率为一样的
cfsetispeed(&new_cfg,B115200);
cfsetospeed(&new_cfg,B115200);
2.4设置字符大小
new_cfg.c_cflag &= ~CSIZE;
new_cfg.c_cflag |= CS8;
2.5设置奇偶校验位
奇校验
new_cfg.c_cflag |= (PARODD | PARENB);
new_cfg.c_iflag |= INPCK;
偶校验
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD;
new_cfg.c_cflag |= INPCK;
2.6 设置停止位
new_cfg.c_cflag &= ~CSTOPB;
new_cfg.c_cflag |= CSTOPB;
2.7.设置最少字符和等待时间
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 0;
2.8清除串口缓冲
int tcdrain(int fd); //使程序阻塞,直到输出缓冲区的数据全部发送完毕
int tcflow(int fd,int action); //用于暂停或重新开始输出
int tcflush(int fd,int queue_selector); //用于清空输入/输出缓冲区
2.9激活配置
tcsetattr(int fd,int optional_actions,const struct termios *termios_p);
3.代码
3.1 串口配置封装函数
int set_com_config(int fd, int baud_rate,int data_bits,char parity,int stop_bits)
{
struct termios new_cfg,old_cfg;
int speed;
//保存并测试现有串口参数配置,在这里如果串口号等出错,会有相关提示信息
if(tcgetattr(fd,&old_cfg) != 0)
{
perror("tcgetattr");
return -1;
}
new_cfg = old_cfg;
cfmakeraw(&new_cfg); //配置为原始模式
new_cfg.c_cflag &= ~CSIZE;
//设置波特率
switch(baud_rate)
{
case 2400:
speed = B2400;
break;
case 4800:
speed = B4800;
break;
case 9600:
speed = B9600;
break;
case 19200:
speed = B19200;
break;
case 38400:
speed = B38400;
break;
case 115200:
speed = B115200;
break;
default:
break;
}
cfsetispeed(&new_cfg,speed);
cfsetospeed(&new_cfg,speed);
switch(data_bits) //设置数据位
{
case 7:
new_cfg.c_cflag |= CS7;
break;
case 8:
new_cfg.c_cflag |= CS8;
break;
default:
break;
}
switch(parity) // 设置奇偶校验位
{
case 'n':
case 'N':
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
new_cfg.c_cflag |= PARODD | PARENB;
new_cfg.c_iflag |= INPCK;
break;
case 'e':
case 'E':
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~ PARODD;
new_cfg.c_iflag |= INPCK;
break;
case 's':
case 'S':
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_cflag |= ~CSTOPB;
break;
default:
break;
}
switch(stop_bits)
{
case 1:
new_cfg.c_cflag &= ~CSTOPB;
break;
case 2:
new_cfg.c_cflag |= CSTOPB;
break;
default:
break;
}
//设置等待时间和最小接收字符
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 1;
tcflush(fd,TCIFLUSH); //清除接收到而未处理的字符
if((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
{
perror("tcsetattr");
return -1;
}
return 0;
}
3.2打开串口封装函数
int open_port(int com_port)
{
int fd;
char *dev[] = {"/dev/ttyS0","/dev/ttyS1","ttyS2"};
if((com_port < 0) || (com_port > MAX_COM_NUM))
{
return -1;
}
//打开串口
fd = open(dev[com_port -1],O_RDWR | O_NOCTTY | O_NDELAY);
if(fd < 0)
{
return -1;
}
if(fcntl(fd, F_SETFL, 0) < 0)
{
perror("fcntl F_SETFL\n");
}
if(isatty(fd) == 0) //测试打开的文件是否为终端设备
{
perror(" This is not a terminal device");
}
return fd;
}
3.3写串口的程序
#include <stdio.h>
#include <stdlib.h>
#inlcude <string.h>
#inlcude <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
int main(void)
{
int fd;
char buff[BUFFER_SIZE];
if(fd == open_port(HOST_COM_PORT) < 0) //打开串口
{
perror("open_port");
return -1;
}
if(set_com_config(fd, 115200, 8, 'N', 1) < 0) //配置串口
{
perror("set_com_config");
return -1;
}
do
{
printf("Input some words(enter 'quit' to exit):");
memset(buff, 0, BUFFER_SIZE);
if(fgets(buff,BUFFER_SIZE, stdin) == NULL)
{
perror("fgets");
break;
}
write(fd, buff, strlen(buff));
}while(strncmp(buff, "quit",4));
close(fd);
return 0;
}
3.4读串口的程序
#include <stdio.h>
#include <stdlib.h>
#inlcude <string.h>
#inlcude <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
int main(void)
{
int fd;
char buff[BUFFER_SIZE];
if(fd == open_port(HOST_COM_PORT) < 0) //打开串口
{
perror("open_port");
return -1;
}
if(set_com_config(fd, 115200, 8, 'N', 1) < 0) //配置串口
{
perror("set_com_config");
return -1;
}
do
{
printf("Input some words(enter 'quit' to exit):");
memset(buff, 0, BUFFER_SIZE);
if(read(fd, buff,BUFFER_SIZE) > 0)
{
printf("The received words are : %s",buff);
}
write(fd, buff, strlen(buff));
}while(strncmp(buff, "quit",4));
close(fd);
return 0;
}