串口软件是电子相关工程师经常会用到的,虽然网上有众多的串口软件,但是,有时候并一定适合
自己的应用,因此,针对与特殊应用,我们依然需要根据实际去改造串口软件,下面是使用VC6.0中
的MFC编写的串口程序,该程序仅仅实现了基本功能,如果实际应用,还需要使用者自行更改。
1:首先添加好串口控件
在对话框中,点击鼠标右键,选中“插入Active X控件”,然后选则Microsoft Communications Control version6.0
控件后在对话框中出现串口控件
2:遍历能够使用的COM口并按顺序显示在组合框中,并定义组合框变量m_Box
BYTE i;
m_Box.SetCurSel(0); //设置当前组合框索引
for(i = 1; i < 17; i++)
{
port.Format(_T("\\\\.\\COM%d"), i);
hCom = CreateFile(port.GetBuffer(0), 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(INVALID_HANDLE_VALUE != hCom )
{
CloseHandle(hCom);
m_Box.AddString(port.Mid(4));
}
}
3:通过组合框中选择串口,然后触发组合框的选中事件(::OnSelendokCombo1()),在里面完成串口初始化
BYTE serail = FASLE;
void CRFTestDlg::OnSelendokCombo1()
{
// TODO: Add your control notification handler code here
CString port,str;
BYTE sel;
/*close the open serial port*/
if(serail == TRUE)
{
m_Msc.SetPortOpen(FALSE); //如果串口已经打开,先关闭
}
m_Box.GetLBText(m_Box.GetCurSel(), str);
sel = atoi(str.Mid(3));
m_Msc.SetCommPort(sel);
if(!m_Msc.GetPortOpen())
{
m_Msc.SetPortOpen(TRUE);
serail = TRUE;
m_Static1.SetWindowText("OK!");
}
else
{
serail = FALSE;
m_Static1.SetWindowText("Error!");
}
if(serail == TRUE)
{
m_Msc.SetSettings("9600,n,8,1");
m_Msc.SetInputMode(1); //二进制
//m_Msc.SetInputMode(0); //以字符格式接收,注意字符接收数据的处理与二进制是不一样的
//m_Msc.SetInBufferSize(1024); //默认1024
//m_Msc.SetOutBufferSize(1024);
m_Msc.SetRThreshold(1); //一个字节引发一次事件
m_Msc.SetInputLen(0);
m_Msc.GetInput();
}
}
4:发送5个串口数据
BYTE test[10] = {0x01,0x02,0x03,0x04,0x05};
BYTE i;
COleVariant value;
CByteArray OutBuf;
OutBuf.SetSize(5);
for(i = 0 ; i < 12; i++)
{
OutBuf = delet_all;
}
value = OutBuf;
m_Msc.SetOutput(value);
5:串口数据接收
如果串口收到数据,会触发comm事件,事件代码为2
以十六进制接收
BYTE RxData[256];
BYTE RxPos;
BYTE RxTimeOut ;
void CRFTestDlg::OnOnCommMscomm1()
{
// TODO: Add your control notification handler code here
VARIANT getrxbuf; //任意类型
COleSafeArray rx_save;
LONG k,len;
if(m_Msc.GetCommEvent() == 2)
{
getrxbuf = m_Msc.GetInput();
rx_save = getrxbuf;
RxTimeOut = 2; //用于接收超时判断
len = rx_save.GetOneDimSize(); //得到有效数据长度
for(k=0;k < len; k++,RxPos++)
{
rx_save.GetElement(&k,RxData+RxPos);//转换为BYTE型数组
}
}
}
以字符格式接收
CString strRxdt ;
BYTE RxTimeOut;
void CRFTestDlg::OnOnCommMscomm1()
{
// TODO: Add your control notification handler code here
VARIANT getrxbuf; //任意类型
if(m_Msc.GetCommEvent() == 2)
{
getrxbuf = m_Msc.GetInput();
strRxdt += getrxbuf.bstrVal;
RxTimeOut = 3;
}
}
6:硬件定时器的使用(软件定时器不太准)
6.1)在RFTestDlg.cpp文件中添加如下头文件,并把定时器使用的库包含进去,如图所示
#include "MMSystem.h"
#include "windows.h"
#pragma comment(lib, "winmm.lib")
定义一个全局变量
MMRESULT TimerId;
定义好定时器的回调函数
void CALLBACK TimeProc(UINT uID, UINT uMsg,DWORD dwUser, DWORD dw1, DWORD dw2)
{
if (uID==TimerId)
{
if(RxTimeOut)
{
RxTimeOut--;
if(RxTimeOut == 0)
{
//处理接收到的数据
}
}
}
}
在对话框中初始化函数中注册一个硬件定时器
TimerId = timeSetEvent(1000,0,TimeProc,0,TIME_PERIODIC); //初始化一个一直周期运行的定时器,定时间隔1000ms
程序的运行结果:
源码下载(源码与上述过程略有不同,但是思路是一致的):
https://pan.baidu.com/s/1S4M9l_DTbHgCh2tSZaBB3w
|