我试图在我的程序中在Ubuntu 14.04中设置半双工通信。我的RS485收发器使用RTS线在发送和接收之间来回切换。我在与系统交谈时使用说话,这个程序是主人。问题是当我完成发送包时,RTS没有切换回来,所以我可以接收数据。基本上我希望它将RTS变为高电平,发送数据,将RTS变为低电平,然后读取数据。任何帮助都会很棒。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/types.h>
#define BAUDRATE B38400
#define COMPORT "/dev/ttyUSB0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1
#define STX_KEYPAD 0xE1
#define PAYLOAD_BUFF_SIZE 256
#define CRC_HI 0xD8
#define CRC_LOW 0xC3
volatile int STOP=FALSE;
int ser_port;
int bus_address = 1;
int message_length = 0;
struct termios oldtio,newtio;
unsigned char rxbuf[256];
unsigned char tx_flags = 0;
void openCommPort();
void sendSerial();
int setRTS(int level);
int main(void)
{
printf("Starting...\r\n");
openCommPort();
setRTS(1);
printf("Sending Serial Data\r\n");
sendSerial();
setRTS(0);
//close(ser_port);
printf("All Done\r\n");
return EXIT_SUCCESS;
}
void openCommPort()
{
ser_port = open(COMPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (ser_port == -1)
{
perror(COMPORT);
perror("Unable to open port");
exit(-1);
}
if(tcgetattr(ser_port,&oldtio) <0)// save current port settings
{
perror(COMPORT);
perror("Couldn't get old terminal attributes");
exit (-1);
}
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
newtio.c_iflag = IGNPAR | ICANON;
newtio.c_oflag = 0;
// set input mode (non-C, no echo,...)
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0; // inter-character timer unused
newtio.c_cc[VMIN] = 0; // blocking read until 5 chars received
tcflush(ser_port, TCIFLUSH);
tcsetattr(ser_port,TCSANOW,&newtio);
}
void sendSerial()
{
unsigned char tx_header[6];
tx_header[0] = STX_KEYPAD;
tx_header[1] = bus_address;
tx_header[2] = tx_flags;
tx_header[3] = message_length;
tx_header[4] = CRC_HI;
tx_header[5] = CRC_LOW;
if((write(ser_port, tx_header, 6)) != 6)
{
printf("Error sending data! Not all bytes sent\r\n");
}
}
int setRTS(int level)
{
int status;
if (ioctl(ser_port, TIOCMGET, &status) == -1)
{
perror("getRTS(): TIOCMSET");
return 0;
}
if(level)
{
status |= TIOCM_RTS;
}
else
{
status &= ~TIOCM_RTS;
}
if (ioctl(ser_port, TIOCMSET, &status) == -1)
{
perror("setRTS(): TIOCMSET");
return 0;
}
return 1;
}