从Linux和OSX上的串口读取

时间:2014-01-09 11:38:45

标签: c macos android-ndk serial-port

我正在编写简单的CLI应用程序,用于从串口读取数据。我有 CP2102 的USB到串口转换器,每隔几秒钟,我收到200 B长串。

编辑:我犯了一个错误。它不是 CP2102 ,而是 Profilic PL2303 。当我使用stty时,我也发现了奇怪的行为 - 我无法改变波特率并随意改变:

$ stty -F /dev/ttyUSB5 57600 # Set baudrate
$ stty -F /dev/ttyUSB5 # Read configuration
speed 1200 baud;
.....
$$ stty -F /dev/ttyUSB5 # Read configuration
speed 9600 baud;
.....

结束修改

当我在Mac OS X下编译我的应用程序时,它没有任何问题。但是当我编译这个代码用于Linux(使用ARM CPU的廉价Android平板电脑,我使用Android NDK进行编译)时,我会收到一些数据,然后是垃圾:

~|?>?lq?43??d??2~??O?$?$??c??Hello World, good data.
???5??l??!???????x?????????????fx???~????????????x??????`???????~???f?x???~????`f??f???~?????x??????#ף???????x?????????????fx???~????????????x??????`???????~???f?x???~????`f??f???~??3?

看起来我设置了错误的波特率,但我100%确定波特率是57600波特。

我的代码中存在问题(POSIX,Unix,Linux等的差异)还是应该在硬件中寻找问题(CP2102等)?

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>     // string function definitions
#include <errno.h>      // Error number definitions
#include <unistd.h>     // UNIX standard function definitions
#include <fcntl.h>      // File control definitions
#include <termios.h>    // POSIX terminal control definitions

int main(int argc, char *argv[]) {
  printf("Opening device... ");
  int USB = open("/dev/ttyUSB5", O_RDONLY | O_NOCTTY | O_NONBLOCK);
  printf("opened.\n");

  struct termios tty;
  struct termios tty_old;
  memset (&tty, 0, sizeof tty);

  /* Error Handling */
  if (tcgetattr(USB, &tty) != 0) {
    printf("Error %d from tcgetattr: %s!\n", errno, strerror(errno));
  }

  /* Save old tty parameters */
  tty_old = tty;

  /* Set Baud Rate */
  cfsetospeed (&tty, (speed_t)B57600);
  cfsetispeed (&tty, (speed_t)B57600);

  /* Setting other Port Stuff */
  tty.c_cflag     &=  ~PARENB;        // Make 8n1
  tty.c_cflag     &=  ~CSTOPB;
  tty.c_cflag     &=  ~CSIZE;
  tty.c_cflag     |=  CS8;

  tty.c_cflag     &=  ~CRTSCTS;       // no flow control
  tty.c_cc[VMIN]  =   1;
  tty.c_cc[VTIME] =   5;
  tty.c_cflag     |=  CREAD | CLOCAL; // turn on READ & ignore ctrl lines

  /* Make raw */
  cfmakeraw(&tty);

  /* Flush Port, then applies attributes */
  tcflush(USB, TCIFLUSH);
  if ( tcsetattr ( USB, TCSANOW, &tty ) != 0) {
    printf("Error %d from tcgetattr: %s!\n", errno, strerror(errno));
  }

  int n = 0;
  char buf [256];

  printf("Starting to read data...\n");
  do {
    n = read( USB, &buf, sizeof buf);

    if (n > 0) {
      printf("%s", buf);
      memset(&buf, '\0', sizeof buf);
    }

    usleep(100000);  /* sleep for 100 milliSeconds */
  } while(1);
}

0 个答案:

没有答案