我已经编写了一个小C代码,用于通过串行总线对测量设备进行编程。我知道这个设备可以在linux中编程,因为在gtkterm中实现的命令运行良好。我尝试通过gtkterm开发人员团队编写的代码激励自己,但没有成功。代码编译等不会产生错误,但设备会忽略发送给它的写入。我在本网站上看到的关于这个主题的先前帖子并没有帮助我。有人有个主意吗?我的老板就此问题了。如果我没有发现问题,我将被迫在Windows中完成工作,这将不会更容易。 串行设备使用8N2配置,1个起始位,并使用DTR / DSR hanshaking。这可能是导致问题的原因。 gtkterm接缝的人已经解决了这个问题,因为它适用于他们的程序,但是我没有在他们的代码中找到答案,也许这是编译问题?
我得到了以下输出:
init succes
configure succes
Read_port timeout
error microhmeter read
感谢您的帮助,
代码:
#include <stdio.h> // standard input / output functions
#include <stdlib.h>//strtoul
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <termios.h> // POSIX terminal control definitionss
#include <fcntl.h> // File control definitions
#include <sys/ioctl.h>
#include <errno.h> // Error number definitions
#include "microhmetre.h"
#define SELF_TEST 1
int microhmetre_fd = -1;
struct termios tio_save;
int microhmetre_Init(void)
{
microhmeter_close();
char* portName = "/dev/ttyUSB0";
int err;
/** open serial ports**/
microhmetre_fd = open(portName, O_RDWR | O_NOCTTY | O_NDELAY);
if(microhmetre_fd==-1) {
err = errno;
printf("openPort ERROR %d\n", err);
return 1;
}
/**Configuring serial port transmission type**/
struct termios newtio;
if(!isatty(microhmetre_fd)) {
printf("port %d is not a tty\n", microhmetre_fd);
close(microhmetre_fd);
microhmetre_fd = -1;
return 1;
}
//bzero(&newtio, sizeof(newtio)); // clear struct for new port settings
tcgetattr(microhmetre_fd, &newtio);
memcpy(&tio_save, &newtio, sizeof(struct termios));
//setting c_cflags
newtio.c_cflag = B9600;//baud rate
newtio.c_cflag |= CS8;//set 8 bits
newtio.c_cflag |= CSTOPB;//|= CSTOPB; 2 stop bits &=~CSTOPB; 1 stop bit
newtio.c_cflag |= (CREAD | CLOCAL); //enable receiver
//l_flags
newtio.c_lflag = 0;
//i_flags
newtio.c_iflag = IGNPAR | IGNBRK;
//o_flags
newtio.c_oflag = 0;
//other flags
newtio.c_cc[VMIN] = 0;
newtio.c_cc[VTIME] = 1; //Inter-char timer 1s read timeout
//apply settings
if(tcsetattr(microhmetre_fd, TCSANOW, &newtio)<0) {
printf("Unable to apply given port settings\n");
close(microhmetre_fd);
microhmetre_fd = -1;
return 1;
}
tcflush(microhmetre_fd, TCOFLUSH);
tcflush(microhmetre_fd, TCIFLUSH);
return 0;
}
void microhmeter_close(void){
if( microhmetre_fd != -1){
tcsetattr(microhmetre_fd, TCSANOW, &tio_save);
tcflush(microhmetre_fd, TCOFLUSH);
tcflush(microhmetre_fd, TCIFLUSH);
close(microhmetre_fd);
microhmetre_fd = -1;
}
}
int microhmeter_write(char * buf, int length)
{
if (microhmetre_fd == -1) return 1;
if (length = 0) return 0;
int res, err;
/*Write data*/
res = write(microhmetre_fd, buf, length);
if( res < 0){
err = errno;
printf("write failed: error %d\n", err);
return 1;
}
else if (res != length){
printf("write not completed\n");
return 1;
}
else {
tcdrain(microhmetre_fd);//attendre la fin de l'envoie.
}
return 0;
}
int microhmeter_configure(void)
{
char * remote = "SYST:REM\n";
if(microhmeter_write(remote, 9)){
printf("configure remote failed\n");
return 1;
}
sleep(1);
char * trig_bus = "TRIG:SOURCE BUS\n";
if(microhmeter_write(trig_bus, 16)){
printf("configure trig bus failed\n");
return 1;
}
sleep(1);
return 0;
}
int microhmeter_read(int recvBytes, char * buf)
{
unsigned long time;
unsigned long mesure;
int res;
//select
fd_set rfds;
struct timeval tv;
int retval = 0;
FD_ZERO(&rfds);
FD_SET(microhmetre_fd, &rfds);
//Timeout 500ms
tv.tv_sec = 3;
tv.tv_usec = 500000;
while(retval == 0) {
retval = select(microhmetre_fd+1, &rfds, NULL, NULL, &tv);
if(retval == -1) {
printf("Select Error in read port\n");
return 1;
} else if (retval) {
res = read(microhmetre_fd, buf, recvBytes);
break;
} else {
printf("Read_port timeout\n");
return 1;
}
}
if(res==15){
buf[res] = 0;
//TODO enregistrer et renvoyer la mesure
} else {
printf("error in read microhmeter\n");
return 1; //something is wrong
}
return 0;
}
int microhmeter_getMes(long double* mes)
{
char * mes_cmd = "MEAS:FRES?\n";
if(microhmeter_write(mes_cmd, 11)){
printf("error microhmeter write\n");
return 1;
}
char buf[16];
if(microhmeter_read(16, buf)){
printf("error microhmeter read\n");
return 1;
}
char ** res;
*mes = strtold(buf, res);
return 0;
}
#if SELF_TEST
int main(void){
long double mes;
if(microhmetre_Init()) {
printf("error init\n");
return 1;
} else printf("init succes\n");
if(microhmeter_configure()) {
microhmeter_close();
return 1;
}
else printf("configure succes\n");
if(microhmeter_getMes(&mes)) {
microhmeter_close();
return 1;
}
else printf("mesure succès\n");
printf("mes = %Lf", mes);
microhmeter_close();
return 0;
}
#endif // SELF_TEST
sudo strace -e trace = write ./microhmeter
的结果write(1, "init succes\n", 12init succes
) = 12
write(3, "", 0) = 0
write(3, "", 0) = 0
write(1, "configure succes\n", 17configure succes
) = 17
write(3, "", 0) = 0
write(1, "Read_port timeout\n", 18Read_port timeout
) = 18
write(1, "error microhmeter read\n", 23error microhmeter read
) = 23
+++ exited with 1 +++