首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将模块配置为115 baud,然后系统将端口重置为9600波特。

将模块配置为115 baud,然后系统将端口重置为9600波特。
EN

Stack Overflow用户
提问于 2017-11-11 16:58:28
回答 1查看 288关注 0票数 1

我正在编写一个C程序,在Linux环境中编写一个HM无线电模块,因为稍后我将编写其中的大约40个,我不想一直输入单独的编程代码来编写每个模块。

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

这是我一步一步地解决问题的方法。

  1. 运行程序。并收到预期的信息: HM-TRP模块配置 第一次建立HM.使用115 Done完成
  2. 切换到新窗口(我称之为#2),执行"stty -aF /dev/ttyS0“来查看设置。结果(显示)向我建议我的C程序功能良好: 速度115200波特;行0;列0;直线= 0;intr = ^C;min =^;擦除= ^H;eof = ^D;eol =;eol2 =;swtch =;start = ^Q;stop = ^S;susp = ^Z;rprnt = ^R;werase = ^W;lnext = ^V;刷新= ^O;min= 1;时间= 0;圆括号( -parodd cs8 -hupcl -cstopb cread clocal -crtscts -brkint ignbrk -parmrk -inpck -istrip -istrip -inlcr -istrip-inlcr -igncr -iuclc -ixany -ixoff )en42 20 en22 en24 en26 en28 en31 en33 en35 en38 en40 en43 en44#
  3. 使用参数"/dev/ttyS0 0 115200“启动"screen”程序,速度为115 k。
  4. 打开一个新窗口(我将称之为#3)并对模块执行以下有效命令: echo -en "\xAA\xFA\x96\x07“> /dev/ttyS0

这里的问题是,当屏幕应该打印"OK“时,它没有报告任何内容。所以我继续..。

  1. 我重新访问窗口#2以终止屏幕程序,然后使用"/dev/ttyS0 9600“重新启动屏幕,以获得9600波特的速度,以查看发生了什么。我再次重复步骤4,这一次出现了"OK“。

但奇怪的是,当我让屏幕程序以9600波特运行,并执行我的C程序时,屏幕报告了"OK“,并(正如我所预料的)了一行垃圾,这向我暗示了无线电模块的最后命令序列:

代码语言:javascript
复制
  \xAA\xFA\x1E\x00\x01\xC2\x00

实际上,仅仅从垃圾结果看,波特率就发生了变化。

那么问题是,为什么这个速率会重新设定到9600 the呢?波特率值是虚拟化的还是什么的,在应用程序之间是隔离的,即使我在一个新窗口中验证了正确的速率?或者我还遗漏了什么?

我的意思是,如果我只是在unix命令行上吐出每段带有echo语句的长代码,就可以设置模块,但是我想用C语言创建程序。

这是代码,对于参数,我使用/dev/ttyS0 0,其中/dev/ttyS0是我的串口(COM1)。

代码语言:javascript
复制
      #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;
  }

我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2017-11-11 17:38:33

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47240487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档