/* Modbus2CAN: Transfer Modbus/TCP cmd to a CAN device. Compiler: BC++ 3.1 Compile mode: large Project: demo1.c 7186EL.Lib tcp_dm32.Lib xs100l.lib mfs_v211.lib fw_09314.lib MBT7@NNN.Lib, with NNN being the lib file's version. Using function ModbusTCP_Init, ModbusTCP_Close, SendCANMsg. Please refer to MBTCP_7E.h and XC100.h for more information. Hardware: 7186EX + I-7565 Utility:MBTCP, I-7565-H1/H2 Usage: Use MBTCP to send Modbus/TCP 10h cmd (Preset Multiple register), then receiver data through I-7565-H1/H2 utility. [July 13, 2011] by Randy */ #include #include #include "..\..\lib\7186e.h" #include "..\..\lib\Tcpip32.h" #include "..\..\lib\MFW.h" #include "..\..\lib\MBTCP_XS.h" #include "..\..\lib\XC100.h" #define CANCmdOffset 13 int VcomCmdModbus(TCPREADDATA *p); // declared in the MBT7@NNN.Lib void Port502(int SocketNumber, int Connected); int iScanCOMPort=1; // for Modbus Kernel //The I/O memory mapping unsigned char far iMemory_DI[100]; unsigned char far iMemory_DO[100]; int far iMemory_AI[100]; int far iMemory_AO[100]; TCP_SERVER MBServer={ 502, -1, 0, 0, Port502 }; /************************************************************************/ char *GetModuleName(void) /* User's program must support this function for UDP search */ { return "uPAC-7186EX" ; } /************************************************************************/ char *GetAliasName(void) /* User's program must support this function for UDP search */ { return "test1" ; } /************************************************************************/ /*If the UserCANInt() function is not used, please don't remove it.*/ void UserCANInt(char CANInt){ if (CANInt) ; /*avoid complier warning*/ } void XS_UserInit(int argc, char *argv[]) { extern int bAcceptBroadcast; extern unsigned long ACKDELAY; /* variable in tcp.c */ extern long MAXTXTOUT; void UserLoop(void); int iRet; InitLib(); XC100Init(1,3,1000000UL,0,0,0x00000000UL,0xffffffffUL); CAN_CreateBuffer(0,1000); //Create RX Buffer CAN_CreateBuffer(1,1000); //Create TX Buffer CAN_InstallIrq(); bAcceptBroadcast=1; ACKDELAY=200; Print("Press any key to exit program!\n\r"); XS_AddSystemLoopFun(UserLoop); // add a Modbus server to your program XS_AddServer(&MBServer); // ======= Begin changing COM port setting ======= // Call following codes once when you change the COM port setting // After saving the setting to the EEPROM, you should remove the codes // COM1 setting ComData[1-1].baud=115200; ComData[1-1].databit=8; ComData[1-1].parity=0; ComData[1-1].stopbit=1; VcomSaveComData(1-1); // COM2 setting ComData[2-1].baud=9600; ComData[2-1].databit=8; ComData[2-1].parity=0; ComData[2-1].stopbit=1; VcomSaveComData(2-1); // ======= End changing COM port setting ======= // ***** Begin Modbus configuration ***** // Before the Modbus Utility can support the 7188XB -MRTU, // You can add following functions to configure the Modbus settings. Set_NetID(1); Set_COMEnableMode(1, _Programming); //(COM1 be a Modbus/RTU slave port) Set_COMEnableMode(2, _Programming); //(COM2 be a Modbus/ASCII slave port) // **** End Modbus configuration ***** //======= Begin of Modbus Kernel ======= iRet=InitModbus(iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO); if(iRet==0) { // Initial Modbus configuration success. } else { // Initial Modbus configuration failure. } Modbus_Memory_Size(100, 100, 100, 100); //======= End of Modbus Kernel======= // uses the TCP/IP functions XS_AddSystemLoopFun(XS_SocketLoopFun); XS_StartSocket(); MAXTXTOUT=6000UL; EnableWDT(); } void XS_UserEnd(void) { int i; XS_StopSocket(); DisableWDT(); RestoreCom(1); RestoreCom(2); CAN_Restore(); } unsigned long lStart_TimeTick; void UserLoop(void) { int i, iRet; //unsigned char MsgData[8]; RefreshWDT(); //======= Begin of Modbus Kernel ======= if(mtModbusPort[iScanCOMPort].EnableMode==_ModbusRTU_Slave) CheckModbusRTURequest(iScanCOMPort); // Is any request from Modbus/RTU Master ? if(mtModbusPort[iScanCOMPort].EnableMode==_ModbusASCII_Slave) CheckModbusASCIIRequest(iScanCOMPort); // Is any request from Modbus/ASCII Master ? if(mtModbusPort[iScanCOMPort].EnableMode==_ModbusRTU_Gateway) { SendModbusRequest(iScanCOMPort); // Passes request to modbus slave device. CheckResponseTimeout(iScanCOMPort); // If response timeout, sets iModbusAction // to IDLE status. CheckModbusResponse(iScanCOMPort); // Is any response from modbus slave device? SendModbusResponse(iScanCOMPort); // Passes response to Modbus/RTU Master. } iScanCOMPort++; if(iScanCOMPort>iTotalCOMPort) iScanCOMPort=1; //======= End of Modbus Kernel ======= if((GetTimeTicks()-lStart_TimeTick)>50) { lStart_TimeTick=GetTimeTicks(); } if(IsCom1()) QuitMain=1; } char far sInputBuffer_P502[512]; void Port502(int SocketNumber, int Connected) { int iByte,j; unsigned char MsgData[8]; TCPREADDATA pTCP_Data_Pointer; if(Connected==0) //First time connected from remote clients. { ; } else { iByte=readsocket(SocketNumber, sInputBuffer_P502, sizeof(sInputBuffer_P502)-1); if(iByte>0) { pTCP_Data_Pointer.Socket=SocketNumber; pTCP_Data_Pointer.ReadUartChar=sInputBuffer_P502; pTCP_Data_Pointer.Length=iByte; VcomCmdModbus(&pTCP_Data_Pointer); for(j=0;j"); //for(i=0;i<*CommandLength;i++) // printCom1("[%02X] ",CommandData[i]&0xFF); // do nothing CommandData=CommandData; CommandLength=CommandLength; } void Modbus_Response_Event(char* ResponseData, int* ResponseLength) { /* char* ResponseData: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it doesn't include 6 leading bytes int* CommandLength: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it doesn't include 6 leading bytes */ //If you want to change the content of the ResponseData, //you have to do 2 steps for Modbus/TCP or Modbus/RTU. //Step1: Change content (Note:you must know the modbus protocol well) //ResponseData[6]=0x19; //ResponseData[7]=0x75; //ResponseData[8]=0x04; //ResponseData[9]=0x01; //Step2: Update data length //*ResponseLength=10; //int i; //printCom1("\n\r Out==>"); //for(i=0;i<*ResponseLength;i++) // printCom1("[%02X] ",ResponseData[i]&0xFF); //printCom1("\n\r"); // do nothing ResponseData=ResponseData; ResponseLength=ResponseLength; } void main(int argc,char *argv[]) { XS_main(argc, argv); // call the XS library main function }