MicroCHIP.RU
Главная Документация Отладочные средства Справочник Поиск Ссылки
 Новости   Конференция   Контакты 
 

VC++ работа с PIC

 Нoвaя темa  |  Наверх  |  Перейти к теме  |  Поиск  |  Правила  |  Вход 

ВНИМАНИЕ!
Вы просматриваете архив форума.

Этот форум работает только в режиме просмотра и поиска.

Действующий форум переведен на новый движок и
находится по адресу www.microchip.su

 VC++ работа с PIC
Автор: Eugen3d ()
Дата:   04/08/2005 02:23

Сейчас занимаюсь написанием интерфейса на VC++ для работы с пиком через RS232. Сосбтвенно, довольно тяжело
разобратся в этих дебрях многопоточности/асинхронности/событиях для корректной работы с портом. Может, кто
сможет помочь документацией на эту тему или каким-то исходниками?
Заранее благодарен.


 
 Re: VC++ работа с PIC
Автор: Voron ()
Дата:   04/08/2005 06:24

Попробуйте найти дистрибутив BUILDER С++, сам BUILDER устанавливать не обязательно, поставте только
справку. Там хорошо все расписано по этой теме (Win32 SDK Reference). Может быть эта справка есть и
в VC++.


 
 Клич Ecole, он может помочь(-)
Автор: abivan ()
Дата:   04/08/2005 09:50

!


 
 В смысле помочь исходником? (+)
Автор: Ecole ()
Дата:   04/08/2005 11:27

В принципе могу. Только у меня очень наворочено, сложно будет разобраться.
Вот:

//файл ComPort.h
//********************************************************
#ifndef CPR_COMPORT_H
#define CPR_COMPORT_H

enum tag_COMPort_errors
{
  eCOMPortErrRead    = 128, //timeout or reading error
  eCOMPortErrCRC     = 129, //CRC error
  eCOMPortErrBlock   = 130, //see CComPort::SendBlock()
  eCOMPortErrWrite   = 131, //writing error
  //240...255 codes are reserved!
};

class CComPort
{
public:
  CComPort();
  virtual ~CComPort();

  //функция открывает порт
  // sPort - "COM1"..."COM4"
  // iBaudRate - скорость, например 9600
  bool  Open(TCHAR *sPort, int iBaudRate);

  //закрыть порт, открытый ранее Open()
  void  Close();

  //работать с CRC (при bCRC=true)
  void  EnableCRC(bool bCRC=true);   //true - checking CRC

  //установить таймаут
  void  SetTimeout(unsigned t);      //should be called before Open()

  //установить скорость
  void  SetBaudRate(int iBaudRate);

  //сброс
  void  Reset();

  //отправить байт
  void  SendByte(BYTE b);

  //отправить блок до 8 байт длиной
  //после отправки блока отправляется и CRC
  BYTE  SendBlock(BYTE *pb, BYTE type, int len); //len=8 bytes max!

  //принять байт
  BYTE  GetByte();

  //принять блок до 256 байт длиной (с контр.суммой)
  //при приема блока проверяется CRC
  const BYTE *GetBlock(int len=257); //len=256 bytes max!
                                     //if len>256 then len will be calculated

  BYTE  CalcCRC(BYTE *buff, int len);
  BYTE  GetCRC();

private:
  BYTE  CalcCRC(int len);

  HANDLE       m_hPort;
  DCB          m_dcb;
  COMMTIMEOUTS m_Timeout;
  BYTE         m_bBlock[256+4]; //Type,len,b0,b1,...b255,CRC,CRC1
  bool         m_bCRC;
};

#endif


//файл ComPort.cpp
//********************************************************
#include "cpr.h"

CComPort::CComPort()
{
  m_hPort = NULL;
  m_Timeout.ReadTotalTimeoutConstant = 5000;
  m_bCRC  = true; //enable CRC checking
}

CComPort::~CComPort()
{
}

