DSP

DSP28335 高速modbus代码实现

2019-07-13 10:34发布

class="markdown_views prism-atom-one-light"> 程序特点
  • 不使用while循环
  • 速度尽可能快速
  • 除去程序运行时间,没有多余等待时间
  • 优化CRC校验方式
头文件modbus.h #ifndef MODBUS_H #define MODBUS_H #define ModbusSlaveAddress 1 typedef enum { MB_FUNC_READ_COIL = 1, MB_FUNC_READ_INPUT, MB_FUNC_READ_HOLDINGREGISTERS, MB_FUNC_READ_INPUTREGISTERS, MB_FUNC_FORCE_COIL, MB_FUNC_WRITE_HOLDINGREGISTER, MB_FUNC_FORCE_NCOILS = 15, MB_FUNC_WRITE_NREGISTERS = 16 } ModbusFunctionCode; typedef enum { MB_ERROR_ILLEGALFUNC = 1, MB_ERROR_ILLEGALADDR, MB_ERROR_ILLEGALDATA, MB_ERROR_SLVFAILURE, MB_ERROR_ACKNOWLEDGE, MB_ERROR_SLVBUSY, MB_ERROR_NEGACKNOWLEDGE, MB_ERROR_MEMPARITY, MB_ERROR_GATEWAYPATHUN } ModbusError; // State machine constants typedef enum { MB_CREATE, MB_START, MB_TIMER_T35_WAIT, MB_IDLE, MB_RECEIVE, MB_PROCESS, MB_TRANSMIT, MB_DESTROY } ModbusState; typedef struct ModbusData ModbusData; struct ModbusData { Uint16 slaveAddress; Uint16 functionCode; Uint32 contentIdx; Uint32 numofregisters; Uint16 content[20]; Uint16 size; Uint16 crc; }; void KD_Modbus_Init(void); typedef struct ModbusCoilsMap ModbusCoilsMap; struct ModbusCoilsMap{ Uint16 dummy1; Uint16 dummy2; Uint16 dummy3; Uint16 dummy4; Uint16 dummy5; Uint16 dummy6; Uint16 dummy7; Uint16 dummy8; Uint16 dummy9; Uint16 dummy10; Uint16 dummy11; Uint16 dummy12; Uint16 dummy13; Uint16 dummy14; Uint16 dummy15; Uint16 dummy16; Uint16 dummy17; Uint16 dummy18; Uint16 dummy19; Uint16 dummy20; Uint16 dummy21; Uint16 dummy22; Uint16 dummy23; Uint16 dummy24; Uint16 dummy25; Uint16 dummy26; Uint16 dummy27; Uint16 dummy28; Uint16 dummy29; Uint16 dummy30; Uint16 dummy31; Uint16 dummy32; Uint16 dummy33; Uint16 dummy34; Uint16 dummy35; Uint16 dummy36; Uint16 dummy37; Uint16 dummy38; Uint16 dummy39; Uint16 dummy40; }; typedef struct ModbusInputsMap ModbusInputsMap; struct ModbusInputsMap{ Uint16 dummy1; Uint16 dummy2; Uint16 dummy3; Uint16 dummy4; Uint16 dummy5; Uint16 dummy6; Uint16 dummy7; Uint16 dummy8; Uint16 dummy9; Uint16 dummy10; Uint16 dummy11; Uint16 dummy12; Uint16 dummy13; Uint16 dummy14; Uint16 dummy15; Uint16 dummy16; Uint16 dummy17; Uint16 dummy18; Uint16 dummy19; Uint16 dummy20; Uint16 dummy21; Uint16 dummy22; Uint16 dummy23; Uint16 dummy24; Uint16 dummy25; Uint16 dummy26; Uint16 dummy27; Uint16 dummy28; Uint16 dummy29; Uint16 dummy30; Uint16 dummy31; Uint16 dummy32; Uint16 dummy33; Uint16 dummy34; Uint16 dummy35; Uint16 dummy36; Uint16 dummy37; Uint16 dummy38; Uint16 dummy39; Uint16 dummy40; }; typedef struct ModbusHoldingRegistersMap ModbusHoldingRegistersMap; struct ModbusHoldingRegistersMap { Uint16 dummy1; Uint16 dummy2; Uint16 dummy3; Uint16 dummy4; Uint16 dummy5; Uint16 dummy6; Uint16 dummy7; Uint16 dummy8; Uint16 dummy9; Uint16 dummy10; Uint16 dummy11; Uint16 dummy12; Uint16 dummy13; Uint16 dummy14; Uint16 dummy15; Uint16 dummy16; Uint16 dummy17; Uint16 dummy18; Uint16 dummy19; Uint16 dummy20; Uint16 dummy21; Uint16 dummy22; Uint16 dummy23; Uint16 dummy24; Uint16 dummy25; Uint16 dummy26; Uint16 dummy27; Uint16 dummy28; Uint16 dummy29; Uint16 dummy30; Uint16 dummy31; Uint16 dummy32; Uint16 dummy33; Uint16 dummy34; Uint16 dummy35; Uint16 dummy36; Uint16 dummy37; Uint16 dummy38; Uint16 dummy39; Uint16 dummy40; }; typedef struct ModbusInputRegistersMap ModbusInputRegistersMap; struct ModbusInputRegistersMap { Uint16 dummy1; Uint16 dummy2; Uint16 dummy3; Uint16 dummy4; Uint16 dummy5; Uint16 dummy6; Uint16 dummy7; Uint16 dummy8; Uint16 dummy9; Uint16 dummy10; Uint16 dummy11; Uint16 dummy12; Uint16 dummy13; Uint16 dummy14; Uint16 dummy15; Uint16 dummy16; Uint16 dummy17; Uint16 dummy18; Uint16 dummy19; Uint16 dummy20; Uint16 dummy21; Uint16 dummy22; Uint16 dummy23; Uint16 dummy24; Uint16 dummy25; Uint16 dummy26; Uint16 dummy27; Uint16 dummy28; Uint16 dummy29; Uint16 dummy30; Uint16 dummy31; Uint16 dummy32; Uint16 dummy33; Uint16 dummy34; Uint16 dummy35; Uint16 dummy36; Uint16 dummy37; Uint16 dummy38; Uint16 dummy39; Uint16 dummy40; }; typedef struct ModbusSlaveStruc{ ModbusState state; Uint16 rdata[30]; Uint16 sdata[100]; Uint16 recvlen; Uint16 sendlen; ModbusCoilsMap coils,*pcoils; ModbusInputsMap inputs,*pinputs; ModbusHoldingRegistersMap holdingRegisters,*pholdingRegisters; ModbusInputRegistersMap inputRegisters,*pinputRegisters; }MBSLSTRU; #endif 源文件modbus.c /********************************************************* * 处理一个数据需要8个us,所以尽可能一次多访问几个数据,可以一次把40个寄存器读完 * 发送命令计算校验码时,前后都不能有多余字符,不然校验会出错 * 波特率460800,暂时不修改 * ***************************************************************/ #include #include #include #include //用于清零数组 MBSLSTRU public_struc_modbus; void receieve_handler(MBSLSTRU *pModbusSlave); //void Scic_xmit(int a); Uint16 CRC16 (Uint16 *nData, Uint16 wLength); #define bufferdepth 0x10 //CycleQueue ScicRecvMsgQueue; //struct ScicRecvMsgQueueStruc ScicRecvMsgBox[ScicRecvMsgLen], *pScicRecvMsgQueueStruc; __interrupt void scicTxFifoIsr(void) { Uint16 i, Temp; if((public_struc_modbus.sendlen&0xff)>bufferdepth) { Temp = bufferdepth; ScicRegs.SCIFFTX.bit.TXFFIL = 0; for(i=0; i< Temp; i++) { ScicRegs.SCITXBUF = public_struc_modbus.sdata[i + bufferdepth*(public_struc_modbus.sendlen>>12)]; } public_struc_modbus.sendlen = public_struc_modbus.sendlen - bufferdepth + 0x1000; } else { Temp = (public_struc_modbus.sendlen&0xff); if((public_struc_modbus.sendlen&0xff)>0) { ScicRegs.SCIFFTX.bit.TXFFIL = 0; for(i=0; i< Temp; i++) { ScicRegs.SCITXBUF = public_struc_modbus.sdata[i + bufferdepth*(public_struc_modbus.sendlen>>12)]; } public_struc_modbus.sendlen = 0; } else { if(public_struc_modbus.sendlen==0) { ScicRegs.SCIFFTX.bit.TXFFIENA = 0; } } } ScicRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag PieCtrlRegs.PIEACK.bit.ACK8=1; } __interrupt void scicRxFifoIsr(void) { Uint16 i; if(ScicRegs.SCIFFRX.bit.RXFFIL != 1) { if(public_struc_modbus.rdata[1]==0) { for(i=1;i<8;i++) { public_struc_modbus.rdata[i]=ScicRegs.SCIRXBUF.all; // Read data } } if((public_struc_modbus.rdata[1]==15)||(public_struc_modbus.rdata[1]==16)) { if(public_struc_modbus.recvlen == 0) { public_struc_modbus.recvlen = public_struc_modbus.rdata[6] + 9 + 0x1000; ScicRegs.SCIFFRX.bit.RXFFIL = 8; i = public_struc_modbus.recvlen&0xff - ((public_struc_modbus.recvlen>>12)*8); if(i>8) {ScicRegs.SCIFFRX.bit.RXFFIL = 8;} else {ScicRegs.SCIFFRX.bit.RXFFIL = i;} } else { if((public_struc_modbus.recvlen>>12)<((public_struc_modbus.recvlen&0xFF)/8)) { for(i=0;i<8;i++) { public_struc_modbus.rdata[i+(public_struc_modbus.recvlen>>12)*8]=ScicRegs.SCIRXBUF.all; // Read data } public_struc_modbus.recvlen = public_struc_modbus.recvlen + 0x1000; i = public_struc_modbus.recvlen&0xff - ((public_struc_modbus.recvlen>>12)*8); if(i>8) {ScicRegs.SCIFFRX.bit.RXFFIL = 8;} else {ScicRegs.SCIFFRX.bit.RXFFIL = i;} } else { for(i=0;i<((public_struc_modbus.recvlen&0xFF)%8);i++) { public_struc_modbus.rdata[i+(public_struc_modbus.recvlen>>12)*8]=ScicRegs.SCIRXBUF.all; // Read data } if((public_struc_modbus.recvlen&0xFF) <= (i+(public_struc_modbus.recvlen>>12)*8)) { receieve_handler(&public_struc_modbus); public_struc_modbus.rdata[1] = 0; ScicRegs.SCIFFRX.bit.RXFFIL = 1; public_struc_modbus.recvlen = 0; } } } } else { public_struc_modbus.recvlen = 8; if((public_struc_modbus.rdata[1]>=1)&&(public_struc_modbus.rdata[1]<=6)) { receieve_handler(&public_struc_modbus); public_struc_modbus.rdata[1] = 0; public_struc_modbus.recvlen = 0; ScicRegs.SCIFFRX.bit.RXFFIL = 1; } else { receieve_handler(&public_struc_modbus); public_struc_modbus.rdata[1] = 0; ScicRegs.SCIFFRX.bit.RXFFIL = 1; } } } else { public_struc_modbus.rdata[0]=ScicRegs.SCIRXBUF.all; if(public_struc_modbus.rdata[0] == ModbusSlaveAddress) {ScicRegs.SCIFFRX.bit.RXFFIL = 7;} else {ScicRegs.SCIFFRX.bit.RXFFIL = 1;} } ScicRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag ScicRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag PieCtrlRegs.PIEACK.bit.ACK8=1; } void KD_Modbus_Init(void) { InitScicGpio(); InitSci(); EALLOW; PieVectTable.SCIRXINTC = &scicRxFifoIsr; PieVectTable.SCITXINTC = &scicTxFifoIsr; EDIS; PieCtrlRegs.PIECTRL.bit.ENPIE = 1; PieCtrlRegs.PIEIER8.bit.INTx5=1; // PIE Group 9, int1 PieCtrlRegs.PIEIER8.bit.INTx6=1; // PIE Group 9, INT2 IER|=M_INT8; // Enable CPU INT public_struc_modbus.recvlen = 0; public_struc_modbus.sendlen = 0; Uint16 i, *pcoils_sub, *pinputs_sub, *pholdingRegisters_sub, *pinputRegisters_sub; public_struc_modbus.pcoils = &public_struc_modbus.coils; public_struc_modbus.pinputs = &public_struc_modbus.inputs; public_struc_modbus.pholdingRegisters = &public_struc_modbus.holdingRegisters; public_struc_modbus.pinputRegisters = &public_struc_modbus.inputRegisters; pcoils_sub =(Uint16 *) public_struc_modbus.pcoils; pinputs_sub =(Uint16 *) public_struc_modbus.pinputs; pholdingRegisters_sub =(Uint16 *) public_struc_modbus.pholdingRegisters; pinputRegisters_sub =(Uint16 *) public_struc_modbus.pinputRegisters; for(i=0;i<sizeof(public_struc_modbus.coils);i++) {(i%2==1)?(*(pcoils_sub+i)=1):(*(pcoils_sub+i)=0);} for(i=0;i<sizeof(public_struc_modbus.inputs);i++) {(i%2==0)?(*(pinputs_sub+i)=1):(*(pinputs_sub+i)=0);} for(i=0;i<sizeof(public_struc_modbus.holdingRegisters);i++) {*(pholdingRegisters_sub+i)=i+1;} for(i=0;i<sizeof(public_struc_modbus.inputRegisters);i++) {*(pinputRegisters_sub+i)=i+1;} memset(public_struc_modbus.rdata,0,sizeof(public_struc_modbus.rdata)); } void receieve_handler(MBSLSTRU *pModbusSlave) { Uint16 i, lentemp = public_struc_modbus.recvlen & 0xff; ModbusData pTempData; Uint16 *pcoils_sub, *pinputs_sub, *pholdingRegisters_sub, *pinputRegisters_sub; // struct ScicRecvMsgQueueStruc KD_ScicRecvMsg; pcoils_sub =(Uint16 *) pModbusSlave->pcoils; pinputs_sub =(Uint16 *) pModbusSlave->pinputs; pholdingRegisters_sub =(Uint16 *) pModbusSlave->pholdingRegisters; pinputRegisters_sub =(Uint16 *) pModbusSlave->pinputRegisters; memset(pModbusSlave->sdata,0,sizeof(pModbusSlave->sdata)); pTempData.crc = ((pModbusSlave->rdata[lentemp-2])<<8)+pModbusSlave->rdata[lentemp-1]; pModbusSlave->sdata[0] = pModbusSlave->rdata[0]; if(pModbusSlave->rdata[0]==ModbusSlaveAddress) {//从地址检查 pModbusSlave->sdata[1] = pModbusSlave->rdata[1]; if(CRC16(pModbusSlave->rdata, lentemp-2) == pTempData.crc) {//校验CRC pTempData.contentIdx = (pModbusSlave->rdata[2]<<8)+pModbusSlave->rdata[3]; pTempData.numofregisters = (pModbusSlave->rdata[4]<<8)+pModbusSlave->rdata[5];//这里不表示寄存器数目,表示线圈的状态 if((pTempData.contentIdx+pTempData.numofregisters)>40) { //数值超限判定 pModbusSlave->sdata[1]|= 0x80; pModbusSlave->sdata[2]|= 0x03; i=CRC16(pModbusSlave->sdata, 3); pModbusSlave->sdata[3]= (i>>8)&0xff; pModbusSlave->sdata[4]= i