Перейти к содержанию
    

Работа с СОМ портом

Здравствуйте, уважаемые!

Если кто сталкивался, помогите плизз. Долбаюсь уже 2 недели, и ничего не получается. Ситуация следующая: Есть некий контроллер и общается он с компьютером через RS232, в Win98 все работает, а вот Операционка Win2000

блокирует прямое обращение к портам. Мне подсказали прогу WinDriver для обхода этой проблемы... но опять-же, для LPT порта там есть стандартная заготовка, которая прекрасно работает... а о СОМ порте ни слова. Сразу оговорюсь, я не являюсь системным программистом и с железом дел никогда не имел... а тут пришлось ;) Искренне надеюсь на Вашу помощь. Заранее спасибо.

З.Ы.

Я впервые на этом форуме, и вполне возможно что запостил тему не совсем в тот раздел куда следовало бы.

ЗЗ.ЫЫ

Работать с этой штукой через CreateFile/ReadFile/WriteFile тоже не получается,

в ReadFile постоянно нули возвращаются, хотя команда сформирована верно и контроллером принята...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте следуюшее в прикреплённом файле.

У меня под Win2000 получалось.

com_win32.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, но эту статью я недавно читал (на сайте www.rs232.ru) но, дело в том, что я никак не могу получить вообще ничего от контроллера... Я пробовал событийную модель(с помощью Overlapped и WaitCommEvent) с различными масками. Как поется, "Крикну, а в ответ - тишна"...

Тут вопрос стоит в прямом обращении к порту, а это возможно только при наличии соответстующего драйвера(во всяком случае, в Win200/XP и им подобным) Для написания драйвера, посоветовали использовать WinDriver...

Если кто ее использовал при работе с СОМ портом, подскажите плизз!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем такие сложности с прямым доступом если и через API всё прекрасно работает?

Вы видимо не очень тщательно разобрались. Я делал всё как сказано в статье и всё получилось и под Win98 и под Win2000.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Могу привести исходник на паскале, присланный разработчиками железки, и свой, на С++ который пытаюсь переписать с паскалевской и перевести на WinAPI... Был бы благодарен, если укжете в чем ошибка...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вы попробуйте RxD и TxD закоротить, и отправить в порт чтенить.

если ничего не приниматься не будет - проверьте настройку DCB структуры, у меня было что в настройках проверку DSR , CTS , RTS или DTR отключить надо. давно было не могу сказать что точно. но история таже - в 98 работало, а в 2к нет. потом все пучком стало

 

О!!! нашел

 

fDsrSensitivity = NULL

Задает чувствительсть коммуникационного драйвера к состоянию линии DSR. Если это поле равно TRUE, то все принимаемые данные игнорируются драйвером (коммуникационный драйвер расположен в операционной системе), за исключением тех, которые принимаются при установленом сигнале DSR.

 

его в ноль,

 

fDtrControl = DTR_CONTROL_DISABLE и fRtsControl = RTS_CONTROL_DISABLE

По идее дожно зафурыкать. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Фуухх, я уже окончательно запутался....

выкладываю настройку DCB

....
   DriverHandle = CreateFile (Com_Name, GENERIC_READ | GENERIC_WRITE,
                              0, NULL, OPEN_EXISTING, 0, NULL);

   if (DriverHandle == INVALID_HANDLE_VALUE) 
   {
       return (DriverHandle);
   }
   else
   {


       SetupComm (DriverHandle, 1024, 1024);

       GetCommState (DriverHandle, &Our_DCB);

       Our_DCB.BaudRate = DCB_Baud_Rate;
       Our_DCB.fParity = 0;
       Our_DCB.fOutxCtsFlow = 0;
       Our_DCB.fOutxDsrFlow = 0;
       Our_DCB.fDtrControl = DTR_CONTROL_ENABLE;
       Our_DCB.fDsrSensitivity = NULL;
       Our_DCB.fTXContinueOnXoff = 0;
       Our_DCB.fOutX = 0;
       Our_DCB.fInX = 0;
       Our_DCB.fErrorChar = 0;
       Our_DCB.fNull = 0;
       Our_DCB.fRtsControl = RTS_CONTROL_DISABLE;
       Our_DCB.fAbortOnError = 0;
       Our_DCB.ByteSize = 8;
       Our_DCB.Parity = NOPARITY;
       Our_DCB.StopBits = ONESTOPBIT;

       SetCommState (DriverHandle, &Our_DCB); 

       SetCommMask (DriverHandle, EV_TXEMPTY);
   }
....

А потом вызываю WriteFile... Данные приходят

на контроллер, причем правильно им "понимаются"... а при вызове

ReadFile нет ни одного быйта в очереди...

а вот что происходит в паскале...

{проверка контроллера на СОМ1}
{в первом байте -младший адрес, идентификатор}
{во втором байте-старший адрес, идентификатор, тип модуля, интервал ответа}
{третий байт (первый байт массива)-команда, идентификатор, интервал между ответами}
{если нужно передать данные, то следующие байт(ы) массива-данные}
{последний байт-контрольная сумма}

program com;
uses crt,dos;
var a,b,c,n,rs,P:byte;
   rs_old:pointer;
   r:registers;
   KS:word;
   I:byte;
const
   MAX:byte = 1;{1-если нет данных}  {команда---данные}
   BUF:array[1..10] of byte =        ($e0,      $8f,$8f,$8f,$8f,$8f,$8f,$8f,$8f,$8f);

label no_RX_,no_0,no_1,no_2,no_RX__,yes_key;

begin
KS:=0;
I:=0;

port[$3fb]:=$83;{без паритета}

port[$3f8]:=$06;
port[$3f9]:=$00;{19200бод}

