簡體   English   中英

C ++串口問題

[英]C++ Serial Port Question

問題 :我有一個手持設備,可以掃描所有包裝上的圖形彩色條形碼。 我可以使用一個跟蹤設備,它將自動滑動該設備。 該跟蹤設備通過通過串行端口獲取ASCII碼來發揮作用。 我需要讓此東西在Mac上的FileMaker中工作。 因此沒有終端程序等。

到目前為止,我所擁有的 :我購買了Keyspan USB /串行適配器。 使用名為ZTerm的程序,我成功向設備發送了命令。 示例:“ C,7 ^ M ^ J”

我還可以使用以下命令在終端中執行相同的操作:screen /dev/tty.KeySerial1 57600,然后在上方輸入相同的命令(但是當我輸入時,我只需要按Control-M和Control-J即可返回和換行)

現在,我正在為FileMaker(當然是C ++)編寫一個插件。 我想獲得我在C ++中所做的一切,所以當我在FileMaker中安裝該插件時,我可以僅調用其中一個函數,並在此進行整個過程。

我可以連接到該設備,但無法與之交談。 它沒有任何反應。

我嘗試使用以下命令連接到設備(成功):

FILE *comport;
if ((comport = fopen("/dev/tty.KeySerial1", "w")) == NULL){...}

int fd;
fd = open("/dev/tty.KeySerial1", O_RDWR | O_NOCTTY | O_NDELAY);

到目前為止,這是我在與設備交談時嘗試過的方法:

fputs ("C,7^M^J",comport);

要么

fprintf(comport,"C,7^M^J");

要么

char buffer[] = { 'C' , ',' , '7' , '^' , 'M' , '^' , 'J' };
fwrite (buffer , 1 , sizeof(buffer) , comport );

要么

fwrite('C,7^M^J', 1, 1, comport);

問題 :當我從終端連接到設備並使用ZTerm時,我可以將波特率設置為57600。我認為這可能就是為什么它在這里沒有響應的原因。 但是我在這里不知道該怎么做。...有人知道該怎么做嗎? 我試過了,但是沒有用:

comport->BaudRate = 57600;

那里有很多類解決方案,但是他們都稱它們包括termios.h和stdio.h之類的文件。 我沒有這些,無論出於什么原因,我都找不到要下載的文件。 我已經下載了一些示例,但是其中有20個文件,它們都在調用我找不到的其他文件(例如上面列出的文件)。 我是否需要找到這些?如果在哪里? 我對C ++不夠了解,是否有一個網站可以下載庫?

另一個解決方案可能是將這些終端命令放入C ++。 有沒有辦法做到這一點?

所以這讓我發瘋。 我不是C ++的人,我只知道基本的編程概念。 有沒有人是C ++專家? 理想情況下,我希望它可以使用已經擁有的功能(例如fwrite,fputs之類的東西)工作。 謝謝!

先發送一個^,然后再發送一個M,不會發送control-M,這只是您編寫它的方式,發送控制字符的最簡單方法是僅使用ascii控制代碼。

PS。 ^ M是回車符,即“ \\ r”,而^ J是換行符“ \\ n”

編輯:可能比您(希望)要知道的更多-但是在繼續之前請閱讀《串行端口方法》

這不是C ++問題。 您在詢問如何與TTY驅動程序進行交互以設置波特率。 您打開/ dev下的文件的事實表明您使用的是unix派生,因此在linux系統上要閱讀的相關手冊頁是“ man 3 termios”。

基本上,您使用上面的open()變體,並將文件描述符傳遞給tcsetattr / tcgetattr。

您確定已正確安裝所有編譯器工具嗎? 正如我期望的那樣,在我的OS X 10.5.8 Mac上,termios.h和stdio.h就在/ usr / include下。 您已經找到的用於在其他Unix變體上進行串行端口編程的代碼,只需稍作更改(如果有的話)即可在Mac上運行。 您能否告訴我們更多有關您嘗試過的內容以及出了什么問題的信息?

mgb還很好地說明了如何表示控制字符。

您可以使用ioctl設置波特率。 這是一個示例鏈接

您沒有指定要使用的Unix,所以下面我發布了一些Linux生產代碼。

請注意,下面的代碼是一個類方法,因此請忽略任何外部(即未聲明的)引用。

步驟如下-

配置termio結構,在這里可以設置任何需要的標志等(即使用zterm完成的步驟。下面的termio設置將端口配置為8個數據位,1個停止位和無奇偶校驗(8-n-1)。也是該端口將處於“原始”(相對於煮熟的)模式,因此其字符流,文本未成幀等。波特常數與實際值匹配,即對於56700波特,請使用“ 57600”。

時序參數表示字符一旦可用就從設備返回。

設置了終端參數后,打開設備(使用POSIX open()),然后可以使用tcgetattr / tcsetattr通過fd配置設備。

此時,您可以使用read()/ write()系統調用來讀取/寫入設備。

請注意,在以下示例中,如果沒有可用數據,則read()將阻塞,因此,如果不希望阻塞,則可能要使用select()/ poll()。

希望能有所幫助。

termios termio    
tcflag_t baud_specifier;

    //reset device state...
    memset (&termio, 0, sizeof (termios));
    read_buffer.clear();

    //get our boad rate...
    if (!(baud_specifier = baud_constant (baud))) {
        ostringstream txt;
        txt << "invalid baud - " << baud;
        device_status_msg = txt.str();
        status = false;

        return (true);
    }


    //configure device state...
    termio.c_cflag = baud_specifier | CS8 | CLOCAL | CREAD;

    //do we want handshaking?
    if (rtscts) {
        termio.c_cflag |= CRTSCTS;
    }

    termio.c_iflag = IGNPAR;
    termio.c_oflag = 0;
    termio.c_lflag = 0;

    //com port timing, no wait between characters and read unblocks as soon as there is a character
    termio.c_cc[VTIME]    = 0;
    termio.c_cc[VMIN]     = 0;

    //open device...
    if ((fd = open (device.c_str(), O_RDWR | O_NOCTTY)) == -1) {

        ostringstream txt;
        txt << "open(\"" << device << "\") failed with " << errno << " - "
            << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //keep a copy of curret device state...
    if (tcgetattr (fd, &old_termio) == -1) {

        ostringstream txt;
        txt << "tcgetattr() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //flush any unwanted bytes
    if (tcflush (fd, TCIOFLUSH) == -1) {

        ostringstream txt;
        txt << "tcflush() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //apply our device config...
    if (tcsetattr (fd, TCSANOW, &termio) == -1) {

        ostringstream txt;
        txt << "tcsetattr() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    node_log_f ("successfully initialised device %s at %i baud", "open_device()",
                device.c_str(), baud);

    status = true;
    return (true);
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM