读书人

MFC串口读数无法正常更新界面

发布时间: 2013-03-29 14:24:52 作者: rapoo

紧急求助,MFC串口读数无法正常更新界面
做一个控制电机工作和监控的软件
需要不停的测转速并且从串口(RS-232)读控制器的参数,然后更新界面,但串口读回来的数据却总部能在要求的EDITBOX上显示,找了半天原因没找到,很苦恼。。

部分代码如下
void CLXJView::OnStart()
{//按下该按钮后开始工作

COMDATAFlag=1; //此变量为全局的变量,在一开始定义的,为了使消息正常发送
DoneFlag=1; //同上
Creat_TB(); //创建实验记录表单
MentorInitial(); //直流电机控制器初始化

///////////////////////////////////////////////
int* v;
AfxBeginThread(ReceiveThread,(LPVOID)v); //开新进程
}

UINT CLXJView::ReceiveThread(LPVOID v)
{

CLXJView *dlg=(CLXJView*) AfxGetApp()->GetMainWnd();
///////////////////////////////////////////////////
while(1)

{
//部分代码省略
if(DoneFlag==1)
{
switch(COMDATAFlag)
{case 1:
DoneFlag=0;
COMDATAFlag++;
::SendMessage(m_hwnd1,WM_USER+1,0,0); // 对应的消息处理函数为通过串口向控制器发送读取励磁电流的指令

case 2:
DoneFlag=0;
COMDATAFlag++;
::SendMessage(m_hwnd1,WM_USER+5,0 ,0); //给定电压
case 3:
DoneFlag=0;
COMDATAFlag++;
::SendMessage(m_hwnd1,WM_USER+7,0 ,0); //电枢电压
case 4:
DoneFlag=0;
COMDATAFlag=1;
::SendMessage(m_hwnd1,WM_USER+9,0 ,0); // 电枢电流

//构成循环;初始化中也同样置1.

defalut:
COMDATAFlag=1;
}
}
}

void CLXJView::OnOnCommMscomm()
{
// 串口返回消息的处理函数
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置 BYTE 数组 An 8-bit integerthat is not signed.
CString strtemp;
CString result;
BYTE bt,bt1,bt2;
if(m_MT.GetCommEvent()==2) //事件值为 2 表示接收缓冲区内有字符
{
variant_inp=m_MT.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT 型变量转换为 ColeSafeArray型变量

len=safearray_inp.GetOneDimSize(); //得到有效数据长度
//////////////转换为 BYTE 型数组
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//
////////////////////////////////////////////

//////////////////////////////////////////

int found=0; //返回数据常含无效数据,以此程序读出有效参数
for(k=0;k<=len && found==0;k++) // 只要第5位到第九位
{

bt=*(char*)(rxdata+k);//字符型 eg:02 30 30 31 31 xx 03 02 04 05 03


bt1=*(char*)(rxdata+k+10);
if(bt==2 && bt1==3)
{
for(int ava=6;ava<=9;ava++)
{
bt2=*(char*)(rxdata+k+ava);
strtemp.Format("%c",bt2); //将字符送入临时变量 strtemp 存放
result+=strtemp;

} //加入到result 变量中
found =1; // 找到有效数据后跳出循环
}
}

}

//根据标志位返回给相应的EDITBOX

switch (COMDATAFlag)
{
case 2: // 接受信息时已经完成自增,所以对应+1
m_LCDL=result; //对应相应的EDITBOX
m_M.Format("%f",m_Data[1]); //同时更新M N的显示
m_N.Format("%f",n_Data[1]);

case 3:
m_GDDY=result;
m_M.Format("%f",m_Data[1]); //同时更新M N的显示
m_N.Format("%f",n_Data[1]);

case 4:
m_DSDY=result;
m_M.Format("%f",m_Data[1]); //同时更新M N的显示
m_N.Format("%f",n_Data[1]);

case 1:
m_DSDL=result;
m_M.Format("%f",m_Data[1]); //同时更新M N的显示
m_N.Format("%f",n_Data[1]);

defalut: break;
}

UpdateData(false);
DoneFlag=1; // 接收完毕,恢复标志位

}

void CLXJView::MentorInitial()
{
//串口初始化程序
if(m_MT.GetPortOpen()) // 如果串口是打开的,则关闭串口
{
m_MT.SetPortOpen(FALSE);
}

//以下串口设定与VB中参数相同
m_MT.SetCommPort(1); // 选择COM1
m_MT.SetSettings("4800,E,7,1");// 数据采用偶校验,数据位数7,停止位1
m_MT.SetInBufferSize(1024); //接收缓冲区
m_MT.SetOutBufferSize(512);// 发送缓冲区
m_MT.SetOutBufferCount(0);
m_MT.SetInputLen(12);// 设置当前接收区数据长度为0, 表示全部读取
m_MT.SetInputMode(1);// 以二进制方式读写数据
m_MT.SetRThreshold(12);//RThreshold属性,表示在 OnComm 事件发生之前,接收缓冲区或发送缓冲区中可以接收的字符数


if(!m_MT.GetPortOpen())// 如果串口没有打开则打开
{
m_MT.SetPortOpen(TRUE);//打开串口
m_MT.SetInBufferCount(0); //清空数据缓存
//AfxMessageBox(_T("串口1打开成功")); //不做提示
}
else
{
m_MT.SetOutBufferCount(0);
AfxMessageBox(_T("串口1打开失败"));
}

}

如果按我的想法正常工作的话,是将每次返回的指令给对应的EDITBOX,就比如说读回来的是电枢电压那就赋给那个EDITBOX。 但现在工作起来的情况则是每次读回来的数据都给了m_DSDL对应的EDITBOX,不应该这样啊

请求高手帮我分析分析到底是什么原因啊
谢谢! mfc RS-232 串口
[解决办法]
ReceiveThread,这是个线程,不停的在运行,所以你收到的数据和这个线程里的COMDATAFlag不同步,你可以设个全局变量来同步这个变量,就是收到一次数据就更新这个COMDATAFlag变量值,你根据你的需要来决定怎么同步.
[解决办法]
最好的做法就是单步走一次试试。。。
[解决办法]
刚发现原因,你的break呢,每一个case结束后都要加break
case 1:
DoneFlag=0;
COMDATAFlag++;
::SendMessage(m_hwnd1,WM_USER+1,0,0); // 对应的消息处理函数为通过串口向控制器发送读取励磁电流的指令
break;//加这句,其它的case结束后也这么加
case 2:

[解决办法]
嗯,加break;

读书人网 >VC/MFC

热点推荐