C 使用超级终端启动串行通信的USB端口

C 使用超级终端启动串行通信的USB端口,c,serial-port,libusb,usbserial,C,Serial Port,Libusb,Usbserial,我正在尝试从下面的代码启动串行通信。但问题是,我必须用相同的设置打开超级终端,然后关闭它,然后在另一个用C编写的程序中运行下面的代码,以使代码按预期工作。我非常想跳过超级终端的初始步骤,但我一直无法找出是什么导致了这种奇怪的行为。 我已经发布了下面启动的代码以及kbhit()的代码,这可能是导致这种行为的原因。如果有人能告诉我如何解决这个问题,我将不胜感激 int kbhit(){ //Detects if a key has been pressed, 1 if true else 0

我正在尝试从下面的代码启动串行通信。但问题是,我必须用相同的设置打开超级终端,然后关闭它,然后在另一个用C编写的程序中运行下面的代码,以使代码按预期工作。我非常想跳过超级终端的初始步骤,但我一直无法找出是什么导致了这种奇怪的行为。 我已经发布了下面启动的代码以及kbhit()的代码,这可能是导致这种行为的原因。如果有人能告诉我如何解决这个问题,我将不胜感激

int kbhit(){ //Detects if a key has been pressed, 1 if true else 0 
  struct termios oldt, newt;
  int ch;
  int oldf;
  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0;
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
  ch = getchar();
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF){
    ungetc(ch, stdin); //Puts back the pressed key to the stack
    return 1;
  }
  return 0;
}  

通过USB端口进行串行通信的启动代码如下所示:

#include "USB.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
/* baudrate settings are defined in <asm/termbits.h>, which is
 * included by <termios.h> */
#ifndef BAUDRATE
#define BAUDRATE B9600  //the desired baud rate
#endif
#define _POSIX_SOURCE 1     /* POSIX compliant source */
static int fd, c, res;
static struct termios oldtio, newtio;
static char *device;
int USB_init(char *modemdevice){
    device = modemdevice;
    fd = open (device, O_RDWR | O_NOCTTY|O_NONBLOCK );//|O_NONBLOCK has been added
    if (fd < 0){
      perror (device);
      exit(-1);
    }
    tcgetattr (fd, &oldtio);    /* save current settings */
    bzero (&newtio, sizeof (newtio));   /* clear struct for new port settings */
    /* 
     *BAUDRATE: Set bps rate. 
     *CS8     : 8n1 (8bit,no parity,1 stop bit)
     *CLOCAL  : local connection, no modem contol
     *CREAD   : enable receiving characters
     **/
    newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    /*
     * ICANON  : enable canonical input
     *           disable all echo functionality, and don't send signals to calling program*/
#if 1
    newtio.c_lflag = ICANON;
#else
    newtio.c_lflag = 0;
#endif 
     /* initialize all control characters 
     * default values can be found in /usr/include/termios.h, and are given
     * in the comments, but we don't need them here*/
    newtio.c_cc[VINTR] = 0; /* Ctrl-c */
    newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
    newtio.c_cc[VERASE] = 0;    /* del */
    newtio.c_cc[VKILL] = 0; /* @ */
    newtio.c_cc[VEOF] = 4;  /* Ctrl-d */
    newtio.c_cc[VTIME] = 10; // 0 before
    newtio.c_cc[VMIN] = 0;  /* blocking read until 0 character arrives*/
    newtio.c_cc[VSWTC] = 0; /* '\0' */
    newtio.c_cc[VSTART] = 0;    /* Ctrl-q */
    newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
    newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
    newtio.c_cc[VEOL] = 0;  /* '\0' */
    newtio.c_cc[VREPRINT] = 0;  /* Ctrl-r */
    newtio.c_cc[VDISCARD] = 0;  /* Ctrl-u */
    newtio.c_cc[VWERASE] = 0;   /* Ctrl-w */
    newtio.c_cc[VLNEXT] = 0;    /* Ctrl-v */
    newtio.c_cc[VEOL2] = 0; /* '\0' */
    tcflush (fd, TCIFLUSH);
    tcsetattr (fd, TCSANOW, &newtio);
    return fd;
}

