2017-11-11 249 views
0

我正在研究一個在Linux環境下編程HM-TRP無線電模塊的C程序,因爲後來我將編程約40個這樣的模塊,我想要一直輸入單個編程代碼來編程每一個編程代碼。配置模塊爲115kbps,然後系統將端口重置爲9600波特

在我的機器上我有三個終端窗口設置。一個是編譯程序並運行它。一個用於發送數據到串行端口(用於測試),另一個用於接收來自無線電模塊的響應。

這是一步一步如何解決問題。

  1. 冉程序。並收到預期的消息:

    HM-TRP模塊配置

    設置HM-TRP首次... 使用115kbps的 配置完成

  2. 切換到新窗口(我稱之爲#2)並執行「stty -aF/dev/ttyS0」以查看已設置的設置。結果(如圖所示)暗示我,我的C程序確定運作:

    speed 115200 baud; rows 0; columns 0; line = 0; 
    intr = ^C; quit = ^\; erase = ^?; kill = ^H; eof = ^D; eol = <undef>; eol2 = <undef>; 
    swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; 
    flush = ^O; min = 1; time = 0; 
    parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts 
    ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany 
    -imaxbel -iutf8 
    -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 
    -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase 
    -tostop -echoprt -echoctl 
    -echoke 
    
  3. 開始 「屏幕」 的程序與參數 「的/ dev/ttyS0來115200」 爲115K的速度。

  4. 打開一個新的窗口(我稱之爲#3),並執行一個有效的命令到模塊如下:

    echo -en "\xAA\xFA\x96\x07" > /dev/ttyS0 
    

這裏的問題是,「畫面」的報告什麼時候它應該打印「確定」。於是我繼續...

  • 我重溫窗口#2終止屏幕程序,然後我「的/ dev/ttyS0來9600」再次重新啓動屏幕爲9600波特的速度剛看看發生了什麼。我再次重複步驟4,這次出現「OK」。
  • 但奇怪的是,當我離開屏幕程序運行9600波特,我執行我的C程序時,屏幕報告「OK」和(正如我期待的)一行垃圾向我暗示:最後的命令序列到收音機模塊:

    \xAA\xFA\x1E\x00\x01\xC2\x00 
    

    實際上確實顯示波特率的變化,只是從看垃圾的結果。

    所以接下來的問題是,爲什麼速率會重置爲9600bps?即使我在新窗口中驗證了正確的速率,波特率值是虛擬化還是應用程序之間的隔離?或者有什麼我失蹤?

    我的意思是我沒有問題,建立模塊,如果我只是吐出每個長碼與UNIX命令行回聲聲明,但我想在C.

    創建程序這是代碼,對於參數,我使用/dev/ttyS0 0,其中/ dev/ttyS0是我的串行端口(COM1)。

     #include <sys/stat.h> 
        #include <sys/types.h> 
        #include <sys/io.h> 
        #include <unistd.h> 
        #include <stdio.h> 
        #include <stdlib.h> 
        #include <string.h> 
        #include <termios.h> 
        #include <fcntl.h> 
    
        void outs(int fd, char* n,unsigned int sz){ 
        char *d=n; 
        unsigned int nwrt=0,x=0; 
        for (x=0;x<sz;x++){ //send byte one by one 
         while ((nwrt=write(fd,d,1))==0){ 
        usleep(10000); //waste CPU cycles passively until byte is sent 
         }; 
         d++; 
        } 
        } 
    
        int openser(speed_t speed,const char* dev){ 
        struct termios options; 
        //open serial port 
        int fd = open(dev, O_RDWR | O_NOCTTY | O_SYNC);if (fd < 0){printf("ERROR\n");return -1;} 
        memset(&options,0,sizeof options); 
        tcflush(fd,TCIOFLUSH); 
        tcgetattr(fd,&options); 
        //set baud rate 
        cfsetispeed(&options, speed); 
        cfsetospeed(&options, speed); 
        options.c_iflag = IGNBRK | IGNPAR; //raw input 
        options.c_cflag |= (TOSTOP|NOFLSH|CLOCAL|CREAD|CS8);//ignore modem + parity: 8N1 + no rtscts 
        options.c_lflag=0; //raw input 
        options.c_oflag=0;options.c_cc[VMIN]=1;options.c_cc[VTIME]=0; //raw output 
        tcsetattr(fd, TCSANOW, &options); 
        return fd; 
        } 
    
        int main(int argc,char* argv[]){ 
        printf("HM-TRP module config\n\n"); 
        int rd=0; 
        setbuf(stdout,NULL); 
        if (argc < 2){printf("serial device + function required as argument.\n");return -1;} 
        //open serial port for 115kbps baud 
        rd=openser(115200L,argv[1]);if (rd == 0){return -1;} 
        // get function 
        int funcn=strtol(argv[2],NULL,10); 
        switch (funcn){ 
        case 0: //function 0. 1st time setup. set things up at 9600 baud then switch to 115kbps 
        printf("Setting up HM-TRP for first time...\n"); 
        close(rd);rd=openser(9600L,argv[1]);if (rd == 0){return -1;} 
        case 1: 
        //set baud + wireless speed to 115kbps 
        printf("Using 115kbps\n"); 
        outs(rd,"\xAA\xFA\xC3\x00\x01\xC2\x00",7); 
        outs(rd,"\xAA\xFA\x1E\x00\x01\xC2\x00",7); 
        break; 
        default: 
        //reset option in case something went wrong 
        printf("Resetting HM-TRP to defaults - 9600bps\n"); 
        outs(rd,"\xAA\xFA\xF0",3); 
        break; 
        } 
        close(rd); 
        printf("Config Done\n"); 
        return 0; 
        } 
    

    我在做什麼錯?

    回答

    0

    經過一番發現,事實證明我需要在發送命令後添加一個延遲,因爲無線電模塊只有半雙工,因此它實際上忽略了導致速度指令不被識別的一半命令。 A usleep(100000)在每個輸出函數調用之後爲我做了訣竅。