2013-03-03 46 views
1

我想控制串行端口上的RTS線來喚醒設備。這裏有一些粗略的測試代碼來打開串口。我需要將RTS線路設置爲低電平500ms。我無法通過Google /瞭解如何控制這些行。任何提示?如何設置和清除串口的RTS線。 C++ POSIX

編輯:或者控制CTS/DTR,除了Tx/Rx線之外的任何其他線路連接到機器人的一個引腳。

#include <iostream> 
#include <string.h> 
#include <cstdio> 
#include <fstream> 

#include <sys/types.h> 
#include <pthread.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <signal.h> 
#include <stdint.h> /* Standard types */ 
#include <fcntl.h> /* File control definitions */ 
#include <errno.h> /* Error number definitions */ 
#include <termios.h> /* POSIX terminal control definitions */ 
#include <sys/ioctl.h> 
#include <getopt.h> 



using namespace std; 

int fd_global; 
FILE* fp_global; 
int serialport_init(const char* serialport, int baud); 
int serialport_read_until(int fd); 
int fpeek(FILE* stream); 
bool fexists(const char *filename); 


void* screen_thread(void* arg) { 
    while(1) { 
    } 
} 



int main(void) { 

    pthread_t screen_thread_id; 
    int flags; 
    int baudrate = B9600; // default 
    fd_global = serialport_init((char*)"/dev/ttyUSB0", baudrate); 
    if(fd_global==-1) { 
     cout << "Open port: error\n"; 
     return -1; 
    } 

    fp_global = fdopen(fd_global, "r"); 


    if (-1 == (flags = fcntl(fd_global, F_GETFL, 0))) flags = 0; 
    fcntl(fd_global, F_SETFL, flags | O_NONBLOCK); 

    //pthread_create(&screen_thread_id, NULL, screen_thread, (void*)NULL);  

    serialport_read_until(fd_global); 
    return 0; 
} 

int serialport_read_until(int fd) 
{ 
    char b[1]; 
    while(1) { 
     int n = read(fd, b, 1); //Read byte at a time 
     if(n==-1) { 
      printf("N");fflush(stdout); 
      perror("READ: "); 
     } 
     else if(n==0) { 
      printf("Z");fflush(stdout); 
     } else if(n>0) { 

      printf(":%d:",n);fflush(stdout); 


     } 
     usleep(100*1000); 

      if (fexists("/dev/ttyUSB0")) 
       printf("CONNECTED\n"); 
      else 
       printf("NOT CONNECTED\n"); 

    } 
    return 0; 
} 

bool fexists(const char *filename) 
{ 
    ifstream ifile(filename); 
    return ifile; 
} 



int serialport_init(const char* serialport, int baud) 
{ 
    struct termios toptions; 
    int fd; 

    // Open port 
    fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY); 
    if (fd == -1) { 
     perror("init_serialport: Unable to open port "); 
     return -1; 
    } 

    // Read current termios settings 
    if (tcgetattr(fd, &toptions) < 0) { 
     perror("init_serialport: Couldn't get term attributes"); 
     return -1; 
    } 

    // Set baud rate variable 
    speed_t brate = baud; 
    switch(baud) { 
    case 2400: brate=B2400; break; 
    case 4800: brate=B4800; break; 
    case 9600: brate=B9600; break; 
#ifdef B14400 
    case 14400: brate=B14400; break; 
#endif 
    case 19200: brate=B19200; break; 
#ifdef B28800 
    case 28800: brate=B28800; break; 
#endif 
    case 38400: brate=B38400; break; 
    case 57600: brate=B57600; break; 
    case 115200: brate=B115200; break; 
    } 
    cfsetispeed(&toptions, brate); 
    cfsetospeed(&toptions, brate); 

    // Setup termios for 8N1 
    toptions.c_cflag &= ~PARENB; 
    toptions.c_cflag &= ~CSTOPB; 
    toptions.c_cflag &= ~CSIZE; 
    toptions.c_cflag |= CS8; 

    // Reccomended settings 
    toptions.c_cflag &= ~CRTSCTS; // no flow control 
    toptions.c_cflag |= CREAD | CLOCAL; // turn on read & ignore ctrl lines 
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl 
    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw 
    toptions.c_oflag &= ~OPOST; // make raw 

    // Setting when read() releases 
    // see: http://unixwiz.net/techtips/termios-vmin-vtime.html (Still a little confusing) 
    toptions.c_cc[VMIN] = 0; 
    toptions.c_cc[VTIME] = 20; 

    // Apply settings 
    if(tcsetattr(fd, TCSANOW, &toptions) < 0) { 
     perror("init_serialport: Couldn't set term attributes"); 
     return -1; 
    } 

    return fd; 
} 
+0

如果您使用的是Linux,您可以在/ sys/class/gpoio /中使用塊設備/控件來開啓/關閉設備。您可能必須使用devmem2(用於TI OMAP)或通過修補內核或引導加載程序來使用MUX /設置gpios /引腳。 – mstrthealias 2013-03-03 03:04:09

回答

0

這項工作?我明天會測試它。

int status; 

status |= TIOCM_RTS; 
ioctl(fd, TIOCMSET, &status); 

usleep(500*1000); 

status &= ~TIOCM_RTS; 
ioctl(fd, TIOCMSET, &status); 
+1

這很糟糕。您正在使用未初始化的整數('status'),因此您的程序將顯示未定義的行爲並可以執行任何操作。您應該先使用TIOCMGET獲取狀態,然後更改您感興趣的位,然後使用TIOCMSET。 – 2015-08-17 18:00:29

+0

是的。自從問這個問題以來,我學到了很多東西。這裏的代碼是非常值得的...雖然,我用「粗糙的測試代碼」做了前言。我應該刪除這個問題嗎?對任何人來說這似乎都沒有多大用處。 – vilive 2015-08-18 20:39:05