Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Com порт


Автор: study 1.8.2005, 12:03
Привет всем!!!
Помогите решить такую задачу. К компьютеру под ОС Linux к Com порту подключен датчик. Мне надо написать прораммку, которая бы посылала бы в Com порт значение и считывала результать, а результат записывать в текстовый файл.
Можете помочь...
Заранее спасибо...

Автор: chaos 1.8.2005, 12:28
вот тебе не большой пример:

Код

#include <stdio.h>

int main(int argc, char *argv[])
{
    FILE *com = fopen("/dev/cua0", "rw"); //открываешь порт

    fprintf(com, "%s", "write string in com port"); //записываем строку в ..

    int val; 
    fscanf(com, "%d", &val); //читаем значение

    fclose(com); //закрываем порт

    FILE *f = fopen("~/log.txt", "w"); //открываем для записи прочитанного значения
    fprintf(f, "Значение датчика: %d\n", val); //записываем
    fclose(f); //закрываем

    return 0;
}

Автор: study 1.8.2005, 13:09
Спасибо chaos, а можешь пояснить, /dev/cua0 - это имя com порта?

Автор: chaos 1.8.2005, 13:39
Цитата(study @ 1.8.2005, 13:09)
Спасибо chaos, а можешь пояснить, /dev/cua0 - это имя com порта?

да, но это у меня, у себя ты должен подставить своё имя

Автор: study 1.8.2005, 13:57
Хорошо, а вот я читал, что в com порт надо устанавливать скорость, биты данных, четность и стоповые биты, где здесь эти параметры задавать?

Автор: chaos 1.8.2005, 13:58
тютю smile

Автор: study 1.8.2005, 14:11
Я сам точно не знаю, просто смотрел какой-то класс для Visual C++, а там эти данные вводились...
Так нужны эти данные или нет? smile

Автор: chaos 1.8.2005, 14:18
нет, так все будет нормально работать, во всяком случае я всегда так делаю!
Добавлено @ 14:19
если не получиться пиши

Автор: study 1.8.2005, 14:24
Хорошо, спасибо большое, попробую, надеюсь получиться? smile

Автор: Airanius 24.12.2005, 09:55
Цитата(chaos @ 1.8.2005, 14:18)
нет, так все будет нормально работать, во всяком случае я всегда так делаю!
Добавлено @ 14:19
если не получиться пиши

И всё-таки... Как читать/писать в порт я разобрался и сам! Подскажите плиз начинаюшему, как изменить параметры порта (скорость, контроль чётность, таймауты, etc.) заранее спасибо

Автор: scapig 24.12.2005, 15:31
Да.. мне тоже интересно, как это все проделывать в линухе, т.к. в винде это делается элементарно... smile

Это понятно, что работать будет нормально, но как быть если надо , чтобы данные передавались с определенной скоростью...., а не от балды...
Как конфигурить???

Автор: GrayCardinal 24.12.2005, 17:30
Цитата
т.к. в винде это делается элементарно

Я сегодня добрый, минусовать не буду. Но просьба больше не упоминать в Линуховском разделе это нехорошее слово да и еще в таком виде smile

$ man tcsetattr

Автор: Бонифаций 25.12.2005, 12:01
man stty

Автор: Airanius 5.1.2006, 23:10
Serial Programming Guide for POSIX Operating Systems.pdf - полное и подробное описание работы с Последовательным портом(ищите поисковиками)

Автор: Guest 12.1.2006, 02:58
http://www.opennet.ru/docs/RUS/serial_guide/
http://www.opennet.ru/base/dev/rs232_prog.txt.html

Автор: mik19 20.6.2008, 17:52
Доброго всем дня, у меня тоже возникла подобная задача, но мне не просто считать данные нужно, а немного посложнее мне нужно его мониторить, и в случае изменений, послать команду в шел (при определенных условиях). Другими словами мне нужен демон, который будет постоянно мониторить СОМ порт, и при поступлении данных, скажем, посылать в шел ансишный код буквы F. 

