Can通信模块详细设计说明书_第1页
Can通信模块详细设计说明书_第2页
Can通信模块详细设计说明书_第3页
Can通信模块详细设计说明书_第4页
Can通信模块详细设计说明书_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Can.cpp模块设计说明1 .总则:传送故障记录数据或运行记录数据时,不传送参数数据和实时数据。传送参数数据和实时数据可同时传送。在界面层:1 .读故障记录数据BUTTON和运行记录数据BUTTON和记录实时数据BUTTON没有按下,参数没有操作时,才能按下读故障记录数据BUTTON或运行记录数据BUTTON。否则弹出信息框。2 .按下故障记录数据BUTTON后,把运行记录数据BUTTON和记录实时数据BUTTON变灰,参数MENU和参数界面上的读和修改BUTTON变灰,故障记录数据读完后,上述按钮复原。对按下运行记录数据BUTTON作同样处理。3 .按下记录实时数据BUTTON时,把故障记

2、录数据BUTTON和运行记录数据BUTTON变灰。按下停止记录实时数据BUTTON时,把故障记录数据BUTTON和运行记录数据BUTTON复原。4 .对参数上载和修改时,把故障记录数据BUTTON和运行记录数据BUTTON变灰,完成操作后把故障记录数据BUTTON和运行记录数据BUTTON复原。CAN和以太网类似,相应7种事件:关闭CAN、实时数据请求、读参数、写参数、发送心跳报文,读故障记录,读运行记录。2功能模块类名为:ClassCan类对象定义在Can.cpp中,是一个全局对象。ClassLang_Can;该模块的功能为:1 .通过USB转CAN与下位机进行实时数据请求和参数的上传下载,

3、读故障记录,读运行记录;2 .通过PCI插卡与下位机进行实时数据请求和参数的上传下载,读故障记录,读运行记录;3 .出错处理。3流程逻辑CAN部分由线程CanThread(证成5个事件。OpenCan(DWORDDevType,DWORDDevIndex,DWORDReserved)函数通过调用API函数VCI_OpenDevice(DWORDDevType,DWORDDevIndex,DWORDReserved)打开CAN;CloseCan(DWORDDevType,DWORDDevIndex)函数通过调用API函数VCI_CloseDevice(DWORDDevType,DWORDDevI

4、ndex)关闭CAN;StartCanThread()函数用于开启Can线程;SuspendedCanThread()函数用于关闭线程;CanThread()为Can线程函数,用于执行五种事件:关闭Can、发送实时数据请求、读参数、写参数和发送心跳报文。SendCanPacket(intiEvent,intIndex=0,intSubIndex=0,*Data=NULL)为CAN发送报文函数,iEvent为事件值,Index、SubIndex、Data用于参数的读写事件。根据不同的事件,发送相应的报文。RecvCanPacket()JudgeOvertime();以上函数形参封装在以下的数据结

5、构中:typedefstruct_CAN_DEVICE_PARM_DWORDdwDevType;设备类型号DWORDdwDevIndex;设备索引号DWORDdwReserved;保留DWORDdwCANIndex;Can第几路DWORDdwChecCode;/验收码DWORDdwMask;/屏蔽码DWORDm_dwMode;/模式intiTimer0;/定时器intiTimer1;/定时器intiFilterType;/滤波方式CAN_DEVICE_PARM;typedefstruct_VCI_CAN_OBJUINTuiID;UINTuiTimeStamp;BYTEbyTimeFlag;BY

6、TEbySendType;BYTEbyRemoteFlag;/是否是远程帧BYTEbyExternFlag;/是否是扩展帧BYTEbyDataNbytes;BYTEbyDataBuf8;BYTEbyReserved3;VCI_CAN_OBJ,*PVCI_CAN_OBJ;成员uiID:报文ID;uiTimeStamp:接收到信息帧的时间标识,从CAN控制器初始化开始计时;byTimeFlag:是否使用时间标识,为1时uiTimeStamp有效,byTimeFlag和uiTimeStamp只在此帧为接收帧时有意义;bySendType:发送帧类型,0为正常发送,1为单次发送,2为自发自收,3为单次

7、自发自收只在此帧为发送帧时有意义;byRemoteFlag:是否为远程帧;byExternFlag:是否为扩展帧;byDataNbytes:数据长度(=8),即Data的长度;byDataBuf:报文的数据;byReserved:系统保留。typedefstruct_VCI_INIT_CONFIGDWORDdwAccCode;DWORDdwAccMask;DWORDdwReserved;UCHARucFilter;UCHARucTiming。;UCHARucTiming1;UCHARucMode;VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;成员:dwAccCode:验收

8、码;dwAccMask:屏蔽码;dwReserved:系统保留;ucFilter:滤波方式,1为单波方式,0为双波方式;ucTiming0:定时器0;ucTimingl:定时器1;ucMode:模式。0为正常模式,1为只听模式在Datalayer.cpp中添加成员变量:BYTEm_byCANRealTimeBuffer;BYTEm_byCANParmBuffer口;添加成员函数:intGetDataFromCANPacket();对CAN接收到的数据进行解析分类,将数据存于他对应的地方。CAN从界面层到通讯层的整体流程图:返回失败SendCanPacket()流程图:SendCanPacket

9、()/判断iEventCANThread()流程图:发送实时数据请求报文接收实时数据报文While判断是否委生其他事件并且是否为一”;组数据的最后一帧.通过返回值判断是否超时重发请求1)如收到的是心跳报文;则丢掉IDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte70x7020x01State00000002)如收到的是中止SDO请求报文(最后4个字节是16进制中止代码之一06010000,其功能描述是对象不支持访问”)CANIDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte7DL0x5820x080x80IndexSub-