bool CComPort::Open(TCHAR *sPort, int iBaudRate)
{
  m_hPort = CreateFile(sPort,GENERIC_READ|GENERIC_WRITE,
                       NULL,NULL,OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
                       NULL);
  if(m_hPort == INVALID_HANDLE_VALUE)
  {
    m_hPort = NULL;
    return false;
  }

  m_dcb.DCBlength         = sizeof(DCB);
  GetCommState(m_hPort,&m_dcb);
  m_dcb.BaudRate          = iBaudRate;
  m_dcb.fBinary           = TRUE;
  m_dcb.fParity           = FALSE;
  m_dcb.Parity            = NOPARITY;

  m_dcb.fOutxCtsFlow      = FALSE;
  m_dcb.fOutxDsrFlow      = FALSE;
  m_dcb.fDtrControl       = DTR_CONTROL_DISABLE;
  m_dcb.fDsrSensitivity   = FALSE;
  m_dcb.fTXContinueOnXoff = TRUE;
  m_dcb.fOutX             = FALSE;
  m_dcb.fInX              = FALSE;
  m_dcb.fErrorChar        = FALSE;
  m_dcb.fNull             = FALSE;
  m_dcb.fRtsControl       = RTS_CONTROL_ENABLE;
  m_dcb.fAbortOnError     = FALSE;
  
  m_dcb.ByteSize          = 8;
  m_dcb.StopBits          = ONESTOPBIT;
  SetCommState(m_hPort,&m_dcb);

  m_Timeout.ReadIntervalTimeout         = MAXDWORD;
  m_Timeout.ReadTotalTimeoutMultiplier  = MAXDWORD;
  //m_Timeout.ReadTotalTimeoutConstant    = 5000; //see SetTimeout()
  m_Timeout.WriteTotalTimeoutMultiplier = 1000;
  m_Timeout.WriteTotalTimeoutConstant   = 1000;
  SetCommTimeouts(m_hPort,&m_Timeout);

  //SetupComm(m_hPort,256*11,256); //buffer size
  return true;
}

void CComPort::Close()
{
  if(m_hPort != INVALID_HANDLE_VALUE && m_hPort)
  {
    CloseHandle(m_hPort);
    m_hPort = NULL;
  }
}

void CComPort::EnableCRC(bool bCRC)
{
  m_bCRC=bCRC;
}

void CComPort::SetTimeout(unsigned t)
{
  m_Timeout.ReadTotalTimeoutConstant = t;
}

void CComPort::SetBaudRate(int iBaudRate)
{
  GetCommState(m_hPort,&m_dcb);
  m_dcb.BaudRate = iBaudRate;
  SetCommState(m_hPort,&m_dcb);
}

void CComPort::Reset()
{
  if(!m_hPort) return;
  PurgeComm(m_hPort,PURGE_RXABORT|PURGE_RXCLEAR);
}

void CComPort::SendByte(BYTE b)
{
  DWORD dwWrite = 0;
  WriteFile(m_hPort,&b,1,&dwWrite,NULL);
}

//len = 1...8
//Block: type, len, b0,b1,...b7, CRC
BYTE CComPort::SendBlock(BYTE *pb, BYTE type, int len)
{
  int   i;
  DWORD dwWrite = 0;

  //prepare a block
  if(len>8 || len < 0) return eCOMPortErrBlock;
  m_bBlock[0]   = type;
  m_bBlock[1]   = len;
  for(i=0; i < len; i++) m_bBlock[ i+2 ] = pb[ i ];
  m_bBlock[ i+2 ] = CalcCRC(len+2);

  //send
  WriteFile(m_hPort,m_bBlock,len+3,&dwWrite,NULL);
  if((int)dwWrite != len+3) return eCOMPortErrWrite;
  return type;
}

BYTE CComPort::GetByte()
{
  BYTE  b;
  DWORD dwRead=0;

  ReadFile(m_hPort,&b,1,&dwRead,NULL);
  if(dwRead != 1) b = eCOMPortErrRead;
  return b;
}

//Input:  len = 1...256
//Return: type, len, b0,b1,...b255, CRC, CRC1
//        (CRC1 - calculating CRC)
//              if len==0  then len=256
//              if len > 256 then len will be calculated
const BYTE* CComPort::GetBlock(int len)
{
  DWORD dwRead = 0;
  BYTE  bCRC;
  int   i;

#ifdef _DEBUG
  for(i=0; i < 256+4; i++) m_bBlock[ i ]=0;
#endif

  //try to read len+3 bytes (type,len,data[ len ],CRC)
  for(i=0; i < len+3; i++)
  {
    ReadFile(m_hPort,m_bBlock+i,1,&dwRead,NULL);
    if(dwRead != 1)
    {
      m_bBlock[0] = eCOMPortErrRead;
      return m_bBlock;
    }
    if(len > 256 && i==1) //m_bBlock[1] - the length
    {
      len = m_bBlock[1];
    }
  }

  //check CRC
  bCRC = CalcCRC(len+2);
  if(bCRC != m_bBlock[len+2] && m_bCRC)
  {
    m_bBlock[0] = eCOMPortErrCRC;
  }

  m_bBlock[len+3] = bCRC;
  return m_bBlock;
}

