#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<linux/serial.h>
#include<asm-generic/ioctls.h>
#include<sys/ioctl.h>
#include<unistd.h>
#include<errno.h>
#include<sys/stat.h>
#include<getopt.h>
struct termios newtio, oldtio;
int set_com_opt( int fd, int nspeed, int nbits, char parity, int nstop )
{
char szTmp[128];
//打印配置信息
sprintf( szTmp, "set_com_opt - speed:%d,bits:%d,parity:%c,stop:%d\n",
nspeed, nbits, parity, nstop );
// log_out( "./485.log", szTmp );
//保存并测试现在有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
if( tcgetattr( fd, &oldtio ) != 0 )
{
sprintf( szTmp, "SetupSerial 1" );
// log_out( "./485.log", szTmp );
perror( "SetupSerial 1" );
return -1;
}
//修改输出模式,原始数据输出
bzero( &newtio, sizeof( newtio ));
newtio.c_cflag &=~(OPOST);
//屏蔽其他标志位
newtio.c_cflag |= (CLOCAL | CREAD );
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= IXON | IXOFF | IXANY;
//设置数据位
switch( nbits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
default:
perror("Unsupported date bit!\n");
return -1;
}
//设置校验位
switch( parity )
{
case 'n':
case 'N': //无奇偶校验位
newtio.c_cflag &= ~PARENB;
newtio.c_iflag &= ~INPCK;
break;
case 'o':
case 'O': //设置为奇校验
newtio.c_cflag |= ( PARODD | PARENB );
newtio.c_iflag |= ( INPCK | ISTRIP );
break;
case 'e':
case 'E': //设置为偶校验
newtio.c_iflag |= ( INPCK |ISTRIP );
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
default:
perror("unsupported parity\n");
return -1;
}
//设置停止位
switch( nstop )
{
case 1:
newtio.c_cflag &= ~CSTOPB;
break;
case 2:
newtio.c_cflag |= CSTOPB;
break;
default :
perror("Unsupported stop bit\n");
return -1;
}
//设置波特率
switch( nspeed )
{
case 2400:
cfsetispeed( &newtio, B2400 );
cfsetospeed( &newtio, B2400 );
break;
case 4800:
cfsetispeed( &newtio, B4800 );
cfsetospeed( &newtio, B4800 );
break;
case 9600:
cfsetispeed( &newtio, B9600 );
cfsetospeed( &newtio, B9600 );
break;
case 115200:
cfsetispeed( &newtio, B115200 );
cfsetospeed( &newtio, B115200 );
break;
case 460800:
cfsetispeed( &newtio, B460800 );
cfsetospeed( &newtio, B460800 );
break;
default:
cfsetispeed( &newtio, B9600 );
cfsetospeed( &newtio, B9600 );
break;
}
//设置等待时间和最小接收字符
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
//VTIME=0,VMIN=0,不管能否读取到数据,read都会立即返回。
//输入模式
newtio.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
//设置数据流控制
newtio.c_iflag &= ~(IXON|IXOFF|IXANY); //使用软件流控制
//如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读
tcflush( fd, TCIFLUSH );
//激活配置 (将修改后的termios数据设置到串口中)
if( tcsetattr( fd, TCSANOW, &newtio ) != 0 )
{
sprintf( szTmp, "serial set error!\n" );
// log_out( "./485.log", szTmp );
perror( "serial set error!" );
return -1;
}
// log_out( "./485.log", "serial set ok!\n" );
return 1;
}
int UART0_Open(char* port)
{
int fd;
fd = open( port, O_RDWR|O_NOCTTY|O_NDELAY);
if (fd<=0)
{
perror("Can't Open Serial Port");
return(-1);
}
//判断串口的状态是否为阻塞状态
if(fcntl(fd, F_SETFL, 0) < 0)
{
printf("fcntl failed!/n");
return(-1);
}
else
{
printf("fcntl=%d/n",fcntl(fd, F_SETFL,0));
}
//测试是否为终端设备
if(0 == isatty(STDIN_FILENO))
{
printf("standard input is not a terminal device/n");
return(-1);
}
else
{
printf("isatty success!/n");
}
printf("fd->open=%d/n",fd);
return fd;
}
int main(int argc,char *argv[])
{
int fd;
int nread;
int i;
char read_buf[128];
char write_buf[] = "123456";
fd = fd = open("/dev/ttyS4",O_RDWR);//打开RS485串行线
if(fd<0)
{
printf("open serial error\n");
return -1;
}
set_com_opt(fd,115200,8,'n',1);
// set_speed(fd,115200);
struct serial_rs485 rs485conf={0};
//ioctl(fd,TIOCGRS485,&rs485conf);
//485控制信号
rs485conf.flags |= SER_RS485_ENABLED; //485使能
rs485conf.flags |=SER_RS485_RTS_ON_SEND; //RTS = 1 发送
rs485conf.flags |=SER_RS485_RTS_AFTER_SEND; //发完包数据后,将RTS拉到1
// rs485conf.flags |=SER_RS485_RX_DURING_TX;
if(ioctl(fd, TIOCSRS485, &rs485conf)) //设置RS485参数
{
printf("set rs485 param error\n");
printf("%d\n",errno);
close(fd);
return -1;
}
#if 0
write(fd,"111111\n",7);
#else
while(1){
/* if new data is available on the serial port, read and print it out */
// write(fd,"111111\n",7);
nread = read(fd ,read_buf ,sizeof(read_buf));
//write(fd,"qweras",6);
if (nread > 0){
printf("RECV[%3d]: ", nread);
printf("read data = %s\n",read_buf);
write(fd,read_buf,nread);
}
tcflush(fd,TCIOFLUSH);
}
#endif
close(fd);
return 0;
}
485串口的测试demo代码
最新推荐文章于 2023-12-22 19:00:00 发布