Решено: Работа с COM-портом (помогите кто может)

Модератор: Модераторы разделов

math
Сообщения: 300
Статус: Ъ участник
ОС: Artix (= Arch without systemd)

Решено: Работа с COM-портом

Сообщение math »

Нужна информация по след. вопросу: Как узнать, что, например, на 8 штырьке логич. 1 или подать логич. 0 на 2 пин. Может есть готовые утилитки для такой низкоуровневой работы с COM-портом? Или подскажите, как это сделать штатными средствами.
Спасибо сказали:
Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Решено: Работа с COM-портом

Сообщение BlackStar »

C помощью ioctl(), вот здесь описано как это сделать: http://www.easysw.com/~mike/serial/serial.html#advanced
LightLang Team
Спасибо сказали:
math
Сообщения: 300
Статус: Ъ участник
ОС: Artix (= Arch without systemd)

Re: Решено: Работа с COM-портом

Сообщение math »

BlackStar писал(а):
24.06.2007 10:46
C помощью ioctl(), вот здесь описано как это сделать: http://www.easysw.com/~mike/serial/serial.html#advanced

Спасибо, кажется это то что надо!
Спасибо сказали:
math
Сообщения: 300
Статус: Ъ участник
ОС: Artix (= Arch without systemd)

Re: Решено: Работа с COM-портом

Сообщение math »

Не пойму, почему не работает - может вы что-нить поскажете...
Написал программу:

Код: Выделить всё

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>

int open_port(char *name);
int set_RTS(int fd); /* установка RTS в 1 */
int reset_RTS(int fd); /* сброс RTS в 0 */
int get_RTS(int fd);
int set_DTR(int fd);
int reset_DTR(int fd);
int get_DTR(int fd);
int set_DSR(int fd);
int reset_DSR(int fd);
int get_DSR(int fd);

int main(void) {
    int fd;
    if((fd=open_port("/dev/ttyS0")) == -1)
        exit(1);
    printf("Порт открыт!\n");
    if(reset_DSR(fd) == -1)
        exit(1);
    printf("DSR сброшен\n");
    int pin;
    while((pin=get_DSR(fd)) == 0) {
        if(pin==-1)
            exit(1);
        if(set_RTS(fd) == -1)
            exit(1);
    }
    printf("DSR: %d\n", pin);
    close(fd);
    return 0;
}

int open_port(char *name) {
    int fd = open(name, O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd==-1)
        perror("Не могу получить доступ к порту");
    return fd;
}

int set_RTS(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить RTS");
        return -1;
    }
    status |= TIOCM_RTS;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу установить RTS");
        return -1;
    }
    return 0;
}

int reset_RTS(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить RTS");
        return -1;
    }
    status &= ~TIOCM_RTS;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу сбросить RTS");
        return -1;
    }
    return 0;
}

int get_RTS(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1)
        perror("Не могу получить RTS");
    return status & TIOCM_RTS;
}

int set_DTR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить DTR");
        return -1;
    }
    status |= TIOCM_DTR;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу установить DTR");
        return -1;
    }
    return 0;
}

int reset_DTR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить DTR");
        return -1;
    }
    status &= ~TIOCM_DTR;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу сбросить DTR");
        return -1;
    }
    return 0;
}

int get_DTR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1)
        perror("Не могу получить DTR");
    return status & TIOCM_DTR;
}

int set_DSR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить DSR");
        return -1;
    }
    status |= TIOCM_DSR;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу установить DSR");
        return -1;
    }
    return 0;
}

int reset_DSR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить DSR");
        return -1;
    }
    status &= ~TIOCM_DSR;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу сбросить DSR");
        return -1;
    }
    return 0;
}

int get_DSR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1)
        perror("Не могу получить DSR");
    return status & TIOCM_DSR;
}
/* EOF */

По идее, цикл должен завершаться, когда я перемыкаю отверткой RTS(7pin) и DSR(6pin), но ничего не происходит.
Че тут не так?
Может, конечно, дело в отвертке, поэтому гляньте - есть или нет в коде ошибок?
Спасибо сказали:
Abaddon
Сообщения: 81
ОС: Gentoo 2006.1.x86_64

Re: Решено: Работа с COM-портом

Сообщение Abaddon »

math писал(а):
01.07.2007 12:36
Не пойму, почему не работает - может вы что-нить поскажете...
Написал программу:

Код: Выделить всё

#include <stdio.h>
int set_DSR(int fd) {
    int status;
    if(ioctl(fd, TIOCMGET, &status) == -1) {
        perror("Не могу получить DSR");
        return -1;
    }
    status |= TIOCM_DSR;
    if(ioctl(fd, TIOCMSET, &status) == -1) {
        perror("Не могу установить DSR");
        return -1;
    }
    return 0;
}

По идее, цикл должен завершаться, когда я перемыкаю отверткой RTS(7pin) и DSR(6pin), но ничего не происходит.
Че тут не так?
Может, конечно, дело в отвертке, поэтому гляньте - есть или нет в коде ошибок?

Может он не завершается потому, что в случае успешного получения состояния кома всегда возвращается 0?
Base: Gentoo 2006.1.x86_64 on AMD64_X2-5200+/1024Mb/7300GS-256Mb/250Gb
Serv: Gentoo 2006.1.x86_32 on iCeleron-2.4/1024Mb/Geforce2MX400-64Mb/250Gb+60Gb
Note: Gentoo 2006.1.x86_32 on Transmeta-8800(Efficeon)/512Mb/(Trident-???)/40Gb
Gate: Gentoo 2005.1.x86_32 on AMD-K6.2-500/64Mb/forgot.../3.2Gb+6.4Gb+40Gb
Спасибо сказали:
math
Сообщения: 300
Статус: Ъ участник
ОС: Artix (= Arch without systemd)

Re: Решено: Работа с COM-портом

Сообщение math »

Всё, решено. Оказывается, некотрые пины - только для чтения, а другие - только для записи. (Ну или что-то в этом роде, я опытным путем определил). Главное, что если выдавать сигнал через RTS, а снимать с CTS и RNG, все работает! :)
Спасибо сказали:
Abaddon
Сообщения: 81
ОС: Gentoo 2006.1.x86_64

Re: Решено: Работа с COM-портом

Сообщение Abaddon »

ммм... покорнейше прошу прощение за невнимательность, ложный совет, и, возможно потерю времени... видимо двое суток в пути в вагоне без кондея окончательно расплавили мои и без того слабые мозги:)
А сорец возьму на заметку, если не возражаете. т.к. в скором времени придется решать задачу, в которой это может понадобиться.
Base: Gentoo 2006.1.x86_64 on AMD64_X2-5200+/1024Mb/7300GS-256Mb/250Gb
Serv: Gentoo 2006.1.x86_32 on iCeleron-2.4/1024Mb/Geforce2MX400-64Mb/250Gb+60Gb
Note: Gentoo 2006.1.x86_32 on Transmeta-8800(Efficeon)/512Mb/(Trident-???)/40Gb
Gate: Gentoo 2005.1.x86_32 on AMD-K6.2-500/64Mb/forgot.../3.2Gb+6.4Gb+40Gb
Спасибо сказали: