串口程序linux C

时间:2016-06-20 15:05:38

标签: c linux serial-port

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

0 个答案:

没有答案