配置模块为115kbps然后系统将端口重置为9600波特

时间:2017-11-11 16:58:29

标签: c linux serial-port reset baud-rate

我正在开发一个在Linux环境中编程HM-TRP无线电模块的C程序,因为稍后我会对其中的40个进行编程而我不想输入各个编程代码一直在编写每个编程代码。

在我的机器上,我有三个终端窗口设置。一个是编译程序并运行它。一种用于将数据发送到串行端口(用于测试),一种用于接收来自无线电模块的响应。

这是我如何解决问题的一步一步。

  1. Ran程序。并收到预期的消息:

    HM-TRP模块配置

    首次设置HM-TRP ...... 使用115kbps Config Done

  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. 启动&#34;屏幕&#34;带参数的程序&#34; / dev / ttyS0 115200&#34;速度为115k。

  4. 打开一个新窗口(我将其称为#3)并按如下方式对模块执行有效命令:

    echo -en "\xAA\xFA\x96\x07" > /dev/ttyS0
    
  5. 这里的问题是&#34;屏幕&#34;什么时候应该打印&#34; OK&#34;。那么我继续......

    1. 我重新访问窗口#2以终止屏幕程序然后我再次使用&#34; / dev / ttyS0 9600&#34;重新启动屏幕。 9600波特速度只是为了看看发生了什么。我再次重复步骤4,这次&#34;好的&#34;出现了。
    2. 但奇怪的是,当我离开屏幕程序以9600波特率运行并且我执行了我的C程序时,屏幕报告了#34; OK&#34;并且(正如我所料)一行垃圾向我建议无线电模块的最终命令序列:

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

      实际上确实显示了波特率的变化,只是从查看垃圾结果。

      那么接下来的问题是,为什么速率只会重置为9600bps?即使我在新窗口中验证了正确的速率,波特率值是否已虚拟化或在应用程序之间隔离?或者还有其他我想念的东西?

      我的意思是如果我只是在unix命令行上用echo语句吐出每个长代码但是我想在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;
        }
      

      我做错了什么?

1 个答案:

答案 0 :(得分:1)

经过一些发现后,发现我需要在发送命令后添加延迟,因为无线电模块只是半双工,因此它实际上忽略了我的一半命令,这导致速度指令无法被识别。在每个out函数调用之后usleep(100000)为我做了诀窍。