Не получается открыть COM порт
Привет !
Пытаюсь научиться работать с COM портом программно
(итоговая задача: нужно снимать показания с мультиметра),
но возникает непонятный затык.
Для экспериментов я использую свой модем (тк мультиметр не мой).
Так вот, при открытии файла порта, происходит зависание программы.
При этом светодиод модема загорается, те в порт я попадаю.
Работаю под рутом, с правами игрался. Не пойму в чём затык.
Модем работает нормально.
Пишу на Паскале, но и на сишном примере
из Serial-Programming-HOWTO то же самое.
"Прямая" попытка:
var
port : Text;
begin
Assign(port, '/dev/ttyS1');
FileMode := 2;
ReWrite(port); // здесь происходит зависание
WriteLn('!');
WriteLn(port, 'ATDP100');
ReadLn;
Close(port);
Через специальную библиотеку:
{$MODE DELPHI}
Program testser;
uses
synaser{, sysutils};
var
ser:TBlockSerial;
begin
ser:=TBlockserial.Create;
try
ser.RaiseExcept:=True;
ser.Connect('/dev/ttyS1'); // здесь происходит зависание
WriteLn('!');
ser.Config(9600,8,'N',0,false,false);
writeln (ser.ATCommand('ATDP100'));
finally
ser.Free;
end;
end.
Пример на Си из Serial-Programming-HOWTO :
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
/* установки бодрейта определены в <asm/termbits.h>, который подключается файлом
<termios.h> */
#define BAUDRATE B38400
/* измените это на правильное устройство в вашем случае */
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX-совместимый код */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
/*
Открываем модемное устройство для чтения и записи и не как терминал
потому что нам не нужно завершение в случае появления в линии CTRL-C
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); // здесь происходит зависание
if (fd <0) {perror(MODEMDEVICE); exit(-1); }
tcgetattr(fd,&oldtio); /* сохраняем текущие настройки порта */
bzero(&newtio, sizeof(newtio)); /* очищаем структуру под новые настройки */
/*
BAUDRATE: Установка кол-ва бод в секунду. Также можно воспользоваться
cfsetispeed и cfsetospeed.
CRTSCTS : аппаратное управление исходящим потоком (используется только
если кабель содержит все необходимые линии. Смотрите раздел 7
Serial-HOWTO)
CS8 : 8n1 (8 бит, без контроля четности, 1 стопбит)
CLOCAL : локальное соединение, без управления модемом
CREAD : разрешаем получать символы
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
/*
IGNPAR : игнорируем байты с ошибками четности
ICRNL : отображаем CR на NL (иначе появление CR на другом компьютере не
завершит ввод)
в остальном оставляем устройство ненастроенным (raw, без других обработок
ввода)
*/
newtio.c_iflag = IGNPAR | ICRNL;
/* Ненастроенный (raw, как есть) вывод */
newtio.c_oflag = 0;
/*
ICANON : включаем режим канонического ввода
отключаем любую эхо-функциональность и не посылаем
сигналов вызвавшей программе
*/
newtio.c_lflag = ICANON;
/*
инициализируем все управляющие символы
значения по умолчанию можно найти в /usr/include/termios.h и они
продублированы в комментариях, но здесь они не необходимы
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* @ */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* междусимвольный таймер выключен */
newtio.c_cc[VMIN] = 1; /* блокировать read до появления 1 символа */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */
/* сбрасываем модемную линию и активируем настройки порта */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/*
настройка терминала выполнена, теперь обрабатываем ввод
в этом примере появление 'z' в начале строки завершит программу
*/
while (STOP==FALSE) { /* повторять до выставления условия останова */
/* read блокирует выполнение программы до появления символа конца строки
даже если получено больше 255 символов. Если количество считанных
символов меньше количества поступивших симоволов, то последующие
вызовы read вернут оставшиеся символы. res будет содержать
количество реально считанных символов */
res = read(fd,buf,255);
buf[res]=0; /* устанавливаем конец строки чтобы вызвать printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
/* восстанавливаем исходные настройки порта */
tcsetattr(fd,TCSANOW,&oldtio);
}
Извиняюсь за размер письма.
Спасибо,
Александр
-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32661; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693779
В сообщении от 28 сентября 2007 17:30 Alexander написал(a):
А затык возникает только в самописных программах или так же если
попытаться залезть на него через minicom или что-нибудь ему подобное?
Так же возможно что какой-то процесс на нем уже висит. (Что насчет ps
ax | grep ttyS1 ?)
-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 32662; Возраст листа: 1526; Участников: 1445
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/693780