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



我正在开发一个C程序,该程序在Linux环境中编程HM-TRP无线电模块,因为稍后我将对其中的大约40个模块进行编程,我不想一直键入单独的编程代码来对每个模块进行编程。

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

这是我逐步解决这个问题的方法。

  1. 运行程序。并收到预期消息:

    HM-TRP模块配置

    首次设置HM-TRP。。。使用115 kbps配置完成

  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 "xAAxFAx96x07" > /dev/ttyS0
    

这里的问题是"屏幕"在应该打印"OK"时没有报告任何内容。然后我继续

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

但奇怪的是,当我让屏幕程序以9600波特运行并执行我的C程序时,屏幕报告"OK",并且(正如我所期望的)一行垃圾,这向我表明:的无线电模块的最终命令序列

xAAxFAx1Ex00x01xC2x00

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

那么问题是,为什么利率只是重置为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("ERRORn");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 confignn");
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 115kbpsn");
outs(rd,"xAAxFAxC3x00x01xC2x00",7);
outs(rd,"xAAxFAx1Ex00x01xC2x00",7);
break;
default:
//reset option in case something went wrong
printf("Resetting HM-TRP to defaults - 9600bpsn");
outs(rd,"xAAxFAxF0",3);
break;
}
close(rd);
printf("Config Donen");
return 0;
}

我做错了什么?

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

最新更新