static BYTE UpdateCRC(BYTE bCRC, BYTE b)
{
  BYTE i;

  for(i=8; i > 0; i--)
  {
    if((b ^ bCRC) & 1) bCRC = ((bCRC ^ 0x18) >> 1) | 0x80;
    else bCRC >>= 1;
    b >>= 1;
  }

  return bCRC;
}

BYTE CComPort::CalcCRC(BYTE *buff, int len)
{
  int  i;
  BYTE bCRC=0;

  for(i=0; i < len; i++)
  {
    bCRC=UpdateCRC(bCRC,buff[ i ]);
  }
  
  return bCRC;
}

BYTE CComPort::CalcCRC(int len)
{
  return CalcCRC(m_bBlock,len);
}

BYTE CComPort::GetCRC()
{
  BYTE len = m_bBlock[1];
  return m_bBlock[len+2];
}



Вообще-то я сначала посоветовал бы почитать статью Олега Титова про работу с СОМ-портами
(можно найти на www.rs232.ru). Там все очень хорошо расписано.
Если есть вопросы по С++ - это к Бьярну Страустраппу (создателю языка) и его книгам.
Если есть вопросы по Win32 API - лучше всего читать файл справки WIN32.HLP
(его можно взять, например из Delphi или C++ Builder), а также НАСТОЯТЕЛЬНО
рекомендую книгу Ч.Петзолда "Программирование для Windows 95".
Можно также почитать вот это: http://www5.domaindlx.com/cprime/lesson/dir2.htm
или одним куском: http://www5.domaindlx.com/cprime/lesson/chm/cpplessons.chm

------------------------------------------------------
http://www5.domaindlx.com/cprime/lesson/dir2.htm
http://www5.domaindlx.com/cprime/
обновление: новый раздел в Уроках С++

Отправка отредактированного (04/08/2005 11:35)


 
 Re: VC++ работа с PIC
Автор: SG house ()
Дата:   04/08/2005 13:55

Документация - известно, где - http://msdn.microsoft.com
В частности, по коммуникациям (порты последовательные, параллельные...) -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_resources.asp
Про многопоточность -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/processes_and_threads.asp

Сразу предупреждаю - там серьёзно и много!

Если Вы пользуетесь mfc в VC++, то для потоков там удобный обёрточный класс существует -
"CWinThread" -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwinthread.asp

Как вариант, для разработки софта можно вместо VC++ использовать CBuilder++. Моё личное мнение о нём
я оставлю при себе, однако он значительно упрощает разработку, скрывая большинство тонкостей.
Естественно, он в своей библиотеке VCL имеет "обёртку" для потоков, работать с которой может даже
первоклассник. Где-то в инете есть и готовые обёртки для COM-портов. Можно поискать на
http://www.codeguru.com где-либо ещё по словам "CBuilder" + "components" + "VCL".




 
 Мне тоже пригодится и от меня спасибо(-)
Автор: abivan ()
Дата:   04/08/2005 14:56

!


 
 Did I can use this code without endless loop in the Receive Thread?
Автор: Entuziast ()
Дата:   04/08/2005 16:18

Dopustim mne nado vse vremia gdat' byte iz Com-porta i otobragat' ego(kak v
Hyperteminal). Kak etim codom sdelat' eto bez beskonechnoi petli i timer-ov?

Sapienti sat


 
 Re: Did I can use this code without endless loop in the Receive Thread?
Автор: SG house ()
Дата:   04/08/2005 16:34

Пошло win32 программирование :)

Для ожидания байта из порта можно использовать два равносильных способа. Первый, использовать
структуру OVERLAPPED в последнем параметре API функции ReadFile, где указать в качестве маркера
события CALLBACK-функцию, сообщение или Event (тогда ReadFile возвращается сразу, не дожидаясь
окончания выполнения операции). В последнем случае для ожидания события можно использовать серию
функций WaitForXXXJbjects (например, WaitForSingleObject(...)) или MsgWaitForMultiplyObjects. Самое
простое - использовать в качестве маркера пользовательское сообщение, посылаемое главному окну
приложения, а уж там байт перекидывать, куда надо.
Второй способ, забить на OVERLAPPED и вынести ReadFile в отдельный поток, который будет принятые
байтики бережно складывать в организованный Вами буфер и сигнализировать об этом главному потоку
сообщениями или Event'ами, или ещё чем.




 
 Re: Did I can use this code without endless loop in the Receive Thread?