10、index00000106则上位机通知参数设定界面,参数设定界面弹出对话框告知参数INDEX或SUBINDEX出错。上位机停止上传/下载系统参数。4实时数据和参数通信过程(供参考)4.1 数据结构:在InternalDef.h中增加#defineLIMIT_CAN_RECV_ONE_PACKET_TIMEOUT_MS200#definePACKET_TIMEOUT2在PdasConfig中增加Intm_iCanRecvOnePacketTimeoutMs;在PdasCong.cpp中m_iCanRecvOnePacketTimeoutMs=LIMIT_CAN_RECV_ONE_PACKET_T

11、IMEOUT_MS在DataLayer.h中增力口intm_iCanRealTimeDataNbytes;/UDP收到的数据长度BYTEm_byCanRealTimeData500;在Can.h中增加BYTEm_byRealTimeData128Intm_iIndexOfRealTimeData;BOOLm_bFirstRealTimeBlock4.2 程序伪代码:1 .初始化m_byRealTimeData口为全0,且m_byRealTimeData00=0xff;m_bFirstRealTimeBlock=TRUE2 .在应该发送的时刻调用SendNmi(0x01)函数然后调用VCI_Tr

12、asmit()3.BOOLbShouldSave=FALSE;While(TRUE)If(ShouldSendParmPacket(.)/W上载参数报文或修改参数报文要发送OrganizeParmPacket(.)/组织发送VCI_Transmit(.)iNbytes=VCI_Receive(.),超时时间用变量g_PdasConfig.CanRecvOnePacketTimeoutMs;iState=ProcessPossibleTimeOut(.)/返回PACKET_TIMEOUT或DEVICE_FAULTIf(iState=PACKET_TIMEOUT)Continue;Elseif(i

13、State=DEVICE_FAULT)g_DataLayer.iDeviceStateDEVICE_CAN=DEVICE_FAULTBreak;iPacketType=JudgeReceivedPacketType(.)If(iPacketType=REAL_TIME_DATA|=LAST_REAL_TIME_DATA)/收至U实时数据报文根据ID,DL,Byte放入相应m_byRealTimeData?口Elseif(iPacketType=UPLOAD_PARM)ProcessUpLoadParm(.)/参数报文处理Elseif(iPacketType=MODITY_PARM)Proces

14、sModityParm(.)参数报文处理If(iPacketType=LAST_REAL_TIME_DATA)/(0x484,0x08,0x0B)收到If(m_iReadRecordStage=BEGIN)break/退出循环,去读故障记录数据If(m_bFirstRealTimeBlock=TRUE)If(12个报文全收到)m_bFirstRealTimeBlock=FALSEbShouldSave=TRUEElsebShouldSave=TRUEIf(bShouldSave)bShouldSave=FALSE;g_DataLayer.PutRealTimeData(m_byRealTime

15、Data,iErrorCode,DEVICE_CAN);)/endofWhile()5传送故障记录数据或运行记录数据过程(供参考)5.1 数据结构:InternalDef.h中增加# defineNON_RECORD0# defineFAULT_RECORD1# defineNORMAL_RECORD2#defineBEGIN_RECORD1.#defineCOMPLETE_RECORDxx0x20000x3000(0x3000-1)(0x4000-1)#defineFIRST_INDEX_OF_FAULT_RECORD#defineFIRST_INDEX_OF_NORMAL_RECORD#d

16、efineLAST_INDEX_OF_FAULT_RECORD#defineLAST_INDEX_OF_NORMAL_RECORD/现由周提供PdasConfig.h中增力口Intm_iFirstIndexOfFaultRecordIntm_iFirstIndexOfNormalRecordIntm_iLastIndexOfFaultRecordIntm_iLastIndexOfNormalRecordPdasConfig.cpp中增力口对它们赋初值Can类中增力口Intm_iRecvRecordTypeIntm_iRecvRecordStageBYTEm_byRecordData128Int

17、m_iIndexOfRecordData;Intm_iSubIndexOfRecordDataIntm_iBlockSizeOfRecordDataDalaLayer中增力口RecvFaultRecord(.)RecvNormalRecord(.)5.2 伪代码1.对故障记录数据,界面调用g_DataLayer.RecvFaultRecord().g_DataLayer.RecvFaultRecord()勺工作:- 设置变量Can.m_iRecvRecordStage=BEGIN还是设置事件m_EventRecvRecord?M论- 设置Can.m_iRecvRecordType=FAULT_

