1.工具usbcan 型号2e_u
官方给出的是使用mfc例程,此文章是根据例程解析s19文件,并发送部分数据
1.打开文件,并将s19文件转成bin逻辑
void CECanTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
unsigned char buffer_1[BUFSIZE];
#if 1
char szPath[MAX_PATH] = ""; //存放选择的目录路径
CString str;
ZeroMemory(szPath, sizeof(szPath));
BROWSEINFO bi;
bi.hwndOwner = m_hWnd;
bi.pidlRoot = NULL;
bi.lpfn=BrowseCallbackProc;
bi.lParam= long(DefaultDir);
bi.pszDisplayName = szPath;
bi.lpszTitle = "请选择需要打开的文件:";
//bi.ulFlags = 0;
bi.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_STATUSTEXT;
bi.iImage = 0;
LPITEMIDLIST lp = SHBrowseForFolder(&bi);
if(lp && SHGetPathFromIDList(lp, szPath))
{
::SHGetPathFromIDList(lp,szPath);
change::get_path(DefaultDir,szPath,MAX_PATH);
state1 = 1;
//str.Format("选择的目录为 %s", szPath);
//AfxMessageBox(str);
}
else
{
AfxMessageBox("无效的目录,请重新选择");
}
#endif
UpdateData(FALSE);
#if 0
HANDLE hFile = CreateFile(_T("D:\\test.txt"),
GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//锟斤拷锟斤拷锟侥硷拷
#endif
unsigned flag = 0;
HANDLE hFile = NULL;
LONG lDistance = 0;
DWORD dwWritenSize = 0;
BOOL bRet;
DWORD dwReadSize = 0;
unsigned int i, j;
unsigned int temp, temp1;
//hFile = CreateFile(_T("D:\\123.s19"),
hFile = CreateFile(szPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_SHARE_READ,
NULL);
bRet = ReadFile(hFile, s19, max_size, &dwReadSize, NULL);
if (bRet)
{
ShowInfo(_T("文件预览"),0);
//ShowInfo(_T("字节数"),0);
//change::num_sring(buffer_1,&,1);
unsigned int temp;
temp = change::get_info(s19,dwReadSize);
change::paixu(temp);
temp = change::s19_to_bin(buffer,s19,temp);
sum_date = temp;
for(i = 0;i<16;i++)//此处为填充发出去的flash,防止写入错误的值
{
if(buffer[temp +i] < max_size)
buffer[temp +i] = 0;
}
unsigned int dis_addr = addrinfo_1[0].addr;
#if 1//hl_test
for(i=0;i<100;i++)//
#else
for(i=0;i<(temp+15)/16;i++)//
#endif
{
unsigned int just_temp;
just_temp = change::inttoAscii(buffer_1,dis_addr);
dis_addr +=16;
change::num_sring(buffer_1+just_temp,&buffer[i*16],16);
ShowInfo((CString)buffer_1,0);
}
ShowInfo(_T("文件预览结束"),0);
}
else
{
state = open_file_fail;
MessageBox(_T("缺少文件!"));
}
state = open_file_ok;
}
2.发送逻辑
void CECanTestDlg::OnButtonSend()
{
// TODO: Add your control notification handler code here
/*
if(m_connect==0)
{
MessageBox(_T("Not open device!"),_T("Alarm"),MB_OK|MB_ICONQUESTION);
return;
}
CAN_OBJ frameinfo;
char szFrameID[9];
unsigned char FrameID[4]={0,0,0,0};
memset(szFrameID,'0',9);
CString sTmp;
BYTE datalen=0;
UpdateData(true);
if(m_EditSendFrmID.GetLength()==0||
(m_EditSendData.GetLength()==0&&m_ComboSendFrmType.GetCurSel()==0))
{
ShowInfo("Input data",1);
return;
}
if(m_EditSendFrmID.GetLength()>8)
{
ShowInfo("ID rang over",1);
return;
}
if(m_EditSendData.GetLength()>24)
{
ShowInfo("data over len,max 8 byte",1);
return;
}
if(m_ComboSendFrmType.GetCurSel()==0)
{
if(m_EditSendData.GetLength()%3==1)
{
ShowInfo("data format fault,please input again",1);
return;
}
}
GetDlgItemText(IDC_EDIT_SENDFRAMEID,m_EditSendFrmID);
GetDlgItemText(IDC_EDIT_SENDDATA,m_EditSendData);
int i,k;
k=0;
CString cstmp="";
datalen=(m_EditSendData.GetLength()+1)/3;
for(i=0;i<m_EditSendData.GetLength();i++)
{
if(m_EditSendData.Mid(i+1,1)!=" ")
cstmp=cstmp+m_EditSendData.Mid(i+1,1);
else
{
if(cstmp!="")
{
frameinfo.Data[k]=(unsigned char)_tcstoul(cstmp,0,16);
cstmp="";
k=k+1;
}
}
}
UpdateData(false);
frameinfo.DataLen=k;
frameinfo.RemoteFlag=m_ComboSendFrmFmt.GetCurSel();
frameinfo.ExternFlag=m_ComboSendFrmType.GetCurSel();
if(frameinfo.ExternFlag==1)
{
frameinfo.ID=((DWORD)FrameID[0]<<24)+((DWORD)FrameID[1]<<16)+((DWORD)FrameID[2]<<8)+
((DWORD)FrameID[3]);
}
else
{
frameinfo.ID=((DWORD)FrameID[2]<<8)+((DWORD)FrameID[3]);
}
frameinfo.ID=_tcstoul(m_EditSendFrmID, 0, 16);
if(Transmit(m_devtype,0,0,&frameinfo,1)==1)
{
ShowInfo("Send success",0);
}
else
{
ShowInfo("Send fault",2);
}
*/
//if(m_connect==0)
// return;
CAN_OBJ frameinfo;
char szFrameID[9];
unsigned char FrameID[4]={0,0,0,0};
memset(szFrameID,'0',9);
unsigned char Data[8];
char szData[25];
BYTE datalen=0;
UpdateData(true);
#if 0
if(m_EditSendFrmID.GetLength()==0||
(m_EditSendData.GetLength()==0&&m_ComboSendFrmType.GetCurSel()==0))
{
ShowInfo("请输入数据",1);
return;
}
if(m_EditSendFrmID.GetLength()>8)
{
ShowInfo("ID值超过范围",1);
return;
}
if(m_EditSendData.GetLength()>24)
{
ShowInfo("数据长度超过范围,最大为8个字节",1);
return;
}
if(m_ComboSendFrmType.GetCurSel()==0)
{
if(m_EditSendData.GetLength()%3==1)
{
ShowInfo("数据格式不对,请重新输入",1);
return;
}
}
memcpy(&szFrameID[8-m_EditSendFrmID.GetLength()],(LPCTSTR)m_EditSendFrmID,m_EditSendFrmID.GetLength());
strtodata((unsigned char*)szFrameID,FrameID,4,0);
datalen=(m_EditSendData.GetLength()+1)/3;
strcpy(szData,(LPCTSTR)m_EditSendData);
strtodata((unsigned char*)szData,Data,datalen,1);
UpdateData(false);
frameinfo.SendType = 0;
frameinfo.DataLen=datalen;
memcpy(&frameinfo.Data,Data,datalen);
frameinfo.RemoteFlag=m_ComboSendFrmFmt.GetCurSel();
frameinfo.ExternFlag=m_ComboSendFrmType.GetCurSel();
if(frameinfo.ExternFlag==1)
{
frameinfo.ID=((DWORD)FrameID[0]<<24)+((DWORD)FrameID[1]<<16)+((DWORD)FrameID[2]<<8)+
((DWORD)FrameID[3]);
}
else
{
frameinfo.ID=((DWORD)FrameID[2]<<8)+((DWORD)FrameID[3]);
}
// frameinfo.SendType=m_ComboSendType.GetCurSel();
if(Transmit(m_devtype,0,0,&frameinfo,1)==1)
{
ShowInfo("写入成功",0);
}
else
{
ShowInfo("写入失败",2);
}
#endif
if(m_EditSendFrmID.GetLength()>8)
{
ShowInfo("ID值超过范围",1);
return;
}
memcpy(&szFrameID[8-m_EditSendFrmID.GetLength()],(LPCTSTR)m_EditSendFrmID,m_EditSendFrmID.GetLength());
strtodata((unsigned char*)szFrameID,FrameID,4,0);
datalen=(m_EditSendData.GetLength()+1)/3;
strcpy(szData,(LPCTSTR)m_EditSendData);
strtodata((unsigned char*)szData,Data,datalen,1);
UpdateData(false);
frameinfo.SendType = 0;
frameinfo.DataLen=datalen;
//memcpy(&frameinfo.Data,Data,datalen);
frameinfo.RemoteFlag=m_ComboSendFrmFmt.GetCurSel();
frameinfo.ExternFlag=m_ComboSendFrmType.GetCurSel();
if(frameinfo.ExternFlag==1)
{
frameinfo.ID=((DWORD)FrameID[0]<<24)+((DWORD)FrameID[1]<<16)+((DWORD)FrameID[2]<<8)+
((DWORD)FrameID[3]);
}
else
{
frameinfo.ID=((DWORD)FrameID[2]<<8)+((DWORD)FrameID[3]);
}
unsigned int i,j;
unsigned char temp = 0;
unsigned char buffer_2[30];//显示数字
if(0 == addr)
ShowInfo(_T("开始写入"),0);
unsigned int uds_order;
uds_order = addr;
{
uds::send_order(addr);//装填数据
if(uds::send_handle(frameinfo.Data))//打包成网络层
{
addr++;
}
else
{
}
unsigned char buffer_1[30];//显示最终字符
#if hl_test
if(1) //测试为发送成功
#else
if(Transmit(m_devtype,0,0,&frameinfo,1)==1)
#endif
{
change::num_sring(buffer_1,&frameinfo.Data[0],8);
ShowInfo(buffer_1,0);
}
else
{
change::num_sring(buffer_1,&frameinfo.Data[0],8);
ShowInfo(buffer_1,0);
ShowInfo("写入失败",2);
}
}
SetTimer(timer1,100,NULL);//10ms进去1次,开启定时器
char buffer_name[50];
change::int_to_char(buffer_name,uds_send_info.to_send);
VALUE.SetWindowText((LPCTSTR)(buffer_name));
change::int_to_char(buffer_name,uds_send_info.length);
VALUE2.SetWindowText((LPCTSTR)(buffer_name));
change::int_to_char(buffer_name,ceshi);
VALUE3.SetWindowText((LPCTSTR)(buffer_name));
if((addr >= handle_num))
{
addr = 0;
ShowInfo(_T("写入完成"),0);//在对话框中写入提示
KillTimer(timer1);
}
else
{
}
#if 0
CString jindu;
//显示进度条,暂时不处理
if(sum_date)
jindu.Format("%d",addr*100/sum_date);
else
jindu.Format("%d",0);
#endif
//GetDlgItem(IDC_EDIT1)->SetWindowText((jindu));//写数值
//GetDlgItem(IDC_STATIC)->SetTextColor(RGB(255, 0, 0));
}
3.实际发现在发送函数中一直发送数据,窗口会会卡死,无法相应其他操作,可以使用一个定时器来一直点击发送按钮,实现自动发送的效果。
void CECanTestDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(timer1 == nIDEvent)
{
//if(1)0 == old_addr)//只有在不接收时间才发送
{
PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON_SEND, BN_CLICKED), NULL);
}
}
CDialog::OnTimer(nIDEvent);
}
SetTimer(timer1,100,NULL);//10ms进去1次,开启定时器
当不用定时器时,停止定时器
KillTimer(timer1);
定时器结束时调用此函数,会模拟发送一个点击发送的指令,
void CECanTestDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(timer1 == nIDEvent)
{
//if(1)0 == old_addr)//只有在不接收时间才发送
{
PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON_SEND, BN_CLICKED), NULL);
}
}
CDialog::OnTimer(nIDEvent);
}
在停止发送时,也可以停止定时器
解析s19文件
此处解析s19的思路为创建一个足够大的内容空间,将s19中提取的数据填入到此内存空间中,有的s19地址是部分是乱的,从新排列有利于发送数据
1此处将s19拆解成带有地址的数据包,
unsigned int change::get_info(unsigned char *sour,int length)//128k为0x2 0000,int 可以容纳
{
unsigned int i,j = 0;
char temp;
for(i = 0;i<length;)
{
temp = sour[i];
if(sour[i] == 's'||sour[i] == 'S')//当有s判断下一至来判断地址的长度
{
if('0' == sour[i+1])//此处没有有效数据
{
i++;
continue;
}
else if('1' == sour[i+1])
{
addrinfo_1[j].length = (Ascii2char(sour[i+2],sour[i+3])-3);//此处不乘以2,防止越界,-3地址2,校验1
addrinfo_1[j].addr = Ascii2int(sour[i+4],sour[i+5],sour[i+6],sour[i+7]);
addrinfo_1[j].position = i+8;
j++;
i += 8;
}
else if('2' == sour[i+1])
{
addrinfo_1[j].length = (Ascii2char(sour[i+2],sour[i+3])-4);//此处不乘以2,防止越界 -4地址3,校验1
addrinfo_1[j].addr = Ascii2int(sour[i+4],sour[i+5],sour[i+6],sour[i+7]);
addrinfo_1[j].addr <<= 8;
addrinfo_1[j].addr += (Ascii2char(sour[i+8],sour[i+9]));
addrinfo_1[j].position = i+10;
j++;
i += 8;
}
else
{
i++;//终止
return j;
}
}
else
{
i++;
}
}
return j;
}
将得到的数据填入到内存中,方便发送时取用
unsigned int change::s19_to_bin(unsigned char *dst,unsigned char *sour,int length)//128k为0x2 0000,int 可以容纳
{
unsigned int i,j,k = 0;
unsigned int temp = 0;//
unsigned int temp_addr = 0;//
unsigned int temp1 = 0;//转成的16进制数
unsigned int temp2 = 0;//转成的16进制数
for(i = 0;i <length;i++)
{
#if 0
temp = addrinfo_1[paixunum[i]].length;
temp <<= 1;
for(j = 0;j < temp;j += 2)
{
temp1 = sour[addrinfo_1[paixunum[i]].position+j];
temp2 = sour[addrinfo_1[paixunum[i]].position+j+1];
dst[k++] = Ascii2char(temp1,temp2);
}
#endif
temp = addrinfo_1[paixunum[i]].length;
temp <<= 1;
temp_addr = addrinfo_1[i].addr;
for(j = 0;j < temp;j += 2)
{
temp1 = sour[addrinfo_1[i].position+j];
temp2 = sour[addrinfo_1[i].position+j+1];
dst[temp_addr++] = Ascii2char(temp1,temp2);
}
}
return temp_addr;
}
如果要对接收值进行判定,在一下函数中进行判断
UINT CECanTestDlg::ReceiveThread(void *param)
{
CECanTestDlg *dlg=(CECanTestDlg*)param;
CListBox *box=(CListBox *)dlg->GetDlgItem(IDC_LIST_INFO);
CAN_OBJ frameinfo[50];
int len=1;
int i=0;
old_addr = 1;//接收为1
CString str,tmpstr;
while(1)
{
Sleep(1);
if(dlg->m_connect==0)
{
old_addr = 0;//退出为空闲状态
break;
}
len=Receive(dlg->m_devtype,0,0,frameinfo,50,100);
if(len>0)
{
for(i=0;i<len;i++)
{
str="Rec: ";
if(frameinfo[i].TimeFlag==0)
tmpstr="Time: ";
else
tmpstr.Format(_T("Time:%08x "),frameinfo[i].TimeStamp);
str+=tmpstr;
tmpstr.Format(_T("ID:%08x "),frameinfo[i].ID);
str+=tmpstr;
str+="Format:";
if(frameinfo[i].RemoteFlag==0)
tmpstr="Data ";
else
tmpstr="Romte ";
str+=tmpstr;
str+="Type:";
if(frameinfo[i].ExternFlag==0)
tmpstr="Stand ";
else
tmpstr="Exten ";
str+=tmpstr;
box->InsertString(box->GetCount(),str);
if(frameinfo[i].RemoteFlag==0)
{
str="Data:";
if(frameinfo[i].DataLen>8)
frameinfo[i].DataLen=8;
for(int j=0;j<frameinfo[i].DataLen;j++)
{
tmpstr.Format(_T("%02x "),frameinfo[i].Data[j]);
str+=tmpstr;
}
//此处加入逻辑
if(frameinfo[i].ID)//暂时不判断
{
#if 0
if(1 == frameinfo[i].Data[0])
{
addr++;
}
#endif
uds::rec_date(frameinfo[i].Data);
}
box->InsertString(box->GetCount(),str);
}
}
box->SetCurSel(box->GetCount()-1);
}
}
old_addr = 0;//退出为空闲状态
return 0;
}