/* MBRTU_S.c: Modbus RTU Slave demo Compiler: BC++ 3.1, Turbo C++ 1.01(3.01) (free from http://cc.codegear.com/free/cpp) Compile mode: Large Project: MBRTU_S.c lib\G4500.lib lib\tcp_dm32.lib lib\FW_nnnnn.lib lib\MBTG@174.lib Hordware: G-4500-2G [Sep 26, 2012] by Liam [Feb 17, 2015] by William */ #include "lib\G4500.h" #include "lib\Tcpip32.h" #include "lib\MFW.h" #include "lib\MBTCP_XS.h" #define REG_SIZE 256 /* The I/O memory mapping */ unsigned char far iMemory_DI[REG_SIZE]; unsigned char far iMemory_DO[REG_SIZE]; int far iMemory_AI[REG_SIZE]; int far iMemory_AO[REG_SIZE]; void ScanUserProcess(void); char *GetModuleName(void) /* User's program must support this function for UDP search */ { return "G-4513-3GWA"; } char *GetAliasName(void) /* User's program must support this function for UDP search */ { return "RTU test1"; } void XS_UserInit(int argc, char *argv[]) { extern int bAcceptBroadcast; extern unsigned long ACKDELAY; extern long MAXTXTOUT; void UserLoop(void); int iRet; InitLib(); X305IO_Init(); bAcceptBroadcast=0; ACKDELAY=200; MAXTXTOUT=6000UL; XS_AddSystemLoopFun(UserLoop); //======= Begin of Modbus Kernel ======= ComData[1-1].baud=115200L; ComData[1-1].databit=8; ComData[1-1].parity=0; ComData[1-1].stopbit=1; VcomSaveComData(1-1);//index 0-->COM1 ComData[2-1].baud=9600L; ComData[2-1].databit=8; ComData[2-1].parity=0; ComData[2-1].stopbit=1; VcomSaveComData(2-1); iRet=InitModbus(iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO); if(iRet!=NoError) { /* Initial Modbus configuration failed */ StopModbus(); } /* Set the COM port to be Modbus/RTU slave port Modbus clients/masters (HMI or SCADA software) can poll the G-4500 via these COM ports */ Set_COMEnableMode(1, _Programming); Set_COMEnableMode(2, _ModbusRTU_Slave); Set_NetID(1); Modbus_Memory_Size(REG_SIZE, REG_SIZE, REG_SIZE, REG_SIZE); //======= End of Modbus Kernel ======= EnableWDT(); printCom1("Finish init.\r\n"); } void XS_UserEnd(void) { DisableWDT(); XS_StopSocket(); StopModbus(); /* StopModbus() will be called before exiting the program */ //- StopModbus don't close Com port, please close it here. RestoreCom1(); RestoreCom2(); } void UserLoop(void) { if(IsCom1()) { if(ReadCom1()==27) { //Press 'Esc' key to quit the program QuitMain=1; } } RefreshWDT(); ModbusLoopFun(); //Modbus library will deal the thing of Modbus here ScanUserProcess(); } void Modbus_Request_Event(char* CommandData,int* CommandLength) { /* Modbus_Request_Event is supported since version 1.6.8 [2007,03,13]. char* CommandData: For Modbus/TCP, it includes 6 leading bytes. (needful) For Modbus/RTU, it includes 6 leading bytes. (needless) int* CommandLength: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it includes 6 leading bytes. */ // Example code //int i; //printCom1("FC:%2d StartAddress:%3d IOCount:%4d\n\r",iModbusRequest_Fun, iModbusRequest_Addr,iModbusRequest_IOCount); //printCom1("Modbus Request\n\r In==>"); //for(i=0;i<*CommandLength;i++) // printCom1("[%02X] ",CommandData[i]&0xFF); } 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"); } //== fill all I/O data to mapping address // don't block in this function --> here use "switch...case..." to avoid WDT timeout and reset void ScanUserProcess(void) { static int iProcess=0; int i, iValue; float fValue; switch(iProcess) { case 0: /* Analog input (Ch0) ==> Modbus Memory */ fValue=X305IO_AnalogIn(0); iMemory_AI[0]=(int)(fValue*1638.35); /* (fValue/20.0*32767.0) */ /* Analog input (Ch1) ==> Modbus Memory */ fValue=X305IO_AnalogIn(1); iMemory_AI[1]=(int)(fValue*1638.35); /* Analog input (Ch2) ==> Modbus Memory */ fValue=X305IO_AnalogIn(2); iMemory_AI[2]=(int)(fValue*1638.35); /* Analog input (Ch3) ==> Modbus Memory */ fValue=X305IO_AnalogIn(3); iMemory_AI[3]=(int)(fValue*1638.35); iProcess=1; break; case 1: /* Analog input (Ch4) ==> Modbus Memory */ fValue=X305IO_AnalogIn(4); iMemory_AI[4]=(int)(fValue*1638.35); /* Analog input (Ch5) ==> Modbus Memory */ fValue=X305IO_AnalogIn(5); iMemory_AI[5]=(int)(fValue*1638.35); /* Analog input (Ch6) ==> Modbus Memory */ fValue=X305IO_AnalogIn(6); iMemory_AI[6]=(int)(fValue*1638.35); /* Analog input (Ch7) ==> Modbus Memory */ fValue=X305IO_AnalogIn(7); iMemory_AI[7]=(int)(fValue*1638.35); iProcess=2; break; case 2: /* Digital input ==> Modbus Memory */ iValue=X305IO_Read_All_DI(); for(i=0; i<3; i++) { if(iValue&0x01) iMemory_DI[i]=1; else iMemory_DI[i]=0; iValue>>=1; } iProcess=3; break; case 3: /* Modbus Memory ==> Digital output */ iValue=0; for(i=0; i<3; i++) { if(iMemory_DO[i]!=0) iValue+=(1<