串口配置的参数包括:波特率,数据位,校验位,停止位与流控。
串口的配置主要是通过配置struct termios结构体,其原型如下:
#include<termios.h>
struct termio
{
unsigned short c_iflag; /*输入模式标志*/
unsigned short c_oflag; /*输出模式标志*/
unsigned short c_cflag; /*控制模式标志*/
unsigned short c_lfag; /*本地模式标志*/
unsigned short c_line; /*line discipline*/
unsigned short c_cc[NCC]; /*control characters*/
};
其中,通过对
c_cflag与c_iflag的赋值,可以设置波特率、数据位、奇偶校验位、停止位、流控。
1、波特率配置
串口通过函数cfsetispeed和cfsetospeed设置端口的输入/输出波特率:
int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);
其中termios_p为串口接头体termios指针变量;speed为需要设置的串口传输速率,取值与波特率对应关系见表:
宏 定 义 | 波特率(单位:bit/s) | 宏 定 义 | 波特率(单位:bit/s) |
B0 | 0 | B1800 | 1800 |
B50 | 50 | B2400 | 2400 |
B75 | 75 | B4800 | 4800 |
B110 | 110 | B9600 | 9600 |
B134 | 134 | B19200 | 19200 |
B150 | 150 | B38400 | 38400 |
B200 | 200 | B57600 | 57600 |
B300 | 300 | B115200 | 115200 |
B600 | 600 | B230400 | 230400 |
B1200 | 1200 |
|
|
2、数据位配置
串口数据位的配置通过修改termios结构体成员c_cflag实现,CS5、CS6、CS7和CS8分别表示数据位为5、6、7和8。在设置数据位前,先使用CSIZE做位屏蔽:
termios_p.c_cflag &= ~CSIZE;
termios_p.c_cflag |= CS5; /*配置为5数据位*/
3、校验位配置
校验位包括:无校验、奇校验、偶校验、空格等:
无校验:
termios_p.c_cflag &= ~PARENB;
termios_p.c_iflag &= ~INPCK;
奇校验:
termios_p.c_cflag &= (PARODD | PARENB);
termios_p.c_iflag &= INPCK;
偶校验:
termios_p.c_cflag |= PARENB;
termios_p.c_cflag ~PARODD;
termios_p.c_iflag & |= INPCK;
空格:
termios_p.c_cflag &= ~PARENB;
termios_p.c_cflag &= ~CSTOPB;
termios_p.c_iflag |= INPCK;
4、停止位配置
串口停止位通过激活c_cflag的CSTOPB控制,具体方法如下:
1个停止位:
termios_p.c_cflag &= ~CSTOPB;
2个停止位:
termios_p.c_cflag |= CSTOPB;
5、流控配置
流控用于标识数据的开始与结束,流控的种类包括硬件流、软件流与不使用流控。
不使用流控:
termios_p.c_cflag &= ~CRTSCTS;
硬件流:
termios_p.c_cflag |= CRTSCTS;
软件流:
termios_p.c_cfalg |= IXON | IXOFF | IXANY;
例子程序:
程序实现了配置串口0参数与向串口0输出数据
#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>
#include <asm/ioctl.h>
void Set_uart(int fd, int databits, int stopbit, char parity, char datastream)
{
int ret;
struct termios termios_opt;
if(tcgetattr(fd, &termios_opt))
{
perror("tcgetattr error\n");
return;
}
/*flush memory*/
tcflush(fd,TCIOFLUSH);
/*Set i/o speed*/
cfsetispeed(&termios_opt, B115200);
cfsetospeed(&termios_opt, B115200);
/*active options*/
termios_opt.c_cflag |= CLOCAL | CREAD;
/*set databits,default is 8 databits*/
termios_opt.c_cflag &= ~CSIZE;
switch (databits)
{
case 5:
termios_opt.c_cflag |= CS5;
break;
case 6:
termios_opt.c_cflag |= CS6;
break;
case 7:
termios_opt.c_cflag |= CS7;
break;
case 8:
termios_opt.c_cflag |= CS8;
break;
default:
termios_opt.c_cflag |= CS8;
break;
}
/*Set Parity, default is no vertify*/
switch (parity)
{
case 'N': /*no vertify*/
termios_opt.c_cflag &= ~PARENB;
termios_opt.c_iflag &= ~INPCK;
break;
case 'O': /*odd vertify*/
termios_opt.c_cflag |= (PARODD | PARENB);
termios_opt.c_iflag |= INPCK;
break;
case 'E': /*even vertify*/
termios_opt.c_cflag |= PARENB;
termios_opt.c_cflag &= ~PARODD;
termios_opt.c_iflag |= INPCK;
break;
case 'S': /*space vertify*/
termios_opt.c_cflag &= ~PARENB;
termios_opt.c_cflag &= ~CSTOPB;
termios_opt.c_iflag |= INPCK;
break;
default:
termios_opt.c_cflag &= ~PARENB;
termios_opt.c_iflag &= ~INPCK;
break;
}
/*Set stop bits, default is 1 stopbit*/
switch (stopbit)
{
case 1:
termios_opt.c_cflag &= ~CSTOPB;
break;
case 2:
termios_opt.c_cflag |= CSTOPB;
break;
default:
termios_opt.c_cflag &= ~CSTOPB;
break;
}
/*set data stream,default is no data stream control*/
switch (datastream)
{
case 'N': /*no data stream control*/
termios_opt.c_cflag &= ~CRTSCTS;
break;
case 'H': /*hardware data stream control*/
termios_opt.c_cflag |= CRTSCTS;
break;
case 'S': /*software data stream control*/
termios_opt.c_cflag |= IXON | IXOFF | IXANY;
break;
default:
termios_opt.c_cflag &= ~CRTSCTS;
break;
}
/*oput modle,initial data output*/
termios_opt.c_oflag &= ~OPOST;
/*set waiting time and recv min character*/
termios_opt.c_cc[VTIME] = 0;
termios_opt.c_cc[VMIN] = 0;
/*flush memory*/
tcflush(fd,TCIFLUSH);
/*start using new options*/
if((tcsetattr(fd,TCSANOW,&termios_opt)) != 0)
{
perror("serial setup error\n");
return;
}
printf("set serial done!\n");
return ;
}
int main(void)
{
int serial_fd;
unsigned char data[14] = {0};
memset(data,'a',sizeof(data));
printf("open UART..\n");
serial_fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NONBLOCK);
if (serial_fd == -1)
{
perror("Serial open error!\n");
return -1;
}
/*Set uart*/
Set_uart(serial_fd, 8, 1, 'N', 'N'); //8 databits, 1 stopbit, No vertify, No data stream control
while(1)
{
write(serial_fd, data, sizeof(data));
tcdrain(serial_fd);
sleep(2);
}
close(serial_fd);
return 0;
}