последовательное устройство игнорирует EscapeCommFunction с C - PullRequest
0 голосов
/ 22 января 2011

Я мигрирую (наконец) из MSDOS в Windows XP для управления счетчиком через последовательный порт. Мой старый код C DOS работает нормально.

Я хочу сделать следующее:

  • метр постоянно снимает показания каждые несколько секунд, но не отправляет информация, пока она не будет запрошена компьютер
  • когда компьютер готов к приему информация от метра, он запрашивает это. В противном случае информация не принимается.

Моя проблема в том, что показания просто поступают в компьютер, поскольку они генерируются счетчиком.

Я установил параметры serail DCB следующим образом, намереваясь управлять связью, используя RTS и DTR:

dcbSerialParams.BaudRate=CBR_4800;
dcbSerialParams.ByteSize=7;
dcbSerialParams.StopBits=TWOSTOPBITS;
dcbSerialParams.Parity=EVENPARITY;
dcbSerialParams.fDtrControl=DTR_CONTROL_ENABLE;
dcbSerialParams.fRtsControl=RTS_CONTROL_ENABLE;

Мой старый код под DOS был таким:

 outportb(COM1+4,0x03);  /* start Minolta reading */   

 for(j=0;j<=10;j++) /*each reading consists of 11 ascii characters*/
  {
  while(!((inportb(COM1+5)) & 1)); /*wait until char received*/
  reading[j]=inportb(COM1);
  }
 sscanf ( &reading[4], "%f", &lum[k] );

 outportb(COM1+4,0x00);  /* stop Minolta reading */

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

void serial_notready(void)
{
EscapeCommFunction(hSerial,CLRDTR);
EscapeCommFunction(hSerial,CLRRTS);
}

void serial_ready(void)
{
EscapeCommFunction(hSerial,SETDTR);
EscapeCommFunction(hSerial,SETRTS);
}

int serial_read(char reading[])
{
DWORD dwBytesRead = 0;
int nbytes=11;
ReadFile(hSerial, reading, nbytes, &dwBytesRead, NULL);
return(dwBytesRead);
}

serial_ready(void);
x = 0; while(x == 0){x=serial_read(reading);}
serial_notready(void);

ОДНАКО, Minolta не ждет получения RTS с компьютера. Он просто идет вперед и отправляет показания, когда каждый становится доступным. В то же время компьютер не отклоняет нежелательное чтение, а принимает его.

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

Обновление:

Основная история заключается в том, что я представляю заданную яркость (яркость) на дисплее, а затем мне нужно соответствующее значение яркости. Это сделано для всего набора яркостей.

L   ---
U      ---
M         ---
     TIME

Я представляю lum1, lum2, lum3, lum4, .... Если измерения не синхронизированы с дисплеем, то я могу получить предполагаемое чтение 3, которое на самом деле является lum2, или какое-то среднее значение, потому что чтение перешло границу между дисплеями lum2 и lum3. И, как вы сказали, Ганс, показания всегда будут отставать от яркости дисплея. Даже если бы я всегда систематически читал одно чтение, это было бы плохо (моя ситуация еще хуже - это случайная связь между чтением и яркостью).

Таким образом, поведение последовательных окон Windows для меня - кошмар. Еще раз спасибо за помощь!

Ответы [ 3 ]

2 голосов
/ 22 января 2011
dcbSerialParams.fDtrControl=DTR_CONTROL_ENABLE; 
dcbSerialParams.fRtsControl=RTS_CONTROL_ENABLE;

Вы сразу активируете сигналы DTR и RTS. Счетчик сразу начнет отправку данных, когда вы откроете порт. Эти данные буферизируются в буфере приема драйвера. У вас не было буфера раньше в коде DOS. Это зависит от того, сколько времени вам потребуется для вызова serial_notready (). У вас будет довольно полный буфер, если это займет секунду или около того. Да, это выглядит так, будто прибор просто отправляет данные. И вы всегда читаете старый образец.

Начните со значения DCB, установленного на DISABLE. Остерегайтесь того, что схема хрупкая, вы можете довольно надежно отключить сигнал обратно в DOS. Теперь у вас есть водитель между ними. Вы можете в конечном итоге выключить RTS слишком поздно. Который рискует получить несвежее чтение. Альтернативой является запуск потока, который просто читает непрерывно. И пусть ваш основной код просто использует последнее прочитанное значение. Накладные расходы довольно низкие, последовательные порты медленные.

0 голосов
/ 24 января 2011

Я использую бесплатный сторонний эмулятор последовательного порта VPS. у него есть таймер интервального запроса, который определяет, когда данные должны быть обновлены / собраны. также позвольте мне регистрировать пакеты шины в файл Excel.

0 голосов
/ 22 января 2011

Первое, что нужно сделать, это проверить возвращаемые значения вызовов на EscapeCommFunction(). Если возвращаемое значение равно нулю , вызов не состоялся, и вы должны использовать GetLastError() для получения дополнительной информации об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...