|
|
|
@@ -8,10 +8,11 @@ |
|
|
|
uint8_t ModbusErr; |
|
|
|
/*0x270F + 1 = K10000 */ |
|
|
|
uint8_t ModbusCoil[1250]; /*10000/8=1250*/ |
|
|
|
uint16_t ModbusReg[10001]; |
|
|
|
uint16_t ModbusReg[10000]; |
|
|
|
|
|
|
|
/*附加功能:页寄存器*/ |
|
|
|
uint16_t ModbusExtPage[1] = {0}; /*设置地址为0xFFFE*/ |
|
|
|
uint16_t ModbusExtReg[1]; /*地址映射为0x10000*/ |
|
|
|
/*附加功能:读取所有单数个寄存器*/ |
|
|
|
uint16_t ModbusExtOdd[1] = {0}; /*设置地址为0xFFFF*/ |
|
|
|
|
|
|
|
@@ -31,6 +32,7 @@ uint8_t ModbusReadRegs(uint16_t addres, uint16_t num); |
|
|
|
uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data); |
|
|
|
uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data); |
|
|
|
uint8_t ModbusWriteCoil(uint16_t addres, uint8_t *data); |
|
|
|
uint8_t ModbusExtReadOdd(uint16_t num); |
|
|
|
|
|
|
|
|
|
|
|
/*USART接收空闲中断*/ |
|
|
|
@@ -78,6 +80,12 @@ void USART1_IRQHandler(void) |
|
|
|
/*modbus响应帧发送*/ |
|
|
|
void ModbusSend(uint8_t *txBuf, uint16_t len) |
|
|
|
{ |
|
|
|
if(DMA_GetCmdStatus(DMA2_Stream7) == ENABLE) |
|
|
|
{ |
|
|
|
/*等待DMA发送完成*/ |
|
|
|
while(DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET); |
|
|
|
} |
|
|
|
|
|
|
|
/*先关闭DMA发送通道*/ |
|
|
|
DMA_Cmd(DMA2_Stream7, DISABLE); |
|
|
|
|
|
|
|
@@ -90,6 +98,9 @@ void ModbusSend(uint8_t *txBuf, uint16_t len) |
|
|
|
/*配置发送地址和长度*/ |
|
|
|
DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)txBuf, DMA_Memory_0); |
|
|
|
DMA_SetCurrDataCounter(DMA2_Stream7, len); |
|
|
|
|
|
|
|
/*等待串口发送完成*/ |
|
|
|
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); |
|
|
|
|
|
|
|
/*启动 DMA 发送*/ |
|
|
|
DMA_Cmd(DMA2_Stream7, ENABLE); |
|
|
|
@@ -104,8 +115,6 @@ void AppTaskModbusParse (void *p_arg) |
|
|
|
uint16_t rxLen; |
|
|
|
uint8_t rxBuf[256]; |
|
|
|
|
|
|
|
ModbusReg[10000] = 123; |
|
|
|
|
|
|
|
while(1) |
|
|
|
{ |
|
|
|
/*无限期等待接收到数据帧信号量*/ |
|
|
|
@@ -174,8 +183,16 @@ void AppTaskModbusParse (void *p_arg) |
|
|
|
ModbusErr = ModbusErrReply(frame.func, ERR_FUNC); |
|
|
|
break; |
|
|
|
} |
|
|
|
/*启动发送*/ |
|
|
|
ModbusSend(ModbusTxBuf, ModbusTxLen); |
|
|
|
/*实现附加功能时不在这里启动发送*/ |
|
|
|
if(frame.func == 0x03 && frame.opeAddres == 0XFFFF) |
|
|
|
{ |
|
|
|
; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/*启动发送*/ |
|
|
|
ModbusSend(ModbusTxBuf, ModbusTxLen); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -192,6 +209,10 @@ uint8_t ModbusReadCoils(uint16_t addres, uint16_t num) |
|
|
|
uint8_t readVal; /*读取到的形式值*/ |
|
|
|
uint8_t writeVal; /*写入的形式值*/ |
|
|
|
|
|
|
|
if(ModbusRxLen < 8) |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x01, ERR_DATA); |
|
|
|
} |
|
|
|
/*操作地址超限*/ |
|
|
|
if(addres > 0x270F || (addres + (num - 1)) > 0x270F) |
|
|
|
{ |
|
|
|
@@ -250,6 +271,10 @@ uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data) |
|
|
|
uint8_t readVal; |
|
|
|
uint8_t writeVal; |
|
|
|
|
|
|
|
if(ModbusRxLen < 10) |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x0F, ERR_DATA); |
|
|
|
} |
|
|
|
/*操作地址超限*/ |
|
|
|
if(addres > 0x270F || (addres + (num - 1)) > 0x270F) |
|
|
|
{ |
|
|
|
@@ -306,10 +331,21 @@ uint8_t ModbusReadRegs(uint16_t addres, uint16_t num) |
|
|
|
uint8_t readValL; |
|
|
|
uint8_t dataLen; |
|
|
|
|
|
|
|
if(ModbusRxLen < 8) |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x13, ERR_DATA); |
|
|
|
} |
|
|
|
/*操作地址超限*/ |
|
|
|
if(addres > 0x270F || (addres + (num - 1)) > 0x270F) |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x03, ERR_OPE_ADDRES); |
|
|
|
if(addres == 0xFFFF && num == 1) |
|
|
|
{ |
|
|
|
; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x03, ERR_OPE_ADDRES); |
|
|
|
} |
|
|
|
} |
|
|
|
/*操作数量超限*/ |
|
|
|
if(num == 0 || num > 125) |
|
|
|
@@ -318,15 +354,21 @@ uint8_t ModbusReadRegs(uint16_t addres, uint16_t num) |
|
|
|
} |
|
|
|
|
|
|
|
dataLen = num * 2; |
|
|
|
/*附加功能:读取0x10000寄存器*/ |
|
|
|
if(ModbusExtPage[0] == 1 && addres == 0x0000) |
|
|
|
{ |
|
|
|
/*将16位寄存器值拆分为两个8位*/ |
|
|
|
readValH = (uint8_t)(ModbusReg[10000] >> 8); |
|
|
|
readValL = (uint8_t)(ModbusReg[10000] & 0x00FF); |
|
|
|
readValH = (uint8_t)(ModbusExtReg[0] >> 8); |
|
|
|
readValL = (uint8_t)(ModbusExtReg[0] & 0x00FF); |
|
|
|
|
|
|
|
ModbusTxBuf[3] = readValH; |
|
|
|
ModbusTxBuf[4] = readValL; |
|
|
|
} |
|
|
|
/*附加功能:读取大量奇数寄存器*/ |
|
|
|
else if(addres == 0xFFFF && num == 1) |
|
|
|
{ |
|
|
|
return ModbusExtReadOdd(ModbusExtOdd[0]); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for(uint16_t i = 0; i < num; i++) |
|
|
|
@@ -357,11 +399,15 @@ uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data) |
|
|
|
uint8_t writeValH; |
|
|
|
uint8_t writeValL; |
|
|
|
uint16_t writeVal; |
|
|
|
|
|
|
|
|
|
|
|
if(ModbusRxLen < 11) |
|
|
|
{ |
|
|
|
return ModbusErrReply(0x10, ERR_DATA); |
|
|
|
} |
|
|
|
/*操作地址超限*/ |
|
|
|
if(addres > 0x270F || (addres + (num - 1)) > 0x270F) |
|
|
|
{ |
|
|
|
if(addres == 0xFFFE && num == 1) |
|
|
|
if((addres == 0xFFFE || addres == 0xFFFF) && num == 1) |
|
|
|
{ |
|
|
|
; |
|
|
|
} |
|
|
|
@@ -376,6 +422,7 @@ uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data) |
|
|
|
return ModbusErrReply(0x10, ERR_DATA); |
|
|
|
} |
|
|
|
|
|
|
|
/*附加功能:读取0x10000寄存器*/ |
|
|
|
if(addres == 0xFFFE && num == 1) |
|
|
|
{ |
|
|
|
writeValH = data[0]; |
|
|
|
@@ -385,6 +432,17 @@ uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data) |
|
|
|
writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); |
|
|
|
ModbusExtPage[0] = writeVal; |
|
|
|
} |
|
|
|
/*附加功能:读取大量奇数寄存器*/ |
|
|
|
else if(addres == 0xFFFF && num == 1) |
|
|
|
{ |
|
|
|
writeValH = data[0]; |
|
|
|
writeValL = data[1]; |
|
|
|
|
|
|
|
/*将要写入两个8位值拼接为16位*/ |
|
|
|
writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); |
|
|
|
ModbusExtOdd[0] = writeVal; |
|
|
|
} |
|
|
|
/*正常功能*/ |
|
|
|
else |
|
|
|
{ |
|
|
|
for(uint16_t i = 0; i < num; i++) |
|
|
|
@@ -497,6 +555,67 @@ uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t ModbusExtReadOdd(uint16_t num) |
|
|
|
{ |
|
|
|
uint8_t i = 0; |
|
|
|
uint8_t numJ = (num + 124) / 125; |
|
|
|
uint8_t numI = num % 125; |
|
|
|
|
|
|
|
uint8_t index; |
|
|
|
uint16_t indexR; |
|
|
|
uint8_t readValH; |
|
|
|
uint8_t readValL; |
|
|
|
uint8_t dataLen; |
|
|
|
|
|
|
|
for(uint16_t j = 0; j < numJ; j++) |
|
|
|
{ |
|
|
|
if(j == numJ - 1) |
|
|
|
{ |
|
|
|
for(i = 0; i < numI; i++) |
|
|
|
{ |
|
|
|
index = 3 + (i * 2); |
|
|
|
indexR = j * 250 + 2 * i + 1; |
|
|
|
/*将16位寄存器值拆分为两个8位*/ |
|
|
|
readValH = (uint8_t)(ModbusReg[indexR] >> 8); |
|
|
|
readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF); |
|
|
|
|
|
|
|
ModbusTxBuf[index] = readValH; |
|
|
|
ModbusTxBuf[index + 1] = readValL; |
|
|
|
} |
|
|
|
dataLen = 2 * numI; |
|
|
|
|
|
|
|
ModbusTxBuf[0] = SLAVE_ADDRES; |
|
|
|
ModbusTxBuf[1] = 0x03; |
|
|
|
ModbusTxBuf[2] = dataLen; |
|
|
|
AddCrc16(ModbusTxBuf, 3 + dataLen); |
|
|
|
ModbusTxLen = 5 + dataLen; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for(i = 0; i < 125; i++) |
|
|
|
{ |
|
|
|
index = 3 + (i * 2); |
|
|
|
indexR = j * 250 + 2 * i + 1; |
|
|
|
/*将16位寄存器值拆分为两个8位*/ |
|
|
|
readValH = (uint8_t)(ModbusReg[indexR] >> 8); |
|
|
|
readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF); |
|
|
|
|
|
|
|
ModbusTxBuf[index] = readValH; |
|
|
|
ModbusTxBuf[index + 1] = readValL; |
|
|
|
} |
|
|
|
dataLen = 250; |
|
|
|
|
|
|
|
ModbusTxBuf[0] = SLAVE_ADDRES; |
|
|
|
ModbusTxBuf[1] = 0x03; |
|
|
|
ModbusTxBuf[2] = dataLen; |
|
|
|
AddCrc16(ModbusTxBuf, 3 + dataLen); |
|
|
|
ModbusTxLen = 5 + dataLen; |
|
|
|
} |
|
|
|
OSTimeDlyHMSM(0, 0, 0, 10); |
|
|
|
ModbusSend(ModbusTxBuf, ModbusTxLen); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t ModbusErrReply(uint8_t func, uint8_t err) |
|
|
|
|