PGN – 参数组号码 (Parameter Group Number)的意思。
CAN技术的报文传输为多主方式工作,网络上任意节点均可在任意时刻主动地向网络上其它节点 发送信息,而不分主从。CAN节点只需通过对报文的标示符滤波即可实现点对点、一点对多点及全局广播等几种方式发送、接收数据。
CAN总线的数据传输(报文传输)采用帧格式。按帧格式的不同,分为含有11位标识符的标准帧和含有29位标识符的扩展帧。CAN总线的帧类型分为 数据帧、远程帧、错误帧和过载帧。
CAN与PGN的关系:
PGN是参数组编号,对于制定CAN协议来说十分重要,很多ECU在接受报文时识别的就是PGN而不是报文的ID,
扩展资料CAN 总线的主要特点有:
( 1) CAN 为多主工作方式 ,网络上的任意节点在任意时刻都可以主动地向其他节点发送信息 ,不分主从 ,方式灵活。
( 2) CAN 网络节点可以安排优先级顺序 ,以满足和协调各自不同的实时性要求。
( 3) 采用非破坏性的总线仲裁技术 ,多点同时发送信息时 ,按优先级顺序通信 ,节省总线冲突仲裁时间 ,避免网络瘫痪。
( 4) 可以进行点对点、一点对多点和全域广播方式传递信息。
( 5) 通信速率最高可达 1M bps( 40m以内 ) ,最长传递距离达 10km(速率为 5kbps以下 )。
( 6) 网络节点目前可达 110个 ,报文标志符 2 032种 ( CAN2. 0A) ,扩展标准 ( CAN2. 0B)中报文标志符几乎不受限制。
参考资料来源:百度百科-can
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=0i<leni++)
{
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=0j<frameinfo[i].DataLenj++)
{
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
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)