|||
两个程序一样的,只是使用的串口不同:一个使用COM3,一个使用COM4
COM3,COM4是计算机上添加的一对虚拟串口
打开两个程序,它们之间可以通信:一方请求数据,一方回应数据
请求数据帧格式: 帧长度(6),命令特征码(00H),起始值,字节数,增量,检验和
回应数据帧格式: 帧长度, 数据特征码(FFH),……数据场……,检验和
程序设计概述
界面设计(纸上画出界面图)
制作界面(在对话框中添加控件,控件布局,命名ID,为控件添加变量)
全局常数和变量定义,
函数声明和打框架(未实现的部分使用“占位符”)
逐步实现
结合串口调试助手调试
代码如下(工程名RS232,字节通信)
/////////////////////////////////////////////////////////////////////
// 常数定义及全局变量说明
unsigned char RxData[1024]; // 接收数据存储区
static int SavePointer=0; // 数据存储指针
unsigned char TxData[1024]; // 发送数据存储区
// 初始化对话框 中 初始化串口
BOOL CRS232Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
……
// TODO: Add extra initialization here
// 增加:串口初始化代码
m_Comm.SetCommPort(4); //
if(!m_Comm.GetPortOpen()) //
m_Comm.SetPortOpen(TRUE);
m_Comm.SetInputMode(1); // 设置输入方式为二进制方式 )
m_Comm.SetSettings("4800, n, 8, 1"); // 设置波特率等参数
m_Comm.SetRThreshold(1); // 当串口接收缓冲区中有≥1个字符时将引发一个
// 关于接收数据Oncomm事件
m_Comm.SetInputLen(0); // 每次读取缓冲区中 所有数据
m_Comm.GetInput(); // 先预置缓冲区以清除残留数据
//_________________________________________________________
return TRUE; // return TRUE unless you set the focus to a control
}
// 发送按钮单击消息响应
void CRS232Dlg::OnButtonTrans()
{
// TODO: Add your control notification handler code here
// 为发送按钮添加鼠标单击消息处理函数
UpdateData(TRUE); // 获取用户输入的数据
TxData[0]=0x06; // 命令帧长度为6
TxData[1]=0x00; // 命令帧特征码为00H
TxData[2]=m_Init; // 指定数据初始值
TxData[3]=m_Size; // 指定数据长度值
TxData[4]=m_Step; // 指定数据增量值
Transmitt(); // 发送命令
}
// 发送函数
void CRS232Dlg::Transmitt()
{
int i;
unsigned char sum=0, count;
CByteArray array; // 定义字节数组
count=TxData[0]; // 帧长度
for(i=0; i<count-1; i++) // 计算无进位校验和
sum+=TxData;
TxData[count-1]=sum;
array.RemoveAll(); ////
array.SetSize(count);
for(i=0; i<count; i++) // 待发送数据放入字节数组
array.SetAt(i, TxData);
if(!m_Comm.GetPortOpen()) // 打开串口
m_Comm.SetPortOpen(TRUE);
m_Comm.SetOutput(COleVariant(array)); // 由字节数组获得变体类型变量,放入发送缓冲区
// 显示发送的数据
char str[10];
m_Tdata="";
for(i=0; i<count; i++)
{
sprintf(str, "%02X,", TxData); // HEX格式
m_Tdata+=str;
}
UpdateData(FALSE);
}
// 串口消息响应函数
void CRS232Dlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT vResponse;
int k;
if(m_Comm.GetCommEvent()==2) // 如果是接收事件
{
k=m_Comm.GetInBufferCount(); // 接收缓冲区中数据长度
if(k>0)
{
m_Comm.SetInputLen(k); // 设置读取长度
vResponse=m_Comm.GetInput();// 读接收缓冲区
SavaData(k,(unsigned char*)vResponse.parray->pvData); // 存储数据(自定义函数)
}
}
}
// 保存接收到的数据
void CRS232Dlg::SavaData(int count, unsigned char *pbval)
{
int i;
for(i=0; i<count; i++)
RxData[SavePointer+i]=pbval;
SavePointer+=count;
if(SavePointer>=RxData[0]) // 接收到一帧,处理
ProcessData();
}
// 接收数据处理
// 最后的代码显示有点紊乱,它是怕断断续续接收两帧,顾及第2帧吧。
void CRS232Dlg::ProcessData()
{
int i, count;
unsigned char sum=0;
char str[10];
count=RxData[0];
for(i=0; i<count-1; i++)
sum+=RxData;
if(sum!=RxData[count-1])
{
MessageBox("ERROR! 接收数据检验和错误!");
m_Comm.SetOutBufferCount(0); //
SavePointer=0;
}
else
{
int len;
unsigned char step;
// MessageBeep(0xFFFFFFFF); ////
// system("pause");
if(RxData[1]==0) // 命令帧的特征码
{
TxData[0]=RxData[3]+3; // 数据帧长度(帧长度,特征码,数据,检验和)
TxData[1]='\xFF'; // 数据帧特征码为FFH
TxData[2]=RxData[2]; // 数据初值
len=RxData[3]; // 数据长度
step=RxData[4]; // 数据增量
for(i=3; i<TxData[0]-1; i++)
TxData=TxData[i-1]+step;
// 显示接收数据
for(i=0; i<count; i++) //
{
sprintf(str, "%02X,", RxData);
m_Rdata+=str;
}
// 发送请求的数据
Transmitt();
}
m_Rdata="";
for(i=0; i<count; i++) //
{
sprintf(str, "%02X,", RxData);
m_Rdata+=str;
}
UpdateData(FALSE);
for(i=0; i<SavePointer-count; i++) //
RxData=RxData[count+i];
SavePointer-=count; //
}
}