Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
串行程序LinuxC_C_Linux_Serial Port - Fatal编程技术网

串行程序LinuxC

串行程序LinuxC,c,linux,serial-port,C,Linux,Serial Port,我已经编写了一个小C代码,通过串行总线对测量设备进行编程。我知道这个设备可以在linux中编程,因为所实现的命令在gtkterm中运行良好。我试图通过gtkterm开发团队编写的代码来激励自己,但没有成功。代码编译等不会产生错误,但设备会忽略发送给它的写操作。我以前在这个网站上看到的关于这个主题的帖子对我没有帮助。有人有主意吗?我和老板在这方面有意见。如果我找不到问题,我将被迫在windows中完成这项工作,这将非常困难。 串行设备使用8N2配置,1个起始位,并使用DTR/DSR hanshak

我已经编写了一个小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

所以你有一个bug。使用调试器。或者更确切地说,在调试RS-232时,将一个侦听器连接到总线,然后查看实际存在的内容。如果您有一台具有多个串行端口的PC,只需将rx和接地连接到第二个端口即可轻松实现这一点,在终端中查看数据。或者,穷人的串行侦听器:使用示波器并手动解码RS-232数据。糟糕。@Lundin我记得在windows中使用了一种叫做
com0com
的东西。。。可以肯定的是,类似这样的东西可以在Linux上找到。但这可能会影响计时。启动简单,不握手,向终端发送几个字符。对于接收,也一样,在终端键入一些。旁注:select read循环不允许读取15个字符。
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 +++