Автор: Ecole ()
Дата:   04/08/2005 16:40

Entuziast-у:
>Второй способ, забить на OVERLAPPED и вынести ReadFile в отдельный поток...
Именно так я и делаю. И мне кажется, этот способ лучше. По крайней мере
работает и под Win9x и под Win2k.

------------------------------------------------------
http://www5.domaindlx.com/cprime/lesson/dir2.htm
http://www5.domaindlx.com/cprime/
обновление: новый раздел в Уроках С++


 
 More depth, if possible please
Автор: Entuziast ()
Дата:   04/08/2005 16:51

About this:
> Первый, использовать
> структуру OVERLAPPED в последнем параметре API функции
> ReadFile, где указать в качестве маркера
> события CALLBACK-функцию, сообщение или Event (тогда ReadFile
> возвращается сразу, не дожидаясь
> окончания выполнения операции). В последнем случае для ожидания
> события можно использовать серию
> функций WaitForXXXJbjects (например, WaitForSingleObject(...))
> или MsgWaitForMultiplyObjects. Самое
> простое - использовать в качестве маркера пользовательское
> сообщение, посылаемое главному окну
> приложения, а уж там байт перекидывать, куда надо.
And this
> Второй способ, забить на OVERLAPPED и вынести ReadFile в
> отдельный поток, который будет принятые
> байтики бережно складывать в организованный Вами буфер и
> сигнализировать об этом главному потоку
> сообщениями или Event'ами, или ещё чем.
>


Or MSDN-links,

Sapienti sat


 
 Re: More depth, if possible please
Автор: Ecole ()
Дата:   04/08/2005 17:52

> Первый, использовать структуру OVERLAPPED....
Про первый способ рассказать не смогу, т.к. для этого потребуется написать
страниц 5 текста. Короче я не умею :)) Если кто сумеет объяснить короче,
пусть напишет.
Но этот способ кое-как описан в документе, о котором я уже писал. Ищите
на www.rs232.ru большую статью Олега Титова о программировании
СОМ-портов под Windows.

Второй способ - вынести ReadFile в отдельный поток. Если у вас уже
получается работать с портом обычным способом, т.е. через ожидание в
цикле, то так и работайте. А для того, чтобы это ожидание не мешало
работе остальной части программы, весь цикл вместе с функцией ReadFile
нужно вынести в отдельный поток.
У меня это делается примерно так:

//CMController - класс, в котором у меня полностью организована
//ВСЯ работа с контроллером (т.е.устройством на PIC) через СОМ-порт

//Эта функция используется для того, чтобы прочитать из контроллера
//данные и записать их в файл на компьютере.
//Функция делает единственное дело - создает отдельный поток - T_Rd()
void CMController::RdFromContr()
{
  DWORD dw;

  CreateThread(NULL,0,T_Rd,NULL,0,&dw);
}

//Функция T_Rd работает в отдельном потоке и выполняет всю работу
//по чтению данных из контроллера и запись их в файл на диске компьютера.
//Вызов функции ReadFile, которая собственно читает данные с СОМ-порта,
//спрятан глубоко в функции DataToFile.
//Функция DataToFile делает следующее:
//1) открывает порт (вызовом CComPort::Open)
//2) посылает нужные команды контроллеру (вызовом CComPort::SendByte
//   или CComPort::SendBlock
//3) принимает данные из контроллера (вызовом CComPort::GetBlock)
//
//Исходный текст функций класса CComPort см. в моем первом посте.
DWORD WINAPI CMController::T_Rd(LPVOID Params)
{
  if(m_this->DataToFile(m_this->m_sFileName))
  {
    //данные прочитаны и записаны в файл
    .....
  }
  else
  {
    //иначе - обработка ошибок
    .....
  }
  return 0;
}


Для того, чтобы нормально работать с потоками, нужно как минимум прочитать
соответствующую главу книги Ч.Петзольда, а еще лучше - прочитать об
этом более подробно в книге Д.Рихтера "Программирование в Win32 API
для Windows NT 3.5 и Windows 95". Есть и более свежая версия
этой же книги.
К сожалению, более подробно я объяснить просто не смогу - на это потребуется
много времени. Лучше все-таки прочитать это в книгах.

