怎样把vc6的MSComm控件接受的数据实时的显示在编辑框,并把数据实时存入txt文件中
我在做一个基于VC6的MSComm控件的电机上位机控制,数据帧格式采用9600bps,8位数据位,奇校验,1位停止位,下位机每次发送16位数据,(16位是分两次发送吗??),高两位代表指令,后14位代表实际的数据,例如“00”代表的是发送的是转速数据,后14位才是转速的实际值。我现在要用vc++6.0的MSComm控件接受数据,把每次接受的数据要正确的显示在编辑框,并且要把每次的数据实时存入到不同的txt文件中。下面是我写的部分的代码,由于下位机还没有好。不知道写正确了没有,我是新手,望各位指导,共同学习。
CFile m_file(_T("data.txt"),CFile::modeCreate|CFile::modeWrite);//创建一个data.txt文件??
CFile m_file2(_T("data2.txt"),CFile::modeCreate|CFile::modeWrite);//创建一个data2.txt文件??
int savespeed,savecurrent;//savespeed是存入data.txt的全局变量,savecurrent是存入data2.txt的全局变量
//下面是MSComm控件的消息响应函数
void CreceiveDlg::OnOnCommMscomm()
{
VARIANT variant_in;
COleSafeArray safearray_in;
short m_data,m_flag;
long k,len,l_COM;
BYTE r_data[1024];//设置BYTE数组
CString temp, strtemp;
if(m_ctrlComm.GetCommEvent()==2)
{
variant_in=m_ctrlComm.GetInput();//读缓冲区数据,设置一个字符触发OnComm事件
safearray_in=variant_in;//类型转换
len=safearray_in.GetOneDimSize();//得到有效数据长度??
for(k=0;k<len;k++)
safearray_in.GetElement(&k,r_data+k);//转换成BYTE型数组,8-bit
l_COM=len;//一次从缓冲区接受的数据长度??
}
//下面是把16位数据整合为一个有效的数据,各位大神,帮看看,不知道对不对?
//下面这个if语句应该放在上面的if语句内部还是就是放在外部??也模糊
if(l_COM==2)
{
m_data=(r_data[0]<<8)+r_data[1];//把接受的原始16位赋给一个整数??
}
//下面得到高两位的控制指令
m_flag=(m_data&0xc000)>>14;//得到高两位指令,不知道对不对??
switch(m_flag)
{
case 0:
{
CString str_speed;
short speed;
speed=m_data<<2;
speed=m_data>>2;//右移两位,左移两位把高两位置“00”得到后14位
//下面把该次接受的实时数据存入data.txt文件,不知道对不对??
savespeed=speed;//把要存的值赋给全局变量savespeed,savespeed是要存入txt的变量
savespeed+=" ";//隔开两个位置
savespeed+="\r\n";//换行
m_file.Write(savespeed,savespeed.GetLength());//写到文件中
savespeed="";//清空,以便下次继续写入
//以下是把该次转速赋给编辑框关联的变量?
str_speed.Format("d%",speed);//把speed以字符形式给临时变量
m_speed=str_speed;//m_speed位编辑框关联的变量
break;
}
case 1:
{
CString str_current;
short current;
current=m_data<<2;
current=m_data>>2;//右移两位,左移两位把高两位置“00”
//下面把该次接受的实时数据存入data2.txt文件,不知道对不对??
savecurrent=current;//把要存的值赋给全局变量savecurrent,savecurrent是要存入txt的变量
savecurrent+=" ";//隔开两个位置
savecurrent+="\r\n";//换行
m_file2.Write(savecurrent,savecurrent.GetLength());//写到文件中
savecurrent="";//清空,以便下次继续写入
//以下是把该次电流赋给编辑框关联的变量?
str_curreent.Format("d%",current);//把current以字符形式给临时变量
m_current=str_current;//m_current位编辑框关联的变量
break;
}
case 2:
{
//待写
}
}
//更新编辑框
UpdataData(False);
} vc++ MSComm 串口通信 实时显示 存入TXT
[解决办法]
“每次发送16位数据”
是 2个 字节(16位)还是 16 字节?
如果是 2个字节,要分 高低 字节 的 顺序。
MSComm 要设置为 BINARY 模式。
你这个 协议,很难 找到消息的开始,通常协议是:
开始标记 如 (0x68 ’h‘); 长度,数据,检验和。
可以看看 MODBUS 协议
[解决办法]
基本没问题,你程序里是按先发高位后发低位处理处理的。但这需要单片机发送不能太快,不然,你可能会收到超过2个字节以上的数据,如果超过两上2个字节,就需要两两判断(前提是接收到正确的数据)。最好定信协议,报文头+长度+命令号+数据+校验,这样就算收到多个报文也可以进行正确解析,否则就会解析错
[解决办法]
这个只管发送数据和接受数据就可以了!
发:0xFF,0xFF
接受:0xFF,0xFF
[解决办法]
"由物理层去实现"
硬件只 对 一个 字节 进行 奇偶 校验。
软件是对 所有 字节 校验。
MODBUS 有2种 格式, ASCII 或 RTU。
RTU 占 字节 少, 但 发送 时 有 时间 限制,(2个 字节 间 ,间隔时间 《 3.5 T)
仔细看看 协议。
[解决办法]
m_flag=(m_data&0xc000)>>14;//得到高两位指令,不知道对不对??
这里最好是先位移, 再取位.
m_flag=(m_data>>14)&0xC000; 避免符号位产生问题.
如果下位机程序没有写好, 可以使用回环的串口线来自己测试.
写一个模拟下位机的程序. 或者使用虚拟机模拟串口都可以.
[解决办法]
那个 T 表示 发送一个 字节的 时间, 与 波特率 有关。
按协议 不会 只有 2字节。
先要 读地址。。。。
http://bbs.csdn.net/topics/360101535
帖子里有 代码参考