Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14506384
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 20:59:17

下载本文示例代码
  最近我在用电台对外发送数据以及接收数据的时候,遇到了一个很棘手的问题,最后用示波器才找到了解决问题的办法,在此特写此文章,以避免大家再出现这样的问题而没法解决了,如有不对,还请多多指教.。  其实用无线电台进行发送数据以及接收数据,只是对串口进行读写数据,但是有一点不同的是需要注意RTS(Request to send),一般情况下我们在用电台发送数据的之前的时间把RTS置为Enable,但这个时间不能太长,然后发送完毕的时候再设Disable, 我在写程序的时候 ,就有一个这样的错误。  在没有发送完数据的时候,就把RTS设为 Disable,这样导致数据没有被完整的发送完毕,但RTS置的时间不能太长,不然表示常发数据,时间长了,会把电台烧坏的.写串口用的是大家都很熟悉的CSerialPort ,我在些基础改了一些东西。  下面的一开始的是发送一个字节的数据所需的时间(ms), 首先是算出你发送一个字节的数据实际是多少个位,假设数据长度是8个位,一个起始位,一个终止位,如果有校验位的话,就是11位,算出每个字节所需的时间,这里这个RTS Enable 的时间应该稍比算出来的时间长一点,下面还有一些自己写的方法,以有用电台写数据的代码: BOOL CSerialPort::InitPort(CWnd *pPortOwner,UINT portnr/* =-1 */,UINT baud/* =19200 */,char parity/* =’N’ */,UINT databits/* =8 */,UINT stopbits/* =1 */,DWORD dwCommEvents/* =EV_RXCHAR|EV_CTS */,UINT nBufferSize/* =512 */){ assert(portnr > 0 && portnr < 5); assert(pPortOwner != NULL); //Calculate the time that delay time. int nTotalBits =0; nTotalBits =databits; nTotalBits =stopbits; if (parity!=’N’)  nTotalBits =1;  //Add a start bit.  nTotalBits =1;  //Use millisecond unit.  nTotalBits*=1000;  nTotalBits =baud;  m_uElapseTime = nTotalBits/baud;  // if the thread is alive: Kill  if (m_bThreadAlive)  {   do   {    SetEvent(m_hShutdownEvent);   } while (m_bThreadAlive);   TRACE("Thread endedn");  }  // create events  if (m_ov.hEvent != NULL)   ResetEvent(m_ov.hEvent);   m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  if (m_hWriteEvent != NULL)   ResetEvent(m_hWriteEvent);   m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  if (m_hShutdownEvent != NULL)   ResetEvent(m_hShutdownEvent);   m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  // initialize the event objects  m_hEventArray[0] = m_hShutdownEvent; // highest priority  m_hEventArray[1] = m_ov.hEvent;  m_hEventArray[2] = m_hWriteEvent;  // initialize critical section  InitializeCriticalSection(&m_csCommunicationSyn);  // set buffersize for writing and save the owner  m_pOwner = pPortOwner;  if (m_szWriteBuffer != NULL)   delete [] m_szWriteBuffer;   m_szWriteBuffer = new BYTE[nBufferSize];  m_nPortNr = portnr;  m_nWriteBufferSize = nBufferSize;  m_dwCommEvents = dwCommEvents;  BOOL bResult = FALSE;  char *szPort = new char[50];  char *szBaud = new char[50];  // now it critical!  EnterCriticalSection(&m_csCommunicationSyn);  // if the port is already opened: close it  if (m_hComm != NULL)  {   CloseHandle(m_hComm);   m_hComm = NULL;  }  // prepare port strings  sprintf(szPort, "COM%d", portnr);  sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);  TRACE("%sn",szBaud);  // get a handle to the port  m_hComm = CreateFile(szPort, // communication port string (COMX)    GENERIC_READ | GENERIC_WRITE, // read/write types    0, // comm devices must be opened with exclusive access    NULL, // no security attributes    OPEN_EXISTING, // comm devices must use OPEN_EXISTING    FILE_FLAG_OVERLAPPED, // Async I/O    0); // template must be 0 for comm devices  if (m_hComm == INVALID_HANDLE_VALUE)  {   // port not found   delete [] szPort;   delete [] szBaud;   return FALSE;  }  // set the timeout values  m_CommTimeouts.ReadIntervalTimeout = 1000;  m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;  m_CommTimeouts.ReadTotalTimeoutConstant = 1000;  m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;  m_CommTimeouts.WriteTotalTimeoutConstant = 1000;  // configure  if (SetCommTimeouts(m_hComm, &m_CommTimeouts))  {    if (SetCommMask(m_hComm, dwCommEvents))   {    if (GetCommState(m_hComm, &m_dcb))    {     m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!     if (BuildCommDCB(szBaud, &m_dcb))     {      if (SetCommState(m_hComm, &m_dcb))       ; // normal operation... continue      else       ProcessErrorMessage("SetCommState()");     }     else      ProcessErrorMessage("BuildCommDCB()");     }     else     {      ProcessErrorMessage("GetCommState()");     }    }    else     ProcessErrorMessage("SetCommMask()");    }    else     ProcessErrorMessage("SetCommTimeouts()");     delete [] szPort;     delete [] szBaud;     // flush the port     PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);      // release critical section     LeaveCriticalSection(&m_csCommunicationSyn);      TRACE("Initialisation for communicationport %d completed.nUse Startmonitor to communicate.n", portnr);     return TRUE;}void CSerialPort ::SetRTSEnable(){ if (m_hComm == NULL) return; GetCommState(m_hComm,&m_dcb); if (m_dcb.fRtsControl ==RTS_CONTROL_ENABLE) return; else {  //Set the RTS enable.   m_dcb.fRtsControl =RTS_CONTROL_ENABLE;   SetCommState(m_hComm,&m_dcb); }}void CSerialPort ::SetRTSDisable(){ if (m_hComm == NULL) return; GetCommState(m_hComm,&m_dcb); if (m_dcb.fRtsControl ==RTS_CONTROL_DISABLE) return; else {  //Set the RTS enable.  m_dcb.fRtsControl =RTS_CONTROL_DISABLE;  SetCommState(m_hComm,&m_dcb); }}//Get the RTS state .If I send data need a few time.BOOL CSerialPort ::GetRTSState(){ if (m_hComm == NULL) return FALSE; DCB dcb; GetCommState(m_hComm,&dcb); if (dcb.fRtsControl == RTS_CONTROL_ENABLE)  return TRUE; else if (dcb.fRtsControl == RTS_CONTROL_DISABLE)   return FALSE; else return FALSE;}//Return the Elpase time that by the wireless.UINT CSerialPort::GetSleepTime(){ return m_uElapseTime;}//How to send data use wireless main station.pFrame->m_pWireLessPort[j].SetRTSEnable();Sleep(dwSleepTime);pFrame->m_pWireLessPort[j].WriteToPort(pti->pData,pti->nDataLen);//At 2005/1/20’s afternoon .When I send data by the wireless.//At first ,I send data to the terminal ,the terminal receive//data,but the terminal don’t back me any data.I don’t know how to// deal with this problem.Finally ,the terminal designner Mr.Liu//use the oscillograph ,then found Because the RTS enable time is too short.//so that I don’t finish send data compeletly .So the the data that the terminal has//received is not a integrated data.Although the terminal receive data//but it is not a valid data .After I send data .then I need a few time to sleep.//Get the baund of the COM.DWORD dwSleepTime = pti->nDataLen*pFrame->m_pWireLessPort[j].GetSleepTime() 10;Sleep(dwSleepTime);pFrame->m_pWireLessPort[j].SetRTSDisable();   最近我在用电台对外发送数据以及接收数据的时候,遇到了一个很棘手的问题,最后用示波器才找到了解决问题的办法,在此特写此文章,以避免大家再出现这样的问题而没法解决了,如有不对,还请多多指教.。  其实用无线电台进行发送数据以及接收数据,只是对串口进行读写数据,但是有一点不同的是需要注意RTS(Request to send),一般情况下我们在用电台发送数据的之前的时间把RTS置为Enable,但这个时间不能太长,然后发送完毕的时候再设Disable, 我在写程序的时候 ,就有一个这样的错误。  在没有发送完数据的时候,就把RTS设为 Disable,这样导致数据没有被完整的发送完毕,但RTS置的时间不能太长,不然表示常发数据,时间长了,会把电台烧坏的.写串口用的是大家都很熟悉的CSerialPort ,我在些基础改了一些东西。  下面的一开始的是发送一个字节的数据所需的时间(ms), 首先是算出你发送一个字节的数据实际是多少个位,假设数据长度是8个位,一个起始位,一个终止位,如果有校验位的话,就是11位,算出每个字节所需的时间,这里这个RTS Enable 的时间应该稍比算出来的时间长一点,下面还有一些自己写的方法,以有用电台写数据的代码: BOOL CSerialPort::InitPort(CWnd *pPortOwner,UINT portnr/* =-1 */,UINT baud/* =19200 */,char parity/* =’N’ */,UINT databits/* =8 */,UINT stopbits/* =1 */,DWORD dwCommEvents/* =EV_RXCHAR|EV_CTS */,UINT nBufferSize/* =512 */){ assert(portnr > 0 && portnr < 5); assert(pPortOwner != NULL); //Calculate the time that delay time. int nTotalBits =0; nTotalBits =databits; nTotalBits =stopbits; if (parity!=’N’)  nTotalBits =1;  //Add a start bit.  nTotalBits =1;  //Use millisecond unit.  nTotalBits*=1000;  nTotalBits =baud;  m_uElapseTime = nTotalBits/baud;  // if the thread is alive: Kill  if (m_bThreadAlive)  {   do   {    SetEvent(m_hShutdownEvent);   } while (m_bThreadAlive);   TRACE("Thread endedn");  }  // create events  if (m_ov.hEvent != NULL)   ResetEvent(m_ov.hEvent);   m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  if (m_hWriteEvent != NULL)   ResetEvent(m_hWriteEvent);   m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  if (m_hShutdownEvent != NULL)   ResetEvent(m_hShutdownEvent);   m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  // initialize the event objects  m_hEventArray[0] = m_hShutdownEvent; // highest priority  m_hEventArray[1] = m_ov.hEvent;  m_hEventArray[2] = m_hWriteEvent;  // initialize critical section  InitializeCriticalSection(&m_csCommunicationSyn);  // set buffersize for writing and save the owner  m_pOwner = pPortOwner;  if (m_szWriteBuffer != NULL)   delete [] m_szWriteBuffer;   m_szWriteBuffer = new BYTE[nBufferSize];  m_nPortNr = portnr;  m_nWriteBufferSize = nBufferSize;  m_dwCommEvents = dwCommEvents;  BOOL bResult = FALSE;  char *szPort = new char[50];  char *szBaud = new char[50];  // now it critical!  EnterCriticalSection(&m_csCommunicationSyn);  // if the port is already opened: close it  if (m_hComm != NULL)  {   CloseHandle(m_hComm);   m_hComm = NULL;  }  // prepare port strings  sprintf(szPort, "COM%d", portnr);  sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);  TRACE("%sn",szBaud);  // get a handle to the port  m_hComm = CreateFile(szPort, // communication port string (COMX)    GENERIC_READ | GENERIC_WRITE, // read/write types    0, // comm devices must be opened with exclusive access    NULL, // no security attributes    OPEN_EXISTING, // comm devices must use OPEN_EXISTING    FILE_FLAG_OVERLAPPED, // Async I/O    0); // template must be 0 for comm devices  if (m_hComm == INVALID_HANDLE_VALUE)  {   // port not found   delete [] szPort;   delete [] szBaud;   return FALSE;  }  // set the timeout values  m_CommTimeouts.ReadIntervalTimeout = 1000;  m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;  m_CommTimeouts.ReadTotalTimeoutConstant = 1000;  m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;  m_CommTimeouts.WriteTotalTimeoutConstant = 1000;  // configure  if (SetCommTimeouts(m_hComm, &m_CommTimeouts))  {    if (SetCommMask(m_hComm, dwCommEvents))   {    if (GetCommState(m_hComm, &m_dcb))    {     m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!     if (BuildCommDCB(szBaud, &m_dcb))     {      if (SetCommState(m_hComm, &m_dcb))       ; // normal operation... continue      else       ProcessErrorMessage("SetCommState()");     }     else      ProcessErrorMessage("BuildCommDCB()");     }     else     {      ProcessErrorMessage("GetCommState()");     }    }    else     ProcessErrorMessage("SetCommMask()");    }    else     ProcessErrorMessage("SetCommTimeouts()");     delete [] szPort;     delete [] szBaud;     // flush the port     PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);      // release critical section     LeaveCriticalSection(&m_csCommunicationSyn);      TRACE("Initialisation for communicationport %d completed.nUse Startmonitor to communicate.n", portnr);     return TRUE;}void CSerialPort ::SetRTSEnable(){ if (m_hComm == NULL) return; GetCommState(m_hComm,&m_dcb); if (m_dcb.fRtsControl ==RTS_CONTROL_ENABLE) return; else {  //Set the RTS enable.   m_dcb.fRtsControl =RTS_CONTROL_ENABLE;   SetCommState(m_hComm,&m_dcb); }}void CSerialPort ::SetRTSDisable(){ if (m_hComm == NULL) return; GetCommState(m_hComm,&m_dcb); if (m_dcb.fRtsControl ==RTS_CONTROL_DISABLE) return; else {  //Set the RTS enable.  m_dcb.fRtsControl =RTS_CONTROL_DISABLE;  SetCommState(m_hComm,&m_dcb); }}//Get the RTS state .If I send data need a few time.BOOL CSerialPort ::GetRTSState(){ if (m_hComm == NULL) return FALSE; DCB dcb; GetCommState(m_hComm,&dcb); if (dcb.fRtsControl == RTS_CONTROL_ENABLE)  return TRUE; else if (dcb.fRtsControl == RTS_CONTROL_DISABLE)   return FALSE; else return FALSE;}//Return the Elpase time that by the wireless.UINT CSerialPort::GetSleepTime(){ return m_uElapseTime;}//How to send data use wireless main station.pFrame->m_pWireLessPort[j].SetRTSEnable();Sleep(dwSleepTime);pFrame->m_pWireLessPort[j].WriteToPort(pti->pData,pti->nDataLen);//At 2005/1/20’s afternoon .When I send data by the wireless.//At first ,I send data to the terminal ,the terminal receive//data,but the terminal don’t back me any data.I don’t know how to// deal with this problem.Finally ,the terminal designner Mr.Liu//use the oscillograph ,then found Because the RTS enable time is too short.//so that I don’t finish send data compeletly .So the the data that the terminal has//received is not a integrated data.Although the terminal receive data//but it is not a valid data .After I send data .then I need a few time to sleep.//Get the baund of the COM.DWORD dwSleepTime = pti->nDataLen*pFrame->m_pWireLessPort[j].GetSleepTime() 10;Sleep(dwSleepTime);pFrame->m_pWireLessPort[j].SetRTSDisable(); 下载本文示例代码


VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题VC下用串口与电台通信需注意的问题
阅读(212) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~