port[$3fb]:=$03;
port[$3f9]:=$00;

port[$3fc]:=$03; {настроить преобразователь RS232/485 на передачу}

delay(500);

b:=0;
KS:=0;


{--ФОРМИРОВАНИЕ МЛАДШЕГО АДРЕСА с битами идентификатора, типа модуля--}
P:=$00;
KS:=P;
port[$3f8]:=P;{передать адрес младший}

no_0:
rs:=port[$3fd];
rs:=rs and 64;
if rs<>64 then goto no_0
else
{goto yes_key;}

{-------------------------------------}
{--ФОРМИРОВАНИЕ СТАРШЕГО АДРЕСА с битами идентификатора, типа модуля и интервала ответа--}
P:=$70;
KS:=KS+P;
port[$3f8]:=P;{передать адрес старший}

no_1:
rs:=port[$3fd];
rs:=rs and 64;
if rs<>64 then goto no_1
else
{goto yes_key;}


{----------------------------}
{--СФОРМИРОВАТЬ КОМАНДУ с битом идентификатора и интервалом между байтами ответа--}
{если необходимо передать данные- изменить индекс и уст. данные массива}
while (I < MAX) do
 begin
 I:=I+1;

P:=BUF[I];
KS:=KS+P;
port[$3f8]:=P;{передать команду И ДАННЫЕ}

no_2:
rs:=port[$3fd];
rs:=rs and 64;
if rs<>64 then goto no_2
else

 end;

{goto yes_key;}

{----------------------------}
{--СФОРМИРОВАТЬ К.С. с битом идентификатора--}
KS:=KS and $00ff;
P:=KS;
P:=P or $80;
port[$3f8]:=P;{передать КС}

port[$3fc]:=$02;{настроить преобразователь RS232/485 на прием}

write('com ');

{----------------------------}
{--ПРИНЯТЬ ВСЕ ПОДРЯД--}
no_RX_:
if memw[0:$41a]<>memw[0:$41c] then goto yes_key;
rs:=port[$3fd];
rs:=rs and 1;
if rs<>1 then goto no_RX_
else

a:=port[$3f8];a:=a and 127; {стереть, для вывода на экран, бит идентификатор}

write(a,';');

goto  no_RX_;

yes_key:

writeln(KS);
 end.
end

Может кто что подскажет....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Our_DCB.fDtrControl = DTR_CONTROL_ENABLE;

 

этой настройкой ты запрещаешь прием данных на комп, если в не устройстве установлен DTR.

короче

1 попробуй сменить на DTR_CONTROL_DISABLE

2 посмотри осцилографом идет ли вообще сигнал?

 

еще

????SetCommMask (DriverHandle, EV_TXEMPTY);

 

после

SetCommState(port, &dcb);

я ставлю

SetupComm(port, 50, 50);

 

а перед записью и считыванием

//сброс буфера порта

PurgeComm(port, PURGE_RXCLEAR|PURGE_TXCLEAR);

 

 

то Sam: включи аську

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При установке DTR_CONTROL_DISABLE данные на контроллер не приходят

вообще... Хе, а осциллографа у меня нет ;) и наврядли когда-то появится...

я ж говорю, до этого никогда с "железом" не работал... по-сути дела, мне вооюще должно быть по-барабану что там за устройство, как оно работает и т.д. главное знать структуру посылки и структуру ответа, вот и все... а тем чем я занимаюсь, вообще должны, по-идее заниматься разработчики контроллера... а то, что это получается... там мы хотим работать, а там не хотим... ну, да ладно, это не важно... важно то, что оно должно работать, вот и оббиваю штукатурку головой ;) я уже облазил весь www.RS232.ru, перечитал кучу материала...но, никак не найду источник проблемы и метод устранения... с помошью WinDriver'a, тоже что-то не получается... хотя, код драйвера он генерит сам, главное настроить ресурсы устройства, а, потом, зарегить новый драйвер(удалив перед этим виндозный)... я в шоке.

а всем, кто принимает участие в обсуждении, большой :a14:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я бы отправил тебе свои исходники, да у меня как раз все настройки в файле сохраняются

если надо могу отправить.

но это завтра....

засиделся я, пора домой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

veter, Давай, буду очень признателен ;)

присылай на [email protected] or [email protected]

если что придумается... я в аське (почти круглосуточно) ICQ# 342610002

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вот что происходит в паскале...

...
port[$3fc]:=$03; {настроить преобразователь RS232/485 на передачу}
...
port[$3fc]:=$02;{настроить преобразователь RS232/485 на прием}
...

Не в этом ли дело? Может, в Вашем примере для Win преобразователь RS232/485 все время на передачу работает? Я, правда, назначение портов UART не помню, поэтому сходу не скажу, как то же самое можно сделать в WinAPI. Если нужно, могу выслать исходники на Паскале (Delphi), где у меня реализована связь с контролером (правда, используется только TxD и RxD, управления преобразователем нет).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь есть класс для работы с ком портом, у меня через него всё работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При порты в прикладной программе забудьте- это привелегия драйверов (vxd, sys). Вот хороший компонент для Дельфей с примерами. Работает на всем, и на USB переходниках тоже.

RS485 к сожалению под Виндой работает отвратительно. И переключать направление из программы корректно неполучится. Т.к. физическая передача в порт разнесена по времени с вызовом WriteFile, то даже ESC команды не переключат направление RS485 вовремя.

Если скорость постоянна, то направление можно переключать одновибратором в разъеме. Хотя более эффективное решение- маленькая схема на AT89c2051. Там же делали и опторазвязку.

cport_3.0.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

[khach], естественно из прикладной программы с портами ни кто работать не собирается, всё делается через WriteFile/ReadFile

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...