//-------------------------------------------------------// // Project Code : ESS100K3L-01-19 // File Name : Modbus.cpp // Created on : 2019. 06. 07. // Description : // Author : KimJeongWoo // Last modified Date : //-------------------------------------------------------// #include "CommonLib.h" // // 1. SCIRXBUF레지스터는 EasyDSP나 에뮬레이터에서 절대 보지 말것. // FIFO 카운터를 감소시켜 처리 시퀀스에 오류를 발생함. // 이는 모든 FIFO를 사용하는 UART의 경우 문제 발생의 여지가 있음. // 꼭 모니터링이 필요 한 경우는 SCIRXEMU 레지스터를 이용하여 볼것. // // 2. FIFO를 사용하는 경유 SCIRXBUF.all 대신 SCIRXBUF.RXDT를 사용 하여야 함 // // 3. RX FIFO가 Overflow가 되는 경우 먼저 들어온 순서대로 삭제됨 (FIFO) #define CPUCLK 200000000L // CPU Main Clock #if(MODBUSA_ENB) #define MODBUSA_RX_RDY ScicRegs.SCIRXST.bit.RXRDY #define MODBUSA_RX_FIFO ScicRegs.SCIFFRX.bit.RXFFST #define MODBUSA_RX_FIFO_RST ScicRegs.SCIFFRX.bit.RXFIFORESET #define MODBUSA_RX_OVF ScicRegs.SCIFFRX.bit.RXFFOVF #define MODBUSA_RX_OVFCLR ScicRegs.SCIFFRX.bit.RXFFOVRCLR #define MODBUSA_RX_BUF ScicRegs.SCIRXBUF.bit.SAR #define MODBUSA_RX_ERROR ScicRegs.SCIRXST.bit.RXERROR #define MODBUSA_TX_RDY ScicRegs.SCICTL2.bit.TXRDY #define MODBUSA_TX_FIFO ScicRegs.SCIFFTX.bit.TXFFST #define MODBUSA_TX_BUF ScicRegs.SCITXBUF.bit.TXDT #define MODBUSA_TX_EMTPY ScicRegs.SCICTL2.bit.TXEMPTY #define MODBUSA_SWRESET ScicRegs.SCICTL1.bit.SWRESET = 0,\ ScicRegs.SCICTL1.all = 0x0023 #define MODBUSA_FIFO_RST ScicRegs.SCIFFTX.bit.SCIRST = 1 //---------------------------- Serial Modbus A set parameter RS485----------------------------------// #define MODBUSA_LSPCLK (CPUCLK/4) // Peripheral Low Speed Clock for SCI- #define MODBUSA_BAUDRATE 9600L #define MODBUSA_BRR_VAL (MODBUSA_LSPCLK/(8*MODBUSA_BAUDRATE)-1) // MODBUSA BaudRate ���� Register �� //16번 funccode로 123개 동시 write 명령시 231 바이트 // #define MODBUSA_RECEIVE_MAX_BYTE 250 #define MODBUSA_RECEIVE_MIN_BYTE 2 #define MODBUSA_TRANS_MAX_BYTE 250 #define MODBUSA_START_ADDR 0 #define MODBUSA_MAX_ADDR 1500 #pragma SET_DATA_SECTION(".Modbus") unsigned int ModbusASlaveID = 1; unsigned int ModbusARxCnt = 0, ModbusARxOk = 0, ModbusARxErr = 0, ModbusATxReady = 0, ModbusATxCnt = 0, ModbusATxDataLength = 0; unsigned int ModbusACharTime = 0, ModbusACnt = 0, ModbusAStop = 0, ModbusACharTimeset = 8; unsigned int ModbusAExceptionCode = 0; unsigned char ModbusARxBuf[MODBUSA_RECEIVE_MAX_BYTE]; unsigned char ModbusATxBuf[MODBUSA_TRANS_MAX_BYTE]; unsigned int ModbusA_Connection_Check = 0; unsigned int Flag_ModbusA_Data_reset = 0; volatile void *ModbusAPtr[MODBUSAPTRMAX]; unsigned int ModbusATxWaitCnt = 0; unsigned int ModbusAFrmStartFlag = 0; unsigned int ModbusARxMaxFlag = 0; unsigned int ModbusARxStop = 0; #pragma SET_DATA_SECTION() #endif //--------------------------------------------------------------------------------------------------// #if (MODBUSA_ENB) void ModbusACheckBuffer() { int kk = 0; if (MODBUSA_RX_OVF == 0) { if (MODBUSA_RX_FIFO != 0) { if (ModbusAFrmStartFlag == 0) { ModbusARxBuf[0] = MODBUSA_RX_BUF; if (ModbusARxBuf[0] == ModbusASlaveID) { ModbusAFrmStartFlag = 1; ModbusARxCnt = 1; } } else if (ModbusAFrmStartFlag == 1) { if (ModbusARxCnt <= MODBUSA_RECEIVE_MAX_BYTE) { ModbusARxBuf[ModbusARxCnt++] = MODBUSA_RX_BUF; } else { ModbusAFrmStartFlag = 0; ModbusARxCnt = 0; } } ModbusACharTime = 0; ModbusAStop = 0; } // else if (MODBUSA_RX_FIFO == 0) { if (ModbusACharTime <= ModbusACharTimeset) ModbusACharTime++; else if (ModbusACharTime > ModbusACharTimeset) { ModbusACharTime = 0; kk = ModbusARxCnt; ModbusARxCnt = 0; if (ModbusAFrmStartFlag == 1) { ModbusACnt = kk; if ((ModbusARxBuf[0] == ModbusASlaveID) && (ModbusACnt >= 4)) { if (ModbusACRC16(ModbusACnt - 2, 1)) // CRC check { //CRC memcpy(&ModbusATxBuf, &ModbusARxBuf, ModbusACnt); ModbusARxOk = 1; } } } ModbusAFrmStartFlag = 0; } } } else { MODBUSA_RX_OVFCLR = 1; MODBUSA_RX_FIFO_RST = 0; MODBUSA_RX_FIFO_RST = 1; } if (ModbusATxReady == 1) { if (MODBUSA_TX_FIFO < 16) { if (ModbusATxCnt < (ModbusATxDataLength)) { MODBUSA_TX_BUF = ModbusATxBuf[ModbusATxCnt]; ModbusATxCnt++; ModbusATxWaitCnt = 0; } else { if (MODBUSA_TX_EMTPY == 1) { if (ModbusATxWaitCnt++ > (ModbusACharTimeset - 1)) { ModbusATxReady = 0; ModbusATxCnt = 0; ModbusATxWaitCnt = 0; } } else { } } } } if (MODBUSA_RX_ERROR != 0) MODBUSA_SWRESET; } void ModbusAResponse() // 10msec routine { if (ModbusARxOk == 1) { if (ModbusACnt > MODBUSA_RECEIVE_MAX_BYTE) { ModbusAExceptionCode = 2; ModbusABadResponse(); //to many bytes in frame */ } else if (ModbusACnt < MODBUSA_RECEIVE_MIN_BYTE) { ModbusAExceptionCode = 2; ModbusABadResponse(); //to few bytes frame*/ } else { if (ModbusATxBuf[1] == 3) ModbusA3rdResponse(); else if (ModbusATxBuf[1] == 4) ModbusA4thResponse(); else if (ModbusATxBuf[1] == 6) ModbusA6thResponse(); else if (ModbusATxBuf[1] == 16) ModbusA16thResponse(); else ModbusABadResponse(); } ModbusARxOk = 0; } } int ModbusACRC16(int dataLength, int RXTXset) //CRC 16 for SERIAL checksum { //RXTXset : 0 TX CRC, 1 RX CRC Uint16 lowCRC; Uint16 highCRC; Uint16 CRC; Uint16 CRC_OK; if (RXTXset == 1) { CRC = CRC16(ModbusARxBuf, dataLength); highCRC = (CRC >> 8) & 0x00FF; lowCRC = (CRC & 0x00FF); if (ModbusARxBuf[dataLength + 1] == highCRC) { if (ModbusARxBuf[dataLength] == lowCRC) CRC_OK = 1; else CRC_OK = 0; //for test } else CRC_OK = 0; } else if (RXTXset == 0) { CRC = CRC16(ModbusATxBuf, dataLength); highCRC = (CRC >> 8) & 0x00FF; lowCRC = (CRC & 0x00FF); ModbusATxBuf[dataLength] = lowCRC; ModbusATxBuf[dataLength + 1] = highCRC; CRC_OK = 1; } return CRC_OK; } void ModbusA3rdResponse() //response for ipos 03 function (read registers) { int j, temp_address, temp_length, *temp_data; temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x00ff); temp_length = ModbusATxBuf[5] & 0x00ff; ModbusATxBuf[2] = temp_length * 2; for (j = 0; j < temp_length; j++) { temp_data = (int*) (ModbusAPtr[MODBUSA_START_ADDR + temp_address + j]); ModbusATxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0x00ff; ModbusATxBuf[j * 2 + 4] = (*temp_data & 0x00ff); } ModbusATxReady = ModbusACRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA ModbusATxDataLength = temp_length * 2 + 5; } void ModbusA4thResponse() //response for MODBUS 4 function read registers { int temp_address, temp_length, *temp_data, j; temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff); temp_length = ModbusATxBuf[5] & 0xff; ModbusATxBuf[2] = temp_length * 2; for (j = 0; j < temp_length; j++) { temp_data = (int*) (ModbusAPtr[MODBUSA_START_ADDR + temp_address + j]); ModbusATxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0xff; ModbusATxBuf[j * 2 + 4] = (*temp_data & 0xff); } ModbusATxReady = ModbusACRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA ModbusATxDataLength = temp_length * 2 + 5; // ModbusTxDataLength=temp_length*2+7; } void ModbusA6thResponse() //response for MODBUS 3 function write single registers { int temp_address; int temp_data; int *ari1; temp_address = (short) ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff); if (ModbusASerialRange(temp_address) == 1) ModbusAExceptionCode = 2; else { temp_data = (((ModbusATxBuf[4] & 0xff) << 8) & 0xff00) + (ModbusATxBuf[5] & 0xff); ari1 = (int*) ModbusAPtr[MODBUSA_START_ADDR + temp_address]; if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000); else *ari1 = temp_data; ModbusATxReady = ModbusACRC16(6, 0); ModbusATxDataLength = 8; } } void ModbusA16thResponse() //response for MODBUS 16 function write multiple registers { int temp_address, temp_length, j; register int temp_data; int *ari1; temp_address = ((ModbusATxBuf[2] << 8) & 0x0ff00) + (ModbusATxBuf[3] & 0x0ff); temp_length = ModbusATxBuf[5] & 0xff; if (ModbusASerialRange(temp_address + temp_length) == 1) ModbusAExceptionCode = 2; else { for (j = 0; j < temp_length; j++) { temp_data = (((ModbusATxBuf[7 + 2 * j] & 0xff) << 8) & 0xff00) + (ModbusATxBuf[8 + 2 * j] & 0xff); ari1 = (int*) ModbusAPtr[MODBUSA_START_ADDR + temp_address + j]; if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000); else *ari1 = temp_data; } } ModbusATxReady = ModbusACRC16(6, 0); ModbusATxDataLength = 8; } void ModbusABadResponse() { ModbusATxBuf[0] = ModbusASlaveID; ModbusATxBuf[1] = ModbusATxBuf[1] + 0x00000080; ModbusATxBuf[2] = ModbusAExceptionCode; ModbusATxReady = ModbusACRC16(3, 0); ModbusATxDataLength = 5; } int ModbusASerialRange(int address) { if ((address >= 0) && (address < MODBUSA_MAX_ADDR)) return 0; //read write enable else return 1; //read only } void Init_ModbusA_Buffer() { memset(&ModbusARxBuf, 0, sizeof(ModbusARxBuf) / sizeof(int)); memset(&ModbusATxBuf, 0, sizeof(ModbusATxBuf) / sizeof(int)); } #endif //-------------------------ModbusB------------------------------------------------------// #if (MODBUSB_ENB) #define MODBUSB_RX_RDY ScibRegs.SCIRXST.bit.RXRDY #define MODBUSB_RX_FIFO ScibRegs.SCIFFRX.bit.RXFFST #define MODBUSB_RX_FIFO_RST ScibRegs.SCIFFRX.bit.RXFIFORESET #define MODBUSB_RX_OVF ScibRegs.SCIFFRX.bit.RXFFOVF #define MODBUSB_RX_OVFCLR ScibRegs.SCIFFRX.bit.RXFFOVRCLR #define MODBUSB_RX_BUF ScibRegs.SCIRXBUF.bit.SAR #define MODBUSB_RX_ERROR ScibRegs.SCIRXST.bit.RXERROR #define MODBUSB_TX_RDY ScibRegs.SCICTL2.bit.TXRDY #define MODBUSB_TX_FIFO ScibRegs.SCIFFTX.bit.TXFFST #define MODBUSB_TX_BUF ScibRegs.SCITXBUF.bit.TXDT #define MODBUSB_TX_EMTPY ScibRegs.SCICTL2.bit.TXEMPTY #define MODBUSB_SWRESET ScibRegs.SCICTL1.bit.SWRESET = 0,\ ScibRegs.SCICTL1.all = 0x0023 #define MODBUSB_FIFO_RST ScibRegs.SCIFFTX.bit.SCIRST = 1; //#define MODBUSB_RX_RDY ScidRegs.SCIRXST.bit.RXRDY //#define MODBUSB_RX_FIFO ScidRegs.SCIFFRX.bit.RXFFST //#define MODBUSB_RX_FIFO_RST ScidRegs.SCIFFRX.bit.RXFIFORESET //#define MODBUSB_RX_OVF ScidRegs.SCIFFRX.bit.RXFFOVF //#define MODBUSB_RX_OVFCLR ScidRegs.SCIFFRX.bit.RXFFOVRCLR // //#define MODBUSB_RX_BUF ScidRegs.SCIRXBUF.bit.SAR //#define MODBUSB_RX_ERROR ScidRegs.SCIRXST.bit.RXERROR // //#define MODBUSB_TX_RDY ScidRegs.SCICTL2.bit.TXRDY //#define MODBUSB_TX_FIFO ScidRegs.SCIFFTX.bit.TXFFST //#define MODBUSB_TX_BUF ScidRegs.SCITXBUF.bit.TXDT //#define MODBUSB_TX_EMTPY ScidRegs.SCICTL2.bit.TXEMPTY //#define MODBUSB_SWRESET ScidRegs.SCICTL1.bit.SWRESET = 0,\ // ScidRegs.SCICTL1.all = 0x0023 //#define MODBUSB_FIFO_RST ScidRegs.SCIFFTX.bit.SCIRST = 1; //---------------------------- Serial Modbus B set parameter RS485----------------------------------// #define MODBUSB_LSPCLK (CPUCLK/4) // Peripheral Low Speed Clock for SCI- #define MODBUSB_BAUDRATE 38400L #define MODBUSB_BRR_VAL (MODBUSB_LSPCLK/(8*MODBUSB_BAUDRATE)-1) // MODBUSB BaudRate ���� Register �� //16�� funccode�� 123�� ���� write ��ɽ� 231 ����Ʈ #define MODBUSB_RECEIVE_MAX_BYTE 400 #define MODBUSB_RECEIVE_MIN_BYTE 2 #define MODBUSB_TRANS_MAX_BYTE 400 #define MODBUSB_START_ADDR 0 #define MODBUSB_MAX_ADDR 1500 unsigned int ModbusBSlaveID = 2; unsigned int ModbusBRxCnt = 0, ModbusBRxOk = 0, ModbusBRxErr = 0, ModbusBTxReady = 0, ModbusBTxCnt = 0, ModbusBTxDataLength = 0; unsigned int ModbusBCharTime = 0, ModbusBCnt = 0, ModbusBStop = 0, ModbusBCharTimeset = 8; unsigned int ModbusBExceptionCode = 0; unsigned char ModbusBRxBuf[MODBUSB_RECEIVE_MAX_BYTE]; unsigned char ModbusBTxBuf[MODBUSB_TRANS_MAX_BYTE]; unsigned int ModbusB_Connection_Check = 0; unsigned int Flag_ModbusB_Data_reset = 0; volatile void *ModbusBPtr[MODBUSBPTRMAX]; unsigned int ModbusBTxWaitCnt = 0; unsigned int ModbusBFrmStartFlag = 0; unsigned int ModbusBRxMaxFlag = 0; unsigned int ModbusBRxStop = 0; #endif //--------------------------------------------------------------------------------------------------// #if (MODBUSB_ENB) void ModbusBCheckBuffer() { int kk = 0; if (MODBUSB_RX_OVF == 0) { if (MODBUSB_RX_FIFO != 0) { if (ModbusBFrmStartFlag == 0) { ModbusBRxBuf[0] = MODBUSB_RX_BUF; if (ModbusBRxBuf[0] == ModbusBSlaveID) { ModbusBFrmStartFlag = 1; ModbusBRxCnt = 1; } } else if (ModbusBFrmStartFlag == 1) { if (ModbusBRxCnt <= MODBUSB_RECEIVE_MAX_BYTE) { ModbusBRxBuf[ModbusBRxCnt++] = MODBUSB_RX_BUF; } else { ModbusBFrmStartFlag = 0; ModbusBRxCnt = 0; } } ModbusBCharTime = 0; ModbusBStop = 0; } // else if (MODBUSB_RX_FIFO == 0) { if (ModbusBCharTime <= ModbusBCharTimeset) ModbusBCharTime++; else if (ModbusBCharTime > ModbusBCharTimeset) { ModbusBCharTime = 0; kk = ModbusBRxCnt; ModbusBRxCnt = 0; if (ModbusBFrmStartFlag == 1) { ModbusBCnt = kk; if ((ModbusBRxBuf[0] == ModbusBSlaveID) && (ModbusBCnt >= 4)) { if (ModbusBCRC16(ModbusBCnt - 2, 1)) // ���ŵ� ������ CRC check { //CRC ���� memcpy(&ModbusBTxBuf, &ModbusBRxBuf, ModbusBCnt); ModbusBRxOk = 1; } } } ModbusBFrmStartFlag = 0; } } } else { MODBUSB_RX_OVFCLR = 1; MODBUSB_RX_FIFO_RST = 0; MODBUSB_RX_FIFO_RST = 1; } if (ModbusBTxReady == 1) { if (MODBUSB_TX_FIFO < 16) { if (ModbusBTxCnt < (ModbusBTxDataLength)) { MODBUSB_TX_BUF = ModbusBTxBuf[ModbusBTxCnt]; ModbusBTxCnt++; ModbusBTxWaitCnt = 0; } else { if (MODBUSB_TX_EMTPY == 1) { if (ModbusBTxWaitCnt++ > (ModbusBCharTimeset - 1)) { ModbusBTxReady = 0; ModbusBTxCnt = 0; ModbusBTxWaitCnt = 0; } } else { } } } } if (MODBUSB_RX_ERROR != 0) MODBUSB_SWRESET; } void ModbusBResponse() // 10msec routine�� ���� { if (ModbusBRxOk == 1) { if (ModbusBCnt > MODBUSB_RECEIVE_MAX_BYTE) { ModbusBExceptionCode = 2; ModbusBBadResponse(); //to many bytes in frame */ } else if (ModbusBCnt < MODBUSB_RECEIVE_MIN_BYTE) { ModbusBExceptionCode = 2; ModbusBBadResponse(); //to few bytes frame*/ } else { if (ModbusBTxBuf[1] == 3) ModbusB3rdResponse(); else if (ModbusBTxBuf[1] == 4) ModbusB4thResponse(); else if (ModbusBTxBuf[1] == 6) ModbusB6thResponse(); else if (ModbusBTxBuf[1] == 16) ModbusB16thResponse(); else ModbusBBadResponse(); } ModbusBRxOk = 0; } } int ModbusBCRC16(int dataLength, int RXTXset) //CRC 16 for SERIAL checksum { //RXTXset : 0 TX CRC, 1 RX CRC Uint16 lowCRC; Uint16 highCRC; Uint16 CRC; Uint16 CRC_OK; if (RXTXset == 1) { CRC = CRC16(ModbusBRxBuf, dataLength); highCRC = (CRC >> 8) & 0x00FF; lowCRC = (CRC & 0x00FF); if (ModbusBRxBuf[dataLength + 1] == highCRC) { if (ModbusBRxBuf[dataLength] == lowCRC) CRC_OK = 1; else CRC_OK = 0; //for test dInverter_Status++; } else CRC_OK = 0; } else if (RXTXset == 0) { CRC = CRC16(ModbusBTxBuf, dataLength); highCRC = (CRC >> 8) & 0x00FF; lowCRC = (CRC & 0x00FF); ModbusBTxBuf[dataLength] = lowCRC; ModbusBTxBuf[dataLength + 1] = highCRC; CRC_OK = 1; } return CRC_OK; } void ModbusB3rdResponse() //response for ipos 03 function (read registers) { int j, temp_address, temp_length, *temp_data; temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x00ff); temp_length = ModbusBTxBuf[5] & 0x00ff; ModbusBTxBuf[2] = temp_length * 2; for (j = 0; j < temp_length; j++) { temp_data = (int*) (ModbusBPtr[MODBUSB_START_ADDR + temp_address + j]); // ����address���� temp_length ��ŭ ModbusBTxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0x00ff; ModbusBTxBuf[j * 2 + 4] = (*temp_data & 0x00ff); } ModbusBTxReady = ModbusBCRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA ModbusBTxDataLength = temp_length * 2 + 5; } void ModbusB4thResponse() //response for MODBUS 4 function read registers { int temp_address, temp_length, *temp_data, j; temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff); temp_length = ModbusBTxBuf[5] & 0xff; ModbusBTxBuf[2] = temp_length * 2; for (j = 0; j < temp_length; j++) { temp_data = (int*) (ModbusBPtr[MODBUSB_START_ADDR + temp_address + j]); ModbusBTxBuf[j * 2 + 3] = ((*temp_data & 0x0ff00) >> 8) & 0xff; ModbusBTxBuf[j * 2 + 4] = (*temp_data & 0xff); } ModbusBTxReady = ModbusBCRC16(temp_length * 2 + 3, 0); //ADD+FUNC(2)+DATA ModbusBTxDataLength = temp_length * 2 + 5; // ModbusTxDataLength=temp_length*2+7; } void ModbusB6thResponse() //response for MODBUS 3 function write single registers { int temp_address; int temp_data; int *ari1; temp_address = (short) ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff); if (ModbusBSerialRange(temp_address) == 1) ModbusBExceptionCode = 2; else { temp_data = (((ModbusBTxBuf[4] & 0xff) << 8) & 0xff00) + (ModbusBTxBuf[5] & 0xff); ari1 = (int*) ModbusBPtr[MODBUSB_START_ADDR + temp_address]; if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000); else *ari1 = temp_data; ModbusBTxReady = ModbusBCRC16(6, 0); ModbusBTxDataLength = 8; } } void ModbusB16thResponse() //response for MODBUS 16 function write multiple registers { int temp_address, temp_length, j; register int temp_data; int *ari1; temp_address = ((ModbusBTxBuf[2] << 8) & 0x0ff00) + (ModbusBTxBuf[3] & 0x0ff); temp_length = ModbusBTxBuf[5] & 0xff; if (ModbusBSerialRange(temp_address + temp_length) == 1) ModbusBExceptionCode = 2; else { for (j = 0; j < temp_length; j++) { temp_data = (((ModbusBTxBuf[7 + 2 * j] & 0xff) << 8) & 0xff00) + (ModbusBTxBuf[8 + 2 * j] & 0xff); ari1 = (int*) ModbusBPtr[MODBUSB_START_ADDR + temp_address + j]; if (temp_data > 32767) *ari1 = (temp_data | 0xffff0000); else *ari1 = temp_data; } } ModbusBTxReady = ModbusBCRC16(6, 0); ModbusBTxDataLength = 8; } void ModbusBBadResponse() { ModbusBTxBuf[0] = ModbusBSlaveID; ModbusBTxBuf[1] = ModbusBTxBuf[1] + 0x00000080; ModbusBTxBuf[2] = ModbusBExceptionCode; ModbusBTxReady = ModbusBCRC16(3, 0); ModbusBTxDataLength = 5; } int ModbusBSerialRange(int address) { if ((address >= 0) && (address < MODBUSB_MAX_ADDR)) return 0; //read write enable else return 1; //read only } void Init_ModbusB_Buffer() { memset(&ModbusBRxBuf, 0, sizeof(ModbusBRxBuf) / sizeof(int)); memset(&ModbusBTxBuf, 0, sizeof(ModbusBTxBuf) / sizeof(int)); } #endif float Char3_5Time = 0.; void InitModbusSci() { #if (MODBUSA_ENB) ScicRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable ScicRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable ScicRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable ScicRegs.SCIFFTX.bit.TXFIFORESET = 1; ScicRegs.SCIFFRX.bit.RXFIFORESET = 1; ScicRegs.SCIFFCT.bit.FFTXDLY = 0; // ScicRegs.SCIFFTX.bit.SCIRST = 1; ScicRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit) ScicRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol ScicRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK, // Disable RX ERR, SLEEP, TXWAKE // ScicRegs.SCICTL2.all = 0x0003; // ScicRegs.SCICTL2.bit.RXBKINTENA = 1; // RX/BK INT ENA=1, // ScicRegs.SCICTL2.bit.TXINTENA = 1; // TX INT ENA=1, ScicRegs.SCIHBAUD.bit.BAUD = (MODBUSA_BRR_VAL >> 8); ScicRegs.SCILBAUD.bit.BAUD = (MODBUSA_BRR_VAL & 0xFF); ScicRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset Init_ModbusA_Buffer(); // 11bit per char Char3_5Time = 1.0 / MODBUSA_BAUDRATE * 11 * 3.5; if(Char3_5Time <= 1.75e-3 ) Char3_5Time = 1.75e-3; //1.75ms 이하인 경우 1.75ms ModbusACharTimeset = (unsigned int)(Char3_5Time / Tsamp); #endif #if(MODBUSB_ENB) //-------------------------------------SCI-B----------------------------------------------------// ScibRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable ScibRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable ScibRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable ScibRegs.SCIFFTX.bit.TXFIFORESET = 1; ScibRegs.SCIFFRX.bit.RXFIFORESET = 1; ScibRegs.SCIFFCT.bit.FFTXDLY = 0; ScibRegs.SCIFFTX.bit.SCIRST = 1; ScibRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit) ScibRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol ScibRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK, ScibRegs.SCIHBAUD.bit.BAUD = (MODBUSB_BRR_VAL >> 8); ScibRegs.SCILBAUD.bit.BAUD = (MODBUSB_BRR_VAL & 0xFF); ScibRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset //-------------------------------------SCI-D----------------------------------------------------// // ScidRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable // // ScidRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable // ScidRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable // ScidRegs.SCIFFTX.bit.TXFIFORESET = 1; // ScidRegs.SCIFFRX.bit.RXFIFORESET = 1; // ScidRegs.SCIFFCT.bit.FFTXDLY = 0; // // // ScidRegs.SCIFFTX.bit.SCIRST = 1; // // ScidRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit) // // ScidRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback // // No parity,8 char bits, // // async mode, idle-line protocol // ScidRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK, // // ScidRegs.SCIHBAUD.bit.BAUD = (MODBUSB_BRR_VAL >> 8); // ScidRegs.SCILBAUD.bit.BAUD = (MODBUSB_BRR_VAL & 0xFF); // // ScidRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset Init_ModbusB_Buffer(); Char3_5Time = 1.0 / MODBUSB_BAUDRATE * 11 * 3.5; if(Char3_5Time <= 1.75e-3 ) Char3_5Time = 1.75e-3; //char 타임자동계산 ModbusBCharTimeset = (unsigned int)(Char3_5Time / Tsamp); #endif InitModbusPtr(); } //-------------------------ModbusA/B ���� �Լ�--------------------------------------// void ModbusALLCheckBuffer() { #if(MODBUSA_ENB) ModbusACheckBuffer(); #endif #if(MODBUSB_ENB) ModbusBCheckBuffer(); #endif } void ModbusALLResponse() { #if(MODBUSA_ENB) ModbusAResponse(); #endif #if(MODBUSB_ENB) ModbusBResponse(); #endif } void InitSci() { // SCI_setConfig(SCID_BASE, DEVICE_LSPCLK_FREQ, 9600, (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE)); // SCI_resetChannels(SCID_BASE); // SCI_resetRxFIFO(SCID_BASE); // SCI_resetTxFIFO(SCID_BASE); // SCI_clearInterruptStatus(SCID_BASE, SCI_INT_TXFF | SCI_INT_RXFF); // SCI_enableFIFO(SCID_BASE); // SCI_enableModule(SCID_BASE); // SCI_performSoftwareReset(SCID_BASE); ScidRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO Enable ScidRegs.SCIFFTX.bit.TXFFIENA = 0; //FIFO Tx-Interrupt Disable ScidRegs.SCIFFRX.bit.RXFFIENA = 0; //FIFO Rx-Interrupt Disable ScidRegs.SCIFFTX.bit.TXFIFORESET = 1; ScidRegs.SCIFFRX.bit.RXFIFORESET = 1; ScidRegs.SCIFFCT.bit.FFTXDLY = 0; // ScidRegs.SCIFFTX.bit.SCIRST = 1; ScidRegs.SCIFFCT.bit.ABDCLR = 1; // Clear ABD(Auto baud bit) ScidRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol ScidRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK, // Disable RX ERR, SLEEP, TXWAKE // ScicRegs.SCICTL2.all = 0x0003; // ScicRegs.SCICTL2.bit.RXBKINTENA = 1; // RX/BK INT ENA=1, // ScicRegs.SCICTL2.bit.TXINTENA = 1; // TX INT ENA=1, ScidRegs.SCIHBAUD.bit.BAUD = (MODBUSA_BRR_VAL >> 8); ScidRegs.SCILBAUD.bit.BAUD = (MODBUSA_BRR_VAL & 0xFF); ScidRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset }