做一个控制电机工作和监控的软件
需要不停的测转速并且从串口(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,不应该这样啊请求高手帮我分析分析到底是什么原因啊
谢谢!mfcRS-232串口

解决方案 »

  1.   

    ReceiveThread,这是个线程,不停的在运行,所以你收到的数据和这个线程里的COMDATAFlag不同步,你可以设个全局变量来同步这个变量,就是收到一次数据就更新这个COMDATAFlag变量值,你根据你的需要来决定怎么同步.
      

  2.   

    是这个原因么
    我在前面设置了一个DoneFlag呀,只有收到数据之后才能把它置1,它不置1就不会在另一个进程中再发消息了呀~~ 所以COMDATAFlag在串口没有数返回的时候是不会改变的,应该就是同步的
      

  3.   

    刚发现原因,你的break呢,每一个case结束后都要加break
    case 1:
    DoneFlag=0;
    COMDATAFlag++; 
    ::SendMessage(m_hwnd1,WM_USER+1,0,0); // 对应的消息处理函数为通过串口向控制器发送读取励磁电流的指令
    break;//加这句,其它的case结束后也这么加   
    case 2:
      

  4.   


    正解啊
    基础不扎实啊。。汗。。
    我分析了好久,发现是因为每次四个消息都依次发出去了,所以造成了问题。然后我改成IF-ELSE IF了,结果就正常工作了。
    我和师兄讨论的时候还大言不惭的黑人家“编译器有问题”。。原来忘加break了
    谢谢各位啦