Автор: chaos 23.6.2008, 12:54
самый простой вариант настроить таймаут на чтение и в отдельно потоке постоянно пытаться проичтать из порта

Автор: MAKCim 23.6.2008, 13:23
select()/poll()/epoll()

Автор: Mal Hack 29.6.2008, 19:52
Цитата(study @  1.8.2005,  14:11 Найти цитируемый пост)
Я сам точно не знаю, просто смотрел какой-то класс для Visual C++, а там эти данные вводились...
Так нужны эти данные или нет? smile 

Все эти вещи нужно вводить (DCB, COMMSTATE etc.), но только для Windows, чтобы система разрешила работать с COM портом, как нам надо.
В линуксе этих вещей в принципе нет, т.к. порт по сути - папка/файл. Если попробовать не просто через fopen, а через socket поработать, то может быть, там что-то как-то и придется куда-то указывать.  Правда, не пробовал. У меня в либе fopen висит...

Цитата(chaos @  23.6.2008,  12:54 Найти цитируемый пост)
самый простой вариант настроить таймаут на чтение и в отдельно потоке постоянно пытаться проичтать из порта

Просто тайм-аут может не прокатить. Все зависит какой девайс сидит на порте, и по какому протоколу он работает RS-232, 485, т.к. в этом случае могут быть косяки из-за того, что, дисикнт возникает, короче смещение окна чтения.

Автор: Tiffany 7.7.2008, 08:17
Вот тут нашла в своей проге кусочек, вроде то, что ты просил (если я прально поняла). Тока он на QT, но не страшно - переделать недолго =)

Код

    fd_set rfds;
    struct timeval tv;
    int retval;
    int res;
                char buf[255];
                QMutex mut;

                bzero(&buf, sizeof(buf));
    FD_ZERO(&rfds);                    
    FD_SET(ControlThread->COMDevice, &rfds);    
while(1)                  {
    retval = select(ControlThread->COMDevice+1, &rfds, NULL, NULL, NULL); //ждем появления новых данных на порту
    if (retval)        {
mut.lock();    
       res=read(ControlThread->COMDevice, buf, sizeof(buf)); // если что-то появилось - читаем
mut.unlock();    
}


После этих манипуляций в "buf" будут данные с порта, делай с ними что хошь. А ваще читай man select и man termios (настройки порта) 

Автор: nworm 27.9.2008, 00:39
Тут возникла задача.

При возникновении прерыванию от lpt порта передавать данные на com-порт прям из драйвера lpt-шного прерывания.
Копаюсь в разных примерах драйверов. smile 

Можно в этом случае безнаказанно stdio.h подключить к драйверу прерывания от lpt?

Автор: MAKCim 27.9.2008, 10:48
Цитата(nworm @  27.9.2008,  00:39 Найти цитируемый пост)
Можно в этом случае безнаказанно stdio.h подключить к драйверу прерывания от lpt? 

нет

Автор: nworm 27.9.2008, 11:56
А может что-нибудь ещё посоветуете?

Автор: nworm 3.10.2008, 00:23
Что-то я нашёл.

Код

static int skeleton_kernel_initport() {
    struct tty_struct* tty;

    // Get the current options for the port...
    
    f = filp_open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY, 0600);
    fs=get_fs();
    set_fs(KERNEL_DS);

    tty=(struct tty_struct*)f->private_data; 
    unsigned int ccflag = *(tty->termios->c_cflag);

...


В ответ на последнюю строку (unsigned int ccflag = *(tty->termios->c_cflag);) мне выдаётся сообщение:

/home/man/model2_my/lpt_interrupt/skeleton.c: In function ‘skeleton_kernel_initport’:
/home/man/model2_my/lpt_interrupt/skeleton.c:63: error: dereferencing pointer to incomplete type

Никто не знает, что с этим делать?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)