void USB_cleanup(int ifd){
    if(ifd != fd){
        fprintf(stderr, "WARNING! file descriptor != the one returned by USB_init()\n");
    }
    /* restore the old port settings */
    tcsetattr (ifd, TCSANOW, &oldtio);
}
#包括“USB.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*波特率设置在中定义,即
*包括在*/
#ifndef波特率
#定义波特率B9600//所需的波特率
#恩迪夫
#定义_POSIX_SOURCE 1/*兼容POSIX的源*/
静态int-fd、c、res;
静态结构术语oldtio、newtio;
静态字符*设备;
int USB_init(字符*调制解调器设备){
设备=调制解调器设备;
fd=打开(已添加设备,O|RDWR | O|NOCTTY | O|U非块);//O|U非块
如果(fd<0){
perror(装置);
出口(-1);
}
tcgetattr(fd,&oldtio);/*保存当前设置*/
bzero(&newtio,sizeof(newtio));/*清除新端口设置的结构*/
/* 
*波特率:设置bps速率。
*CS8:8n1(8位,无奇偶校验,1个停止位)
*CLOCAL:本地连接,无调制解调器控制
*CREAD:启用接收字符
**/
newtio.c|cflag=波特率| CS8 | CLOCAL | CREAD;
newtio.c_iflag=IGNPAR | ICRNL;
/*
*ICANON:启用规范输入
*禁用所有回显功能,不向呼叫程序发送信号*/
#如果1
newtio.c_lflag=ICANON;
#否则
newtio.c_lflag=0;
#恩迪夫
/*初始化所有控制字符
*默认值可以在/usr/include/termios.h中找到,并给出了
*在评论中,但我们这里不需要它们*/
newtio.c_cc[VINTR]=0;/*Ctrl-c*/
newtio.c_cc[VQUIT]=0;/*Ctrl-\*/
newtio.c_cc[VERASE]=0;/*del*/
newtio.c_cc[VKILL]=0;/*@*/
newtio.c_cc[VEOF]=4;/*Ctrl-d*/
newtio.c_cc[VTIME]=10;//0之前
newtio.c_cc[VMIN]=0;/*在到达0个字符之前阻止读取*/
newtio.c_cc[VSWTC]=0;/*'\0'*/
newtio.c_cc[VSTART]=0;/*Ctrl-q*/
newtio.c_cc[VSTOP]=0;/*Ctrl-s*/
newtio.c_cc[VSUSP]=0;/*Ctrl-z*/
newtio.c_cc[VEOL]=0;/*'\0'*/
newtio.c_cc[vreprit]=0;/*Ctrl-r*/
newtio.c_cc[VDISCARD]=0;/*Ctrl-u*/
newtio.c_cc[vwrase]=0;/*Ctrl-w*/
newtio.c_cc[VLNEXT]=0;/*Ctrl-v*/
newtio.c_cc[VEOL2]=0;/*'\0'*/
tcflush(fd,TCIFLUSH);
tcsetattr(fd、TCSANOW和newtio);
返回fd;
}
无效USB_清理(int ifd){
如果(ifd!=fd){
fprintf(stderr,“警告!文件描述符!=USB_init()\n返回的文件描述符”);
}
/*恢复旧的端口设置*/
tcsetattr(ifd、TCSANOW和oldtio);
}
“通过USB端口进行串行通信”——如果您使用的是USB-to-RS232适配器(或模拟串行端口设备的USB小工具),那么涉及到的USBus对应用程序来说是完全透明的。因此,当函数与USB无关时,将它们命名为USB_init()和USB_cleanup(),会产生误导
bzero(&newtio,sizeof(newtio))
是初始化termios结构的常见但错误的方法。学习也是学习。不要使用来自中国的坏例子