工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
VC下用串口与电台通信需注意的问题
[文章信息]
作者:cc_011
时间:2005-02-24
出处:VCCode
责任编辑:方舟
[文章导读]
最近我在用电台对外发送数据以及接收数据的时候,遇到了一个很棘手的问题,最后用示波器才找到了解决问题的办法
advertisement
热点推荐
· 初学者的福音:游戏开发新手入门指南
· 原位升级 Win XP崩溃的救命稻草
· 微软拼音输入法超级技巧
· 发掘WinRAR的“自解压安装”功能
· 黑客突破防火墙常用的几种技术
[正文]
  最近我在用电台对外发送数据以及接收数据的时候,遇到了一个很棘手的问题,最后用示波器才找到了解决问题的办法,在此特写此文章,以避免大家再出现这样的问题而没法解决了,如有不对,还请多多指教.。

  其实用无线电台进行发送数据以及接收数据,只是对串口进行读写数据,但是有一点不同的是需要注意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();

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 剖析MFC六大关键技术之初始化过程
  • VC调用ACM音频编程接口压缩Wave音频
  • VC利用控件传递自定义struct解决方案
  • MFC程序员的WTL指南之包容ActiveX
  • 用递归算法解决VC中CEdit的一个Bug
  • 中国将从4月1日起收取电信网码号资源占用费
  • 信产部将整顿高清碟机标准 红头文件已印好
  • 九成手机贴牌商难迈核准制高门槛
  • 国信办副主任杨学山谈信息化发展三大问题
  • 海信赴德应诉在即 西门子称愿协商解决
  • AMD注1亿美元中国造芯片 3月2日正式投产
  • 陈天桥欲借外力打碎毒丸 段永基动向成谜
  • 中国有望成为诺基亚全球最大市场
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索