做一个控制电机工作和监控的软件
需要不停的测转速并且从串口(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串口
需要不停的测转速并且从串口(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串口
解决方案 »
- 词典类软件要用到数据库吗?
- 谁有blowfish的测试数据?16进制字符串的,不用多,一个就行!
- 控件不能添加变量了
- SDI程序中一个文件能不能打开数次?
- 急急!MFC中ActiveX项目中插入一个内置控件为什么不显示
- 谁有比较好一点的“工作周报”的文档模板或表格。
- 请教一个有关win2k自动安装的问题
- 谁有Serv-U 3.0的注册码? 如何注册?(112分!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
- MFC中Picture怎么加载Buffer中的图片?
- 在VC中使用ADO,其中的Execute是怎么用的?它的第二个参数VARIANT *RecordsetAffected是什么玩意?
- 关于richedit的问题,求大神!
- ADO方式下,VC调用Execute执行插入int型数据的insert语句怎么写?
我在前面设置了一个DoneFlag呀,只有收到数据之后才能把它置1,它不置1就不会在另一个进程中再发消息了呀~~ 所以COMDATAFlag在串口没有数返回的时候是不会改变的,应该就是同步的
case 1:
DoneFlag=0;
COMDATAFlag++;
::SendMessage(m_hwnd1,WM_USER+1,0,0); // 对应的消息处理函数为通过串口向控制器发送读取励磁电流的指令
break;//加这句,其它的case结束后也这么加
case 2:
正解啊
基础不扎实啊。。汗。。
我分析了好久,发现是因为每次四个消息都依次发出去了,所以造成了问题。然后我改成IF-ELSE IF了,结果就正常工作了。
我和师兄讨论的时候还大言不惭的黑人家“编译器有问题”。。原来忘加break了
谢谢各位啦