CAN接口卡读取数据线程问题?
点击“启动CAN”按钮会开启“CAN接收数据”线程,1. 但是记得《VC++深入详解》这本书上介绍过:只有主线程处于睡眠状态时,辅助线程才工作,但是OnBtnStartcan()函数中没有Sleep();那么ReceiveThread怎么还会工作,此时,能将数据显示在列表控件中;
2. 如果将红色部分的Sleep(8000)不注释的话,列表控件要等8秒钟才会有显示,这是什么原因?
3. 红色部分的Sleep(500)和Sleep(1)只是停顿作用吧?
void CCOMMUNICATIONSet::OnBtnStartcan() //“启动CAN”按钮
{
// TODO: Add your control notification handler code here
if(m_connect==1) //如果已经连接
{
m_connect=0;
m_startcanlight.SetIcon(m_hIConGrey1);
Sleep(500);
GetDlgItem(IDC_EDIT_BTR)->EnableWindow(!m_connect);
GetDlgItem(IDC_EDIT_STARTID)->EnableWindow(!m_connect);
GetDlgItem(IDC_EDIT_ENDID)->EnableWindow(!m_connect);
GetDlgItem(IDC_COMBO_BAUD)->EnableWindow(!m_connect);
GetDlgItem(IDC_COMBO_FILTER)->EnableWindow(!m_connect);
GetDlgItem(IDC_COMBO_MODE)->EnableWindow(!m_connect);
OnSelchangeComboBaud();
OnSelchangeComboFilter();
GetDlgItem(IDC_BTN_STARTCAN)->SetWindowText("启动CAN");
VCI_ResetCAN(m_devtype,m_devind,m_cannum);
VCI_CloseDevice(m_devtype,m_devind);// 此函数用以关闭设备。
return;
}
//如果未连接
VCI_INIT_CONFIG init_config;//定义初始化CAN的数据类型的结构体
int index,mode,cannum,baud;
UpdateData(true);//控件的值->变量
index=m_ComboIndex.GetCurSel();//设备索引号
mode=m_ComboMode.GetCurSel();//工作模式
cannum=m_ComboCANInd.GetCurSel();//第几路CAN
sscanf(m_strBTR, _T("%x"), &baud);
m_devind=index;//设备类型
m_cannum=cannum;//第几路CAN
UpdateData(false);//变量值->控件显示
init_config.Mode=mode;//模式
//滤波设置
DWORD filterMode=m_ComboFilterMode.GetCurSel();//"滤波模式"
if (filterMode!=2)
{
VCI_FILTER_RECORD filterRecord;
filterRecord.ExtFrame=filterMode;
UpdateData(TRUE);//控件的值->变量
DWORD IDtemp;
IDtemp=atoi(m_strStartID);//"滤波范围起始帧ID"字符转换为整形
//_stscanf_s(m_strStartID, _T("%d"), &IDtemp);
filterRecord.Start = IDtemp;//Start:滤波范围的起始帧ID
IDtemp=atoi(m_strEndID);//"滤波范围结束帧ID"字符转换为整形
//_stscanf_s(m_strEndID, _T("%d"), &IDtemp);
filterRecord.End= IDtemp;//End:滤波范围的结束帧ID
VCI_SetReference(m_devtype, m_devind, cannum, 1, &filterRecord);// 设置报文滤波。为1表示操作成功,0表示操作失败
//使滤波表格生效
if (VCI_SetReference(m_devtype, m_devind, cannum, 2, NULL)!=STATUS_OK)//参数类型为2????????????????????
{
MessageBox(_T("设置滤波失败!"), _T("警告"), MB_OK | MB_ICONQUESTION);
VCI_CloseDevice(m_devtype,index);
return;
}
}
m_connect=1;
GetDlgItem(IDC_EDIT_BTR)->EnableWindow(!m_connect);//不激活"自定义波特率寄存器"编辑框
GetDlgItem(IDC_EDIT_STARTID)->EnableWindow(!m_connect);//不激活"滤波范围起始帧ID"编辑框
GetDlgItem(IDC_EDIT_ENDID)->EnableWindow(!m_connect);//不激活"滤波范围结束帧ID"编辑框
GetDlgItem(IDC_COMBO_BAUD)->EnableWindow(!m_connect);//不激活"波特率"组合框
GetDlgItem(IDC_COMBO_FILTER)->EnableWindow(!m_connect);//不激活"滤波模式"组合框
GetDlgItem(IDC_COMBO_MODE)->EnableWindow(!m_connect);//不激活"工作模式"组合框
GetDlgItem(IDC_BTN_STARTCAN)->SetWindowText("关闭CAN");//改变控件的文本内容
m_startcanlight.SetIcon(m_hIConGreen1);
VCI_StartCAN(m_devtype,m_devind,m_cannum);
AfxBeginThread(ReceiveThread,this);//启动线程,ReceiveThread为线程函数
//Sleep(8000);
}
UINT CCOMMUNICATIONSet::ReceiveThread(void *param)//接收CAN报文 线程函数的定义
{
CCOMMUNICATIONSet *dlg=(CCOMMUNICATIONSet*)param;
CListBox *box=(CListBox *)dlg->GetDlgItem(IDC_LIST_INFO);
VCI_CAN_OBJ frameinfo[50];//定义CAN信息帧数据类型的结构体
VCI_ERR_INFO errinfo;//定义错误信息数据类型的结构体
int len=1;
int i=0;
CString str,tmpstr;
while(1)
{
Sleep(1);
if(dlg->m_connect==0)//未连接
break;
len=VCI_Receive(dlg->m_devtype,dlg->m_devind,dlg->m_cannum,frameinfo,50,200);//从指定的设备读取数据
if(len<=0)//没有读到数据
{
VCI_ReadErrInfo(dlg->m_devtype,dlg->m_devind,dlg->m_cannum,&errinfo);//获取最后一次错误信息
}
else//读到数据
{
for(i=0;i<len;i++)
{
str="接收到数据帧: ";
if(frameinfo[i].TimeFlag==0)//无时间标识
tmpstr="时间标识:无 ";
else
tmpstr.Format("时间标识:%08x ",frameinfo[i].TimeStamp);
str+=tmpstr;//接收到信息帧时的时间标识
tmpstr.Format("帧ID:%08x ",frameinfo[i].ID);
str+=tmpstr;//报文ID
str+="帧格式:";
if(frameinfo[i].RemoteFlag==0)
tmpstr="数据帧 ";
else
tmpstr="远程帧 ";
str+=tmpstr;
str+="帧类型:";
if(frameinfo[i].ExternFlag==0)
tmpstr="标准帧 ";
else
tmpstr="扩展帧 ";
str+=tmpstr;
box->InsertString(box->GetCount(),str);//插入字符串
if(frameinfo[i].RemoteFlag==0)//不是远程帧?
{
str="数据:";
if(frameinfo[i].DataLen>8)
frameinfo[i].DataLen=8;
for(int j=0;j<frameinfo[i].DataLen;j++)
{
tmpstr.Format("%02x ",frameinfo[i].Data[j]);
str+=tmpstr;
}
//EnterCriticalSection(&(dlg->m_Section));//获得指定的临界区对象的所有权
//LeaveCriticalSection(&(dlg->m_Section));//释放指定的临界区对象的所有权
box->InsertString(box->GetCount(),str);
}
CNaS_BMSDlg *m_Host = (CNaS_BMSDlg*)AfxGetMainWnd();//获取主界面的指针
if(frameinfo[7].Data[2]!=1)
m_Host->xxx->m_page1.SendMessage(UM_ALARM,0,0);
}
box->SetCurSel(box->GetCount()-1);//box->GetCount():返回列表框中的字符串数目
}
}
return 0;
}
[ 本帖最后由 喜鹊王子 于 2013-3-12 12:34 编辑 ]