18、RECORD对故障记录数据,界面调用g_DataLayer.RecvNormalRecord().g_DataLayer.RecvNormalRecord()勺工作:- 设置变量Can.m_iRecvRecordStage=BEGIN_RECORD还是设置事件m_EventRecvRecord?M论-设置Can.m_iRecvRecordType=NORMAL_RECOED初始化m_byRecordData128为0和m_byReacordData00为0xFF。2 .CanThread的代码在适当时刻检查一系列变量(事件?),当检查到m_iRecvRecordStage=BEGIN_RECO

19、RD时,做:OpenRecordFile()/伪代码后面提供- 设置m_iRecvRecordType=NORMAL_RECOED初始化m_byRecordData128为0和m_byReacordData00为0xFF。- 设置m_iReadRecordStage=SEND_SDO1- 设置If(m_iReadRecordType=FAULT_RECORD)m_iIndexOfRecordData=g_PdasConfig.m_iFirstIndexOfFaultRecordElse(m_iReadRecordType=NORMAL_RECORD)m_iIndexOfRecordData=g

20、_PdasConfig.m_iFirstIndexOfNormalRecord- 设置m_iSubIndexOfRecordData=0;m_iBlockSizeOfRecordData=128- 调用SendNmi(0x80)函数该函数组织报文(00,02,80,02,00,00,00,00,00,00然后调用VCI_Trasmit()3 .调用SendSdo1()函数SDO1IDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte7DL0x6020x080xA4m_iIndexm_iSubIndexm_iBlockSize000然后调用VCI_Transmit

21、()-设置m_iReadRecordStage=RECV_SDO24 .CanThread等待接收报文Sdo2调用VCI_Receive(),超时时间用变量g_PdasConfig.CanRecvOnePacketTimeoutMsiState=ProcessPossibleTimeOut(.)返回PACKET_TIMEOUT或DEVICE_FAULTIf(iState=PACKET_TIMEOUT)超时处理?Elseif(iState=DEVICE_FAULT)g_DataLayer.iDeviceStateDEVICE_CAN=DEVICE_FAULT故障处理?-如果准确,即收到的是SDO

22、2IDniDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte70x5820x080xC6IndexSub-indexsize000000调用SendSdo3()函数SDO3IDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte7DL0x6020x080xA3000000然后调用VCI_Transm4()发送设置m_iReadRecordStage=RECV_DATA5 .接收报文调用VCI_Receive(),超时时间用变量g_PdasConfig.CanRecvOnePacketTimeoutMsiState=ProcessPo

23、ssibleTimeOut(.)返回PACKET_TIMEOUT或DEVICE_FAULTIf(iState=PACKET_TIMEOUT)超时处理?Elseif(iState=DEVICE_FAULT)g_DataLayer.iDeviceStateDEVICE_CAN=DEVICE_FAULT故障处理?-如果准确,即收到的是SDOIDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte7Bit7Bit6-010x5820x0800xxxxxxxxxxxxxx20x5820x0801xxxxxxxxxxxxxx30x5820x0802xxxxxxxxxxxxxx

24、N-10x5820x080N-1xxxxxxxxxxxxxxN0x5820x081Nxxxxxxxxxxxxxx根据ID,DL,Byte0的Bit6-0位把Byte0到Byte7放入m_byRecordData.If(Byte0的Bit7为1)m_iReadRecordStage=SEND_SDO4iLastBlockNo=Byte0的Bit6-0的值否则继续56 .调用SendSdo4()函数该函数组织报文SDO4IDDLByte0Byte1Byte2Byte3Byte4Byte5Byte6Byte70x6020x080xA21blksize00000然后调用VCI_Transmit()-设

25、置m_iReadRecordStage=RECV_SDO57 CanThread等待接收报文Sdo5调用VCI_Receive(),超时时间用变量g_PdasConfig.CanRecvOnePacketTimeoutMsiState=ProcessPossibleTimeOut(.)/返回PACKET_TIMEOUT或DEVICE_FAULTIf(iState=PACKET_TIMEOUT)超时处理?Elseif(iState=DEVICE_FAULT)g_DataLayer.iDeviceStateDEVICE_CAN=DEVICE_FAULT故障处理?-如果准确,即收到的是SDO5IDD

26、IDLByteOBytelByte2Byte3Byte4Byte5Byte6Byte70x5820x08byPacketCmdbyPacketCrc00000注:byPacketcmd=(0x06<<5)|(7-size%7)<<2)|0x01),其中size表示所要上传的数据数量(字节数)。byPacketCrc为整个数据的CRC校验。/PC计算cmd和CRC(使用变量byMyCmd,byMyCrc)byMyCmd=CalCmd(&m_byRecordData,iLastBlockNo);byMyCrc=CalCrc(&m_byRecordData口口,iLastBlockNo);If(byMyCmd=byPacketCmd&&byMyCrc=byPacketCrc)贝Ufile.write(m_byRecordBuf,limit_block_nbytes)+m_iSubIndexOfRecordData;If(m_iSubIndexOfRecord=0)m_iIndexOfRecordData+;)设置m_iRecvRecordStage=REC

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论