linux串口可以同时读和写么,Linux上用C ++编写的串口。可以在串口上读写同时发生..?...

我正在开发一个项目,需要一台Linux PC从UART上的微控制器获取数据,我已经在C ++ for Linux中使用了已经可用的串口开源代码。 (基于Ros(机器人操作系统)的代码)

代码如下:

#define DEFAULT_BAUDRATE 115200

#define DEFAULT_SERIALPORT "/dev/ttyUSB0"

//Global data

FILE *fpSerial = NULL; //serial port file pointer

ros::Publisher ucResponseMsg;

ros::Subscriber ucCommandMsg;

int ucIndex; //ucontroller index number

int FileDesc;

unsigned char crc_sum=0;

//Initialize serial port, return file descriptor

FILE *serialInit(char * port, int baud)

{

int BAUD = 0;

int fd = -1;

struct termios newtio, oldtio;

FILE *fp = NULL;

//Open the serial port as a file descriptor for low level configuration

// read/write, not controlling terminal for process,

fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);

ROS_INFO("FileDesc : %d",fd);

if ( fd<0 )

{

ROS_ERROR("serialInit: Could not open serial device %s",port);

return fp;

}

// save current serial port settings

tcgetattr(fd,&oldtio);

// clear the struct for new port settings

bzero(&newtio, sizeof(newtio));

//Look up appropriate baud rate constant

switch (baud)

{

case 38400:

default:

BAUD = B38400;

break;

case 19200:

BAUD = B19200;

break;

case 115200:

BAUD = B115200;

break;

case 9600:

BAUD = B9600;

break;

case 4800:

BAUD = B4800;

break;

case 2400:

BAUD = B2400;

break;

case 1800:

BAUD = B1800;

break;

case 1200:

BAUD = B1200;

break;

} //end of switch baud_rate

if (cfsetispeed(&newtio, BAUD) < 0 || cfsetospeed(&newtio, BAUD) < 0)

{

ROS_ERROR("serialInit: Failed to set serial baud rate: %d", baud);

close(fd);

return NULL;

}

// set baud rate, (8bit,noparity, 1 stopbit), local control, enable receiving characters.

newtio.c_cflag = BAUD | CRTSCTS | CS8 | CLOCAL | CREAD;

// ignore bytes with parity errors

newtio.c_iflag = IGNPAR;

// raw output

newtio.c_oflag = 0;

// set input mode to non - canonical

newtio.c_lflag = 0;

// inter-charcter timer

newtio.c_cc[VTIME] = 0;

// blocking read (blocks the read until the no.of charcters are read

newtio.c_cc[VMIN] = 0;

// clean the line and activate the settings for the port

tcflush(fd, TCIFLUSH);

tcsetattr (fd, TCSANOW,&newtio);

//Open file as a standard I/O stream

fp = fdopen(fd, "r+");

if (!fp) {

ROS_ERROR("serialInit: Failed to open serial stream %s", port);

fp = NULL;

}

ROS_INFO("FileStandard I/O stream: %d",fp);

return fp;

} //serialInit

//Process ROS command message, send to uController

void ucCommandCallback(const geometry_msgs::TwistConstPtr& cmd_vel)

{

unsigned char msg[14];

float test1,test2;

unsigned long i;

// build the message packet to be sent

msg = packet to be sent;

msg[13] = crc_sum;

for (i=0;i<14;i++)

{

fprintf(fpSerial, "%c", msg[i]);

}

tcflush(FileDesc, TCOFLUSH);

} //ucCommandCallback

//Receive command responses from robot uController

//and publish as a ROS message

void *rcvThread(void *arg)

{

int rcvBufSize = 200;

char ucResponse[10];//[rcvBufSize]; //response string from uController

char *bufPos;

std_msgs::String msg;

std::stringstream ss;

int BufPos,i;

unsigned char crc_rx_sum =0;

while (ros::ok()) {

BufPos = fread((void*)ucResponse,1,10,fpSerial);

for (i=0;i<10;i++)

{

ROS_INFO("T: %x ",(unsigned char)ucResponse[i]);

ROS_INFO("NT: %x ",ucResponse[i]);

}

msg.data = ucResponse;

ucResponseMsg.publish(msg);

}

return NULL;

} //rcvThread

int main(int argc, char **argv)

{

char port[20]; //port name

int baud; //baud rate

char topicSubscribe[20];

char topicPublish[20];

pthread_t rcvThrID; //receive thread ID

int err;

//Initialize ROS

ros::init(argc, argv, "r2SerialDriver");

ros::NodeHandle rosNode;

ROS_INFO("r2Serial starting");

//Open and initialize the serial port to the uController

if (argc > 1) {

if(sscanf(argv[1],"%d", &ucIndex)==1) {

sprintf(topicSubscribe, "uc%dCommand",ucIndex);

sprintf(topicPublish, "uc%dResponse",ucIndex);

}

else {

ROS_ERROR("ucontroller index parameter invalid");

return 1;

}

}

else {

strcpy(topicSubscribe, "uc0Command");

strcpy(topicPublish, "uc0Response");

}

strcpy(port, DEFAULT_SERIALPORT);

if (argc > 2)

strcpy(port, argv[2]);

baud = DEFAULT_BAUDRATE;

if (argc > 3) {

if(sscanf(argv[3],"%d", &baud)!=1) {

ROS_ERROR("ucontroller baud rate parameter invalid");

return 1;

}

}

ROS_INFO("connection initializing (%s) at %d baud", port, baud);

fpSerial = serialInit(port, baud);

if (!fpSerial )

{

ROS_ERROR("unable to create a new serial port");

return 1;

}

ROS_INFO("serial connection successful");

//Subscribe to ROS messages

ucCommandMsg = rosNode.subscribe("cmd_vel" /*topicSubscribe*/, 100, ucCommandCallback);

//Setup to publish ROS messages

ucResponseMsg = rosNode.advertise<:string>(topicPublish, 100);

//Create receive thread

err = pthread_create(&rcvThrID, NULL, rcvThread, NULL);

if (err != 0) {

ROS_ERROR("unable to create receive thread");

return 1;

}

//Process ROS messages and send serial commands to uController

ros::spin();

fclose(fpSerial);

ROS_INFO("r2Serial stopping");

return 0;

}

您可以将ROS部分放在一边,但问题出在串口代码上。

当我运行此代码时,我正确地从控制器接收数据,但即使控制器停止发送数据,我也会看到printf上连续出现的相同数据。这是不刷新输入缓冲区的问题吗?

但我无法将数据从Linux PC发送到控制器,不知道发生了什么,可以在linux的串口上同时读写吗?

奇怪的是,当我用H-term打开端口(类似于超级终端的uART可视化器),我的串口代码在后端运行时,H-term仍然没有给出任何错误,但理想情况下,H-term应该给出一个错误说&#34;端口无法打开它被锁定&#34;,但这没有发生,我的代码是不是在串口上锁定了? / p>

当我使用H-term连接端口并运行mu串口代码时,我可以看到UART上的数据从linux-PC到微控制器?

任何人都可以对我在这里遇到的问题有任何见解吗?

提前致谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值