Организация работы программы с Rs232
Может кто подскажет, как организовать работу программы с ком – портом?
Я имею в виду не подключение, а именно то, как считывать с порта информацию динамически.
В общем, есть прибор (допустим дозиметр), который постоянно подает сигнал на порт.
Есть программа на основе диалога, на котором есть (например) edit box, который в свою очередь показывает значение прибора.
Вот функция, с помощью которой я открываю порт
bool ComOpen (int comNum)
{
ComClose ();
char commName[5];
strcpy(commName,"com1");
commName[3]=comNum+'0';
DCB dcb;
COMMTIMEOUTS timeouts;
DWORD dwError;
BOOL fSuccess;
m_hComm = CreateFile(commName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (m_hComm == INVALID_HANDLE_VALUE)
{
dwError = GetLastError();
MessageBox(0,"COM open error, code=%lu\n","",MB_OK|MB_ICONSTOP);
return false;
}
fSuccess = SetupComm(m_hComm, 128, 128);
if (!fSuccess)
{
dwError = GetLastError();
MessageBox(0,"SetupComm failure, code=%lu\n","",MB_OK|MB_ICONSTOP);
return false;
}
fSuccess = GetCommState(m_hComm, &dcb);
if (!fSuccess)
{
dwError = GetLastError();
MessageBox(0,"GetCommState error, code=%lu\n","",MB_OK|MB_ICONSTOP);
return false;
}
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = 1;
dcb.fParity = 0;
dcb.fOutxCtsFlow = 0;
dcb.fOutxDsrFlow = 0;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = 0;
dcb.fTXContinueOnXoff = TRUE;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fNull = 0;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fAbortOnError = 0;
fSuccess = SetCommState(m_hComm, &dcb);
if (!fSuccess)
{
dwError = GetLastError();
MessageBox(0,"SetCommState failure, code=%lu\n","",MB_OK|MB_ICONSTOP);
return false;
}
timeouts.ReadIntervalTimeout=100;
timeouts.ReadTotalTimeoutMultiplier=1;
timeouts.ReadTotalTimeoutConstant=0;
timeouts.WriteTotalTimeoutMultiplier=0;
timeouts.WriteTotalTimeoutConstant=0;
fSuccess = SetCommTimeouts(m_hComm, &timeouts);
if (!fSuccess)
{
dwError = GetLastError();
MessageBox(0,"SetCommTimeouts failure, code=%lu","",MB_OK|MB_ICONSTOP);
return false;
}
return true;
}
Я ее еще ни разу не пользовался, может она и неправильная.
Мои предположения:
1) При инициализации диалога открываю порт;
2) По таймеру (допустим каждые 100 мс) считываю данные с порта (каким образом не знаю, может, кто подскажет?) и обновляю переменную, связанную с edit box;
3) При закрытии диалога вызываю функцию CloseComm();
bool ComClose ()
{
bool res = false;
if (m_hComm != NULL)
{
res = CloseHandle(m_hComm);
}
if (res)
{
m_hComm = NULL;
}
return res;
}
заранее всем благодарен.
в параметрах команды указывается буфер куда считать, количество байт для считывания и указатель на переменную, в которую по завершении команды занесется число несчитанных байтов.
метод простой - сначала вызываешь ReadFile для считывания 1 байта, например, потом в переменной несчитанных байтов получаешь общее количество байтов в буфере.
вызываешь второй раз ReadFile с точным числом байтов для считывания.
надеюсь, разберешься, если нет - пример в конце дня скину.
В остальном все так по инициализации, и закрытию порта. Проверь таймауты, которые по 0, это не есть хорошо.
Цитата:
Originally posted by xelos
считывание происходит по команде ReadFile,
в параметрах команды указывается буфер куда считать, количество байт для считывания и указатель на переменную, в которую по завершении команды занесется число несчитанных байтов.
метод простой - сначала вызываешь ReadFile для считывания 1 байта, например, потом в переменной несчитанных байтов получаешь общее количество байтов в буфере.
вызываешь второй раз ReadFile с точным числом байтов для считывания.
надеюсь, разберешься, если нет - пример в конце дня скину.
В остальном все так по инициализации, и закрытию порта. Проверь таймауты, которые по 0, это не есть хорошо.
считывание происходит по команде ReadFile,
в параметрах команды указывается буфер куда считать, количество байт для считывания и указатель на переменную, в которую по завершении команды занесется число несчитанных байтов.
метод простой - сначала вызываешь ReadFile для считывания 1 байта, например, потом в переменной несчитанных байтов получаешь общее количество байтов в буфере.
вызываешь второй раз ReadFile с точным числом байтов для считывания.
надеюсь, разберешься, если нет - пример в конце дня скину.
В остальном все так по инициализации, и закрытию порта. Проверь таймауты, которые по 0, это не есть хорошо.
Не помню я в ReadFile переменной несчитанных байтов. Вот сколько реально считано - есть. Поэтому надо смотреть, как именно передает прибор, и в соответствии с этим выставлять правильные значения в COMMTIMEOUTS, DCB и ReadFile.
Цитата:
Originally posted by Kalitkin
Привет всем!
bool ComOpen (int comNum)
{
ComClose ();
char commName[5];
strcpy(commName,"com1");
commName[3]=comNum+'0'; // !!!!!!!!!!!
Привет всем!
bool ComOpen (int comNum)
{
ComClose ();
char commName[5];
strcpy(commName,"com1");
commName[3]=comNum+'0'; // !!!!!!!!!!!
Мне кажется, что в строке, которую я пометил, есть несколько кривостей:
1. ты не сделал преобразование comNum из int в char.
2. ты хочешь на место одного char положить два символа: comNum и '0'
3. символ конца строки надо класть по-другому: commName[...] = NULL;