------------------------------------------------------
http://www5.domaindlx.com/cprime/lesson/dir2.htm
http://www5.domaindlx.com/cprime/
обновление: новый раздел в Уроках С++


 
 Thanks(-)
Автор: Entuziast ()
Дата:   04/08/2005 20:29

-

Sapienti sat


 
 Уже есть кое-что. [КОД]
Автор: Eugen3d ()
Дата:   04/08/2005 20:40

Благодарю за столь активное обсуждение - видно тема действительно интересная :)
Я для себя давно решил, что лучше сделать отдельный поток и синхронно принмать/отправлять данные. С
асинхронной работой я так и на разобрался.
Вот, что у меня есть:

В функции созданиея окна пишу код для открытия порта и дочерного потока:


BOOL CDefenceView::PreCreateWindow(CREATESTRUCT& cs)
{									
	char *SelPort = "COM2";
	DWORD nb;
	DCB dcb;
	hCom = CreateFile(SelPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
	if (hCom != INVALID_HANDLE_VALUE) {
		GetCommState(hCom, &dcb);
		dcb.BaudRate = 9600; 
		dcb.ByteSize = 8; 
		dcb.Parity = NOPARITY;
		dcb.StopBits = ONESTOPBIT;
		SetCommState(hCom, &dcb);
		COMMTIMEOUTS TOut;
		TOut.ReadIntervalTimeout = 50; 
		TOut.ReadTotalTimeoutMultiplier = 10; 
		TOut.ReadTotalTimeoutConstant = 50; 
		TOut.WriteTotalTimeoutMultiplier = 10;  
		TOut.WriteTotalTimeoutConstant = 50; 
	}

	PWinThread1=AfxBeginThread(TWork, hCom);

	return CScrollView::PreCreateWindow(cs);
}


Чуть выше этой функции пиши саму функцию потока (пока просто маячек):

UINT TWork(LPVOID pParam) {
      int Number=10;
	HANDLE hCom=pParam;
	DWORD nb;
	::WaitForSingleObject(t_Write, INFINITE);
	::ResetEvent(t_Write);
      AfxMessageBox("Work!");
//    WriteFile(hCom,&Number,2,&nb,NULL);
	return 0;
}


Ну и еще нужно глобально обьявить событие - чуть выше этого кода пишется следующее:
CEvent t_Write


А из основного потока нужно в нужные моменты времени устанавливать события для записи в порт:
::SetEvent(t_Write);



Собственно - это все, что у меня на данный момент есть :) Работает даже ;)


 
 Re: Уже есть кое-что. [КОД]
Автор: SG house ()
Дата:   04/08/2005 21:08

Ну, если уж совсем красиво делать, то Event "t_Write" надо автосбрасываемым создавать
(см. параметры
функции CreateEvent(...)). Тогда вместо 2 строчек

::WaitForSingleObject(t_Write, INFINITE);
::ResetEvent(t_Write);

можно будет только первую оставить.

Да, вспомнил, на сайте http://www.rsdn.ru очень много статей про программирование на
PC, и многие, как мне показалось, хорошие. Про порты: Статьи -> Базовые сервисы ->
COM,LPT.



Отправка отредактированного (04/08/2005 21:34)


 
 Еще вопрос
Автор: Eugen3d ()
Дата:   04/08/2005 22:37

Спасибо - буду исправлять :)
Сейчас вот столкнулся с 2 проблемами:
- как работать с PostMessage - как их принимать основным потоком и отправлять вторичным?
- как сделать синхронное ожидание с таймером?

По поводу ожидания - сама функция WaitCommEvent третим параметром принримает адрес на структуру
Overlapped. В моем случае я ставлю NULL (синхронная работа), но тогда происходит остановка потока до
появления сигнала в порте (а нужно завершить ожидание через секунду).
Как быть?


 
 ещё раз
Автор: patton ()
Дата:   04/08/2005 23:44

1.
сюда смотреть
http://www5.domaindlx.com/cprime/lesson/dir2.htm
принимает сообщения оконная процедура, дальше разные пути

2.
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dllproc/base/waitforsingleobject.asp

глянете и увидите

Ваше ожидание вторым параметром в мс


 
 Re: ещё раз
Автор: Eugen3d ()
Дата:   05/08/2005 00:13

Не все так просто - это я по поводу ожидания.
Вот мой код:

ov.hEvent=CreateEvent(NULL, 1, 1, NULL);
SetCommMask(hCom,EV_RXCHAR);
WaitCommEvent(hCom,&mask,&ov);
WaitForSingleObject(ov.hEvent, 200);
AfxMessageBox(\"a\");

Так вот, ожидание работает только тогда, когда порт открыт в асинхронном режиме. Если в синхронным - то не
работает (ждет бесконечно события). А мне нужно именно в синхронном режиме.


 
 и ещё
Автор: patton ()
Дата:   05/08/2005 00:29

я про WaitForSingleObject

и так вот там The function returns if the interval elapses, even if the
object's state is nonsignaled.
и это никак не связано в каком режиме у Вас открыт файл


 
 Re: и ещё
Автор: Eugen3d ()
Дата:   05/08/2005 01:20

WaitForSingleObject понятно, но перед этим еще нужно событие связать с сигналом в буфере порта:
SetCommMask(hCom,EV_RXCHAR);
WaitCommEvent(hCom,&mask,&ov);

Собственно, вторая функция моментально начинает ждать событие. Если асинхронные режим - тогда понятно,
оиждание идет в фоне, а поток продолжает работать. А если в синхронном режиме, то поток блокируется сразу
же после вызова этой функции. И ничем его не остановить ожидание кроме как натуральным сигналом от внешнего
устройства.


 
 Re: VC++ работа с PIC
Автор: Ig_B ()
Дата:   05/08/2005 12:01

А я использую Measurement Studio от National Instrument, весьма удобная штука. Там
есть и работа с компортами и отображение на графиках разных (надо же после
получения данных что-то с ними делать). Прием с компорта можно настроить на
бинарный или текстовый ввод, и после получения байта (строки символов) вызывается
функция что-то типа DataReady и там уже или отображаем (другими компонентами) или
записываем...


 
 Re: и ещё
Автор: Schneider ()
Дата:   05/08/2005 15:50

значит так, можно в потоке ждать ReadFile'ом настроив при этом таймауты

например:

	COMMTIMEOUTS *pcto = new COMMTIMEOUTS;
	pcto->ReadIntervalTimeout		= 20;
	pcto->ReadTotalTimeoutMultiplier	= 20;
	pcto->ReadTotalTimeoutConstant	= 200;
	pcto->WriteTotalTimeoutMultiplier	= 10;
	pcto->WriteTotalTimeoutConstant	= 100;
	SetCommTimeouts(g_hPort, pcto);
	delete[] pcto;



далее в цикле

	ok = ReadFile(m_hPort, (void *)&c, 1, &r, NULL);
	ok &= r == 1;
	if (ok)
	{
		Buf[ i] = c;



и тому подобное



Отправка отредактированного (05/08/2005 15:52)


 
 Re: VC++ работа с PIC
Автор: Schneider ()
Дата:   05/08/2005 15:53

это же не наш метод (c) расслабляет, опыта 0 итп :)


 
 Re: и ещё
Автор: Eugen3d ()
Дата:   05/08/2005 17:45

Спасибо - все теперь работает. Скажите, а как можно определить, произошло ли какое-то событие или нет?


 
 Траблс...
Автор: Eugen3d ()
Дата:   06/08/2005 20:00

Сталкнулся с непонятными проблемами. Открываю порт(асинхронный) и вызывается функция для работы:

WriteFile(hCom,&ToSend,1,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);	
Sleep(10);

WriteFile(hCom,&ToSend2,2,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);
Sleep(10);

Temp=1;
while (Temp!=0) {
 Temp=0;
 ov.hEvent=CreateEvent(NULL, 1, 1, NULL);
 SetCommMask(hCom,EV_RXCHAR); 
 WaitCommEvent(hCom,&mask,&ov);
 WaitForSingleObject(ov.hEvent, 500);
 ReadFile(hCom,&Temp,2,&nb,&ov);
 if (Temp!=0) Recives.Add(Temp);
}
::PostMessage(HWND(pParam),WM_USERMSGA,0,0);

WriteFile(hCom,&ToSend,1,&nb,&ov);
GetOverlappedResult(hCom,&ov,&nb,TRUE);	
Sleep(10);


Что она должна делать? Передать в порт однобайтное число (например 123), подождать, отправить двубайтное
число (123+16768), принять все, что идет с порта, отправить один байт (123).
Собственно, работает это через раз - наверняка из-за очень корявого кода. Подскажите, что исправить? :)