串口上位机程序的编制_第1页
串口上位机程序的编制_第2页
串口上位机程序的编制_第3页
串口上位机程序的编制_第4页
串口上位机程序的编制_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、我们飞思卡尔智能车的比赛已经接近尾声了,23号就要去上海决赛了呵。论文基本完成,Duuboo已经排版结束,排出来还真挺长的。整个过程都挺累的,持续的时间还这么长,最累的恐怕只有惠哥了,这些比赛完再说吧。这里介绍下在Donald写的一个串口调试程序,主要是方便我们查看运行起来的小车的内部参数。程序的作用是接收来自Freescale MC9SDG128单片机发送来的数据,并显示出来。分为两部分。一部分是普通的数据,ASCII数据,另一部分是实时的图像,也是以ASCII方式传输。程序可通过“模式”按钮设置工作在这两种模式。当进入CCD模式时,通过“连接”按钮触发DG128单片机发送图像信息,这时“连

2、接”按钮变为“断开”,可通过其触发DG128单片机停止发送,降低单片机内部资源消耗。程序中串口部分的编程参考的是Visual C+串口通信技术与工程实践,李现勇编著。书中对串口的编程讲得很不错,除了C的,还有VB的。详细请参考该书。这里介绍本程序的一部分程序代码。一、添加串口控件本程序是在VC6下MFC实现,所以添加一个串口控件,方法是选择Project菜单下Add To Project子菜单中的 Components and Controls选项,在弹出的对话框中进入Registered ActiveX Controls目录,选择Microsoft Communications Contro

3、l, version 6.0,Insert到Project中就行了。然后可在窗体中添加串口控件,接着Ctrl+W到ClassWizard中为该控件添加一个对应的变量就行。二、串口工作方式的改变串口的工作方式有很多种,比如串口的选择、波特率、校验位、数据位和停止位等。这些的设置可以通过组合框实现,实现方法基本一样,Donald就以波特率说明下。之前已经为波特率组合框对象IDC_COMBO_BAUD添加对应变量m_cboBaud。在程序主窗体初始化时写有如下代码。 / combo Baud init m_cboBaud.AddString(_T("1200"

4、); m_cboBaud.AddString(_T("2400"); m_cboBaud.AddString(_T("4800"); m_cboBaud.AddString(_T("9600"); m_cboBaud.AddString(_T("115200"); m_cboBaud.SetCurSel(3); m_strBaud = _T("9600");再在ClassWizard中为IDC_COMBO_BAUD添加CBN_SELCH

5、ANGE消息处理函数,再在函数中添加代码。 switch (m_cboBaud.GetCurSel()  case 0:  m_strBaud = _T("1200");  break; case 1:  m_strBaud = _T("2400");  break; case 2:  m_strBaud = _T("4800");  break; case

6、 3:  m_strBaud = _T("9600");  break; case 4:  m_strBaud = _T("115200");  break; default:  m_strBaud = _T("9600");  InitCommPort(); 通过switch选择不同的波特率。case的顺序按照初始化添加时的顺序,开始为0。三、OnComm()消息处理函数在串口控件中,

7、最重要的就是OnComm()函数,这个函数是用来处理串口消息事件的,每当串口接收到数据,就会产生一个串口接收数据缓冲区中“有字符”的消息事件,只要在该函数内写好处理这些字符的代码就可以。在Donald的这个程序里,该程序代码如下。代码的结构(switch结构)是参考该书。 VARIANT variant_inp; COleSafeArray safearray_inp; CByteArray arraySend; LONG len,k; BYTE rxdata1024; /An 8-bit integer that is not signed

8、for Receive CString strAdd; int i; m_strComRcv.Empty(); switch(m_com.GetCommEvent()   case 1: / comEvSend  arraySend.RemoveAll();  arraySend.SetSize(m_strEditTrn.GetLength();  for (i = 0; i < m_strEditTrn.GetLength(); i+)  

9、0;  arraySend.SetAt(i, m_strEditTrn.GetAt(i);    m_com.SetOutput(COleVariant(arraySend);  break; case 2: / comEvReceive  variant_inp = m_com.GetInput();  / Read buffer  safearray_inp = variant_inp;  / VARIANT to Col

10、eSafeArray  len = safearray_inp.GetOneDimSize(); / Get effective length  / Store to EDIT_REV  for(k = 0; k < len; k+)     safearray_inp.GetElement(&k, rxdata + k); / Change to BYTE array   BYTE bt = *(char*)(rxdat

11、a+k);  / BYTE type   strAdd += bt;          if (m_bCcdMode = FALSE)   m_myEdit.AppendText(strAdd);   else   g_strRcv = strAdd;   g_bReceive = TRUE;    brea

12、k; default: / Error  m_com.SetOutBufferCount(0);  /AfxMessageBox("Com Err");  break; 使用控件编程就是相对简单,系统的串口消息发生时,程序自动调用该函数。由switch语句判断,参数1为发送,参数2为接收。Donald主要介绍下接收的思路,由于接收时有两种模式,所以通过m_bCcdMode成员变量记录这两种模式。当其为FALSE时直接实时显示在窗口右边,就像Windows处事的超级终端。如果是TRUE,则不显示,

13、将信息放到一个全局变量g_strRcv。其实尽量不要用全局变量,但Donald暂时也不懂线程间通信,只能简单这么做了。并置位全局变量g_bReceive。该变量是在CCD模式下一个线程处理的依据,实时显示图像。四、文本框实时显示和发送串口字符为了能实现Windows超级终端文本框的功能,我们必须手动修改Edit类,然后用CWnd:SubclassDlgItem提供的动态连接功能,将原来的文本框和修改的类连接起来。利用ClassWizard新建一个CEdit类自己命名(如CMyEdit),并在这个类中添加WM_CHAR消息处理函数和。确定后,再在新建类的头文件中手动添加void AppendTe

14、xt (LPCSTR pText)函数,用于将串口收到的字符输出在文本框中。以及添加CByteArray arraySend成员变量,用于显示字符的临时存储。Donald程序中,CMyEdit:AppendText(LPCSTR pText)的内容如下: int nLen = GetWindowTextLength ();  CString strTmp = pText; SetFocus ();  if(strTmp.GetAt(0) = (char)0X08)  SetSel (nLen - 1, nLen); 

15、0;strTmp.Delete(0);  Clear();  else  SetSel (nLen, nLen);   ReplaceSel (pText); 修改CMyEdit:OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)函数,该函数实现在文本控件中输入一字符时自动由串口向外发送。代码如下: arraySend.RemoveAll(); arraySend.SetSize(1); arraySend.SetAt(0, (char)nCha

16、r); (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->m_com.SetOutput(COleVariant(arraySend); /CEdit:OnChar(nChar, nRepCnt, nFlags); 程序的第四行语句必是向Donald的窗体串口控件关联变量m_com输出字符,注意要调用COleVariant()函数。五、实时接收图像线程众所周知,如果一个程序用了while(1)语句的话,那么这个程序将是一个死循环,将严重占用CPU资源,而这里,我们的程序又需要用while来实时地接收来自单片机的串口信息,于是

17、,最好的解决方法就是用线程。调用线程的思路是这样,当程序处于文本框模式时,线程是关闭的。如果进行CCD模式,还没“连接”,程序状态同上,如果进行“连接”状态,则创建实时接收线程,并设置一定时器以在一定时间未接收到来自串口的握手信号时自动断开。如果从“连接”状态手动或自动“断开”,则将线程终止,向单片机发送终止传送图像信号并关闭定时器。至此,完成显示图像流程。线程中首先是发送握手信号FS_CONNECTION。 arraySend.SetSize(1); arraySend.SetAt(0, FS_CONNECTION);  g_bOvertime = F

18、ALSE; / Send Connection Signal (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->m_com.SetOutput(COleVariant(arraySend); 然后无限循环等待接收,用了两层while语句,第一个等待来自单片机的握手信号,第二个处理接收图像。 while(1)   / Wait for receiving  (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->GetDlgItem(

19、IDC_STATIC_NOW)   ->SetWindowText("等待.");  g_bReceive = FALSE;  SetTimer(AfxGetApp()->GetMainWnd()->m_hWnd, 1, 1000, NULL);  g_bOvertime = TRUE;  while(!g_bReceive);   KillTimer(AfxGetApp()->GetMainWnd()->

20、m_hWnd, 1);  g_bReceive = FALSE;  g_bOvertime = FALSE;  if (-1 = g_strRcv.Find(FS_CONNECTION) / Not found   continue;  else   (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->GetDlgItem(IDC_STATIC_NOW)    ->SetW

21、indowText("连接完成, 接收中");   row = 0;   col = 0;   while(1)       SetTimer(AfxGetApp()->GetMainWnd()->m_hWnd, 1, 1000, NULL);    g_bOvertime = TRUE;    g_bReceive = FA

22、LSE;    while(!g_bReceive);    KillTimer(AfxGetApp()->GetMainWnd()->m_hWnd, 1);    g_bReceive = FALSE;    g_bOvertime = FALSE;    /AfxMessageBox(g_strRcv);    n = g_strRcv.Fi

23、nd(FS_TRANFINISH);    if(-1 = n) / Not finish     n = g_strRcv.GetLength();     for(i = 0; i < n; i+)      cRcvrowcol+ = g_strRcv.GetAt(i);      if(col = MAX_CCD_Y)

24、60;      col = 0;       if(+row = MAX_CCD_X)        row = 0;                      els

25、e  / Finish     /n = g_strRcv.Find(FS_TRANFINISH);     for(i = 0; i < n; i+)      cRcvrowcol+ = g_strRcv.GetAt(i);      if(col = MAX_CCD_Y)      &#

26、160;col = 0;       if(+row = MAX_CCD_X)        row = 0;                       (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->m_ccdGraph.ChangeBit(cRcv);     (CFSonPCDlg*)AfxGetApp()->m_pMainWnd)->GetDlgItem(IDC_STATIC_NOW)     

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论