串口上位机程序的编制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我们飞思卡尔智能车的比赛已经接近尾声了,23号就要去上海决赛了呵。论文基本完成,Duuboo已经排版结束,排出来还真挺长的。
整个过程都挺累的,持续的时间还这么长,最累的恐怕只有惠哥了,这些比赛完再说吧。这里介绍下在Donald写的一个串口调试程序,主要是方便我们查看运行起来的小车的内部参数。
程序的作用是接收来自Freescale MC9SDG128单片机发送来的数据,并显示出来。分为两部分。一部分是普通的数据,ASCII数据,另一部分是实时的图像,也是以ASCII方式传输。程序可通过“模式”按钮设置工作在这两种模式。当进入CCD模式时,通过“连接”按钮触发DG128单片机发送图像信息,这时“连接”按钮变为“断开”,可通过其触发DG128单片机停止发送,降低单片机内部资源消耗。
程序中串口部分的编程参考的是《Visual C++串口通信技术与工程实践》,李现勇编著。书中对串口的编程讲得很不错,除了C的,还有VB的。详细请参考该书。这里介绍本程序的一部分程序代码。
一、添加串口控件
本程序是在VC6下MFC实现,所以添加一个串口控件,方法是选择Project菜单下Add To Project子菜单中的 Components and Controls选项,在弹出的对话框中进入Registered ActiveX Controls目录,选择Microsoft Communication s Control, version 6.0,,Insert到Project中就行了。然后可在窗体中添加串口控件,接着Ctrl+W到ClassWizard中为该控件添加一个对应的变量就行。
二、串口工作方式的改变
串口的工作方式有很多种,比如串口的选择、波特率、校验位、数据位和停止位等。这些的设置可以通过组合框实现,实现方法基本一样,Donald就以波特率说明下。
之前已经为波特率组合框对象IDC_COMBO_BAUD添加对应变量m_cboBaud。在程序主窗体初始化时写有如下代码。
// combo Baud init
m_cboBaud.AddString(_T("1200"));
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_SELCHANGE消息处理函数,再在函数中添加代码。
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 3:
m_strBaud = _T("9600");
break;
case 4:
m_strBaud = _T("115200");
break;
default:
m_strBaud = _T("9600");
}
InitCommPort();
通过switch选择不同的波特率。case的顺序按照初始化添加时的顺序,开始为0。
三、OnComm()消息处理函数
在串口控件中,最重要的就是OnComm()函数,这个函数是用来处理串口消息事件的,每当串口接收到数据,就会产生一个串口接收数据缓冲区中“有字符”的消息事件,只要在该函数内写好处理这些字符的代码就可以。
在Donald的这个程序里,该程序代码如下。代码的结构(switch结构)是参考该书。
VARIANT variant_inp;
COleSafeArray safearray_inp;
CByteArray arraySend;
LONG len,k;
BYTE rxdata[1024]; //An 8-bit integer that is not signed for Receiv e
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++)
{
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 ColeSafeArray
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 ar ray
BYTE bt = *(char*)(rxdata+k); // BYTE type
strAdd += bt;
}
if (m_bCcdMode == FALSE){
m_myEdit.AppendText(strAdd);
} else{
g_strRcv = strAdd;
g_bReceive = TRUE;
}
break;
default: // Error
m_com.SetOutBufferCount(0);
//AfxMessageBox("Com Err");
break;
}
使用控件编程就是相对简单,系统的串口消息发生时,程序自动调用该函数。由switch语句判断,参数1为发送,参数2为接收。Donald主要介绍下接收的思路,由于接收时有两种模式,所以通过m_bCcdMode成员变量记录这两种模式。当其为FALSE时直接实时显示在窗口右边,就像Windows处事的超级终端。如果