реклама на сайте
подробности

 
 
> Программирование COM порта, Проблемы с передачей данных устройству по COM
Yuriy_Rus
сообщение Aug 30 2006, 08:45
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 24-07-06
Пользователь №: 19 039



Уважаемые, уже котрый день занимаюсь программированием GPRS модема по COM и не могу понять, что за фигня...
Загружаю комп втыкаю модем, запускаю прогу - всё виснет, соединения - нет.
Закрываю прогу. Запускаю гипертерминал. Ввожу любую команду - всё ништяк, устройство отвечает.

Закрываю гипертерминал. Запускаю прогу, и всё уже пашет без проблем, только установка настроек порта(SetCommState(Port, &dcb) странно работет (то работает, то не работает, но восновном не работает).
Так вроде в DCB всё указываю что надо для работы устройства.
Исходник открытия и настройки порта:

if(PortOpen == 1) return false;

DCB dcb;
COMMTIMEOUTS ct;
unsigned long int bc;

//dcb = (DCB*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
//BuildCommDCB("baud = 9600 parity = N data = 8 stop = 1", &dcb);

dcb.fBinary = TRUE;
dcb.BaudRate = 9600;
dcb.fParity = NOPARITY;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;


dcb.fNull = TRUE; //Èãíîðèðîâàíèå íóëåâûõ áàéò ïðè ïðè¸ìå
dcb.fOutX = FALSE;
dcb.fInX = FALSE;

ct.ReadIntervalTimeout = D_TimeOutValue;
ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant = D_TimeOutValue;
ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant = D_TimeOutValue;

Port = CreateFile(D_COM_Name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if(Port == INVALID_HANDLE_VALUE)
{
Application->MessageBox(D_ComOpenError, D_Error, MB_OK+MB_ICONERROR);
ComPortClose();
return FALSE;
}

if(!SetCommState(Port, &dcb))
{
// Application->MessageBox(D_ComOpenError, D_Error, MB_OK+MB_ICONERROR);
// ComPortClose();
// return false;
}

if (!SetCommTimeouts(Port, &ct))
{
Application->MessageBox(D_ComOpenError, D_Error, MB_OK+MB_ICONERROR);
ComPortClose();
return FALSE;
}
else PortOpen = 1;

PurgeComm(Port, PURGE_RXABORT);
PurgeComm(Port, PURGE_TXCLEAR|PURGE_RXCLEAR);

Подскажите, пожалуста, как решить эту проблему. help.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
Yuriy_Rus
сообщение Aug 30 2006, 09:07
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 24-07-06
Пользователь №: 19 039



Предполагаю, что дело в настройках порта, но каких именно - чёрт его знает...
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Aug 30 2006, 09:16
Сообщение #3


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



У меня была аналогичная проблемма. Только устройство (не GPRS модем) и прога не висли, а просто не работали как надо. При этом существовала прога от производителя девайса с которым я хотел соединиться. Так вот если загрузить комп, и включить мою прогу, то не работало. Если после этого (или после включения компа) загрузить прогу от производителя, то она работает. И самое интересное, что работает потом и моя, но только до перезагрузки.
Ситуация оказалась следущая. DCB имеет дочерта параметров (около 25). Так вот, моя прога настраивала некоорые параметры, а некоторые оставляла по-умолчанию, в частности количество стоповых битов. Эти настройки сохраняются, даже после завершения проги, вплоть до перезагрузки. И вышло следующее. Мой девайс использовал 8 бит данных и 2 стоповых. А Винда изначально (у меня по крайней мере) давала 7 бит данных и один стоповый. Проверить это можно после перезагрузки Винды, запуска проги и в отладчике просмотреть поля DCB. И я не изменял эти параметры в своей проге! Поэтому моя прога не работала с девайсом. Затем я запускад прогу производителя она конфигурировала порт как надо для этого девайса. После закрытия проги настройки сохранялись и их можно было просмотреть опять запустив в отладчике прогу. Поэтому моя прога тоже после этого работала.
Извиняюсь что так длинно. Короче, посмотри на поля структуры DCB после загрузки Винды и после запуска ГиперТерминала. И сравни.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Aug 30 2006, 09:53
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Ошибка имхо в том, что Вы не заполняете ВСЕ поля структуры dcb. Если Вы не желаете изменять их(эти поля), то вызовите функцию GetCommState - она их заполнит, а затем измените те, что Вам нужны на необходимые значения.
Go to the top of the page
 
+Quote Post
Alexsys
сообщение Aug 30 2006, 10:09
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 8-08-06
Из: Москва
Пользователь №: 19 398



А на какой строчке прога подвисает??? Попробуйте её пошагово выполнить.

Я DCB заполняю следующим кодом:

Код
// настраиваем выбранный COM-порт
ZeroMemory(&dcb,sizeof(DCB));
dcb.DCBlength=sizeof(DCB);  // !!!!!!!!!
dcb.BaudRate=CBR_38400;
dcb.fBinary=TRUE;
dcb.fParity=FALSE;
dcb.fRtsControl=RTS_CONTROL_DISABLE;
dcb.fDtrControl=DTR_CONTROL_DISABLE;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;


Подобной проблемы у меня никогда небыло. Прога иногда подвисала при некорректном выключении прибора.
Go to the top of the page
 
+Quote Post
Yuriy_Rus
сообщение Aug 31 2006, 04:37
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 24-07-06
Пользователь №: 19 039



Цитата(Alexsys @ Aug 30 2006, 14:09) *
А на какой строчке прога подвисает??? Попробуйте её пошагово выполнить.

Я DCB заполняю следующим кодом:

Код
// настраиваем выбранный COM-порт
ZeroMemory(&dcb,sizeof(DCB));
dcb.DCBlength=sizeof(DCB);  // !!!!!!!!!
dcb.BaudRate=CBR_38400;
dcb.fBinary=TRUE;
dcb.fParity=FALSE;
dcb.fRtsControl=RTS_CONTROL_DISABLE;
dcb.fDtrControl=DTR_CONTROL_DISABLE;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;


Подобной проблемы у меня никогда небыло. Прога иногда подвисала при некорректном выключении прибора.


Можете подробнее рассказать про эти поля:

dcb.fRtsControl=RTS_CONTROL_DISABLE;
dcb.fDtrControl=DTR_CONTROL_DISABLE;

Насколько я знаю, fRtsContro задает режим управления потоком для сигнала RTS, а fDtrControl задает режим управления обменом для сигнала DTR. Но что это за сигналы я "в душе" не знаю...
Go to the top of the page
 
+Quote Post
Yuriy_Rus
сообщение Aug 31 2006, 04:54
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 24-07-06
Пользователь №: 19 039



Цитата(Alexsys @ Aug 30 2006, 14:09) *
А на какой строчке прога подвисает??? Попробуйте её пошагово выполнить.



На отправке-приёме команды...

Сообщение отредактировал Yuriy_Rus - Aug 31 2006, 04:56
Go to the top of the page
 
+Quote Post
Alexsys
сообщение Aug 31 2006, 07:38
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 8-08-06
Из: Москва
Пользователь №: 19 398



2 Yuriy_Rus

Я не совсем понял, прога виснет при попытке послать информацию в COM порт.

RTS - сигнал запроса передачи. Активен во все время передачи.
CTS - сигнал сброса (очистки) для передачи. Активен во все время передачи. Говорит о готовности приемника.
DTR - сигнал готовность к приему
DSR - сигнал готовности данных

Эти сигналы используются для аппаратного управления потоком (RTS-CTS or DTR-DSR handshake). Подробнее посмотри в книжке Гука "Интерфейсы ПК". Флаги RTS_CONTROL_DISABLE и DTR_CONTROL_DISABLE отключают использование аппаратного управления потоком.

Возможна проблема твоя в том, что ты не отчищаешь содержимое структуры DCB перед её заполнением. Я это делаю строкой ZeroMemory(&dcb,sizeof(DCB));
Go to the top of the page
 
+Quote Post
_Andu_
сообщение Aug 31 2006, 10:25
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 127
Регистрация: 11-07-06
Пользователь №: 18 735



У меня вот такая процедура открытия порта для COM порта.
И все работает только не для GPRS модема а для своих целей.
BOOL CSerial::Open( LPVOID dr )
{
BYTE ByteSize = 8; // number of bits/byte, 4-8
BYTE Parity = 0; // 0-4=no,odd,even,mark,space
BYTE StopBits = 0; // 0,1,2 = 1, 1.5, 2

CDriver *driver = (CDriver *)dr;
m_driver = dr;
int nPort = driver->kanal.port;
DWORD nBaud = driver->kanal.speed;
ByteSize = driver->kanal.ByteSize;
Parity = driver->kanal.Parity;
StopBits = driver->kanal.StopBits;


int rw = 3;
if( m_bOpened ) return( TRUE );

char szPort[15];
char szComParams[50];
DCB dcb;

wsprintf( szPort, "COM%d", nPort);


m_hIDComDev = CreateFile(szPort,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED | DDL_SYSTEM,
NULL);


if( m_hIDComDev == NULL ) return( FALSE );
DWORD yy = GetFileAttributes(szPort);

memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

DWORD b = driver->status.waitin + driver->status.waitout + driver->status.waitout_ + driver->status.timeout;// + 25;//driver->status.waitin;
DWORD c=driver->status.waitoutall;
DWORD a=driver->status.timeout;

COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0;//a;//0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;//10;
CommTimeOuts.ReadTotalTimeoutConstant = b;//100;
CommTimeOuts.WriteTotalTimeoutMultiplier = (15000/(nBaud));//c;//10;
CommTimeOuts.WriteTotalTimeoutConstant = 0xFFFFFFFF;//c;//50;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = ByteSize;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
//dcb.fNull=true;

/////////////////////////
dcb.fRtsControl = RTS_CONTROL_ENABLE;

/////////////////////////
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 1000, 1000 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL )
{
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
return( FALSE );
}
SetupComm(m_hIDComDev, 1024, 1024);

SetCommMask(m_hIDComDev,EV_ERR);
DWORD dwError;
ClearCommError( m_hIDComDev, &dwError, NULL);
m_bOpened = TRUE;

PurgeRx();
PurgeTx();
SetRTS(FALSE);

CString qqq;
qqq.Format("SHLPICR");
if(m_bOpened){qqq.Format("SHLPICR [COM%d]", driver->kanal.port);}
if(driver->mainWnd!=NULL)
((CWnd *)driver->mainWnd)->SetWindowText(LPCSTR(qqq));


return( m_bOpened );

}
Go to the top of the page
 
+Quote Post
Yuriy_Rus
сообщение Aug 31 2006, 11:30
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 24-07-06
Пользователь №: 19 039



Цитата(Alexsys @ Aug 31 2006, 11:38) *
2 Yuriy_Rus

Я не совсем понял, прога виснет при попытке послать информацию в COM порт.

RTS - сигнал запроса передачи. Активен во все время передачи.
CTS - сигнал сброса (очистки) для передачи. Активен во все время передачи. Говорит о готовности приемника.
DTR - сигнал готовность к приему
DSR - сигнал готовности данных

Эти сигналы используются для аппаратного управления потоком (RTS-CTS or DTR-DSR handshake). Подробнее посмотри в книжке Гука "Интерфейсы ПК". Флаги RTS_CONTROL_DISABLE и DTR_CONTROL_DISABLE отключают использование аппаратного управления потоком.

Возможна проблема твоя в том, что ты не отчищаешь содержимое структуры DCB перед её заполнением. Я это делаю строкой ZeroMemory(&dcb,sizeof(DCB));


Да, спасибо, скорее всего дело в том, что я не отключал использование аппаратного управления потоком. a14.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th June 2025 - 02:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01495 секунд с 7
ELECTRONIX ©2004-2016