瀏覽代碼

实现错误处理

main
the_deepest 1 周之前
父節點
當前提交
a9d2034129
共有 5 個文件被更改,包括 1132 次插入991 次删除
  1. +120
    -34
      iar/settings/uCOS_Modbus.dbgdt
  2. +12
    -12
      iar/settings/uCOS_Modbus.dnx
  3. +893
    -894
      iar/uCOS_Modbus.dep
  4. +102
    -51
      modbus/modbus.c
  5. +5
    -0
      modbus/modbus.h

+ 120
- 34
iar/settings/uCOS_Modbus.dbgdt
文件差異過大導致無法顯示
查看文件


+ 12
- 12
iar/settings/uCOS_Modbus.dnx 查看文件

@@ -18,10 +18,10 @@
<StLinkDriver> <StLinkDriver>
<stlinkserialNo>30303031</stlinkserialNo> <stlinkserialNo>30303031</stlinkserialNo>
<stlinkfoundProbes /> <stlinkfoundProbes />
<CStepIntDis>_ 0</CStepIntDis>
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
<stlinkResetStyle>0</stlinkResetStyle> <stlinkResetStyle>0</stlinkResetStyle>
<stlinkResetStrategy>0</stlinkResetStrategy> <stlinkResetStrategy>0</stlinkResetStrategy>
<CStepIntDis>_ 0</CStepIntDis>
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
</StLinkDriver> </StLinkDriver>
<DebugChecksum> <DebugChecksum>
<Checksum>3881723374</Checksum> <Checksum>3881723374</Checksum>
@@ -120,12 +120,6 @@
<ShowTimeSum>1</ShowTimeSum> <ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder> <SumSortOrder>0</SumSortOrder>
</EventLog> </EventLog>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<TermIOLog> <TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled> <LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile> <LogFile>_ ""</LogFile>
@@ -135,10 +129,6 @@
<LogFile>_ ""</LogFile> <LogFile>_ ""</LogFile>
<Category>_ 0</Category> <Category>_ 0</Category>
</LogFile> </LogFile>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<DriverProfiling> <DriverProfiling>
<Enabled>0</Enabled> <Enabled>0</Enabled>
<Mode>3</Mode> <Mode>3</Mode>
@@ -152,4 +142,14 @@
<CallStackStripe> <CallStackStripe>
<ShowTiming>1</ShowTiming> <ShowTiming>1</ShowTiming>
</CallStackStripe> </CallStackStripe>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
</settings> </settings>

+ 893
- 894
iar/uCOS_Modbus.dep
文件差異過大導致無法顯示
查看文件


+ 102
- 51
modbus/modbus.c 查看文件

@@ -10,13 +10,13 @@
extern OS_EVENT* ModbusReceived; /*接收到modbus请求报文*/ extern OS_EVENT* ModbusReceived; /*接收到modbus请求报文*/






/*0x270F+1=K10000*/
/*0x270F + 1 = K10000 */
uint8_t ModbusCoil[1250]; /*10000/8=1250*/ uint8_t ModbusCoil[1250]; /*10000/8=1250*/
uint16_t ModbusReg[10000]; uint16_t ModbusReg[10000];
uint8_t ModbusErr;



uint8_t ModbusErrReply(uint8_t func, uint8_t err);
uint16_t Crc16(const uint8_t *data, uint16_t length);
void AddCrc16(uint8_t *data, uint16_t length); void AddCrc16(uint8_t *data, uint16_t length);
int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length); int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length);
uint8_t ModbusReadCoil(uint16_t addres, uint16_t num); uint8_t ModbusReadCoil(uint16_t addres, uint16_t num);
@@ -24,6 +24,7 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data);
uint8_t ModbusReadReg(uint16_t addres, uint16_t num); uint8_t ModbusReadReg(uint16_t addres, uint16_t num);
uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data); uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data);



/*USART接收空闲中断*/ /*USART接收空闲中断*/
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
@@ -49,6 +50,7 @@ void USART1_IRQHandler(void)
rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2); rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2);
ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain; ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain;


/*释放接收到数据帧信号量,唤醒帧解析任务*/
if(ModbusRxLen != 0) if(ModbusRxLen != 0)
{ {
OSSemPost(ModbusReceived); OSSemPost(ModbusReceived);
@@ -96,42 +98,41 @@ void AppTaskModbusParse (void *p_arg)


while(1) while(1)
{ {
/*无限期等待接收到数据帧信号量*/
OSSemPend(ModbusReceived, 0, &err); OSSemPend(ModbusReceived, 0, &err);
/*数据接收,防止下一帧覆盖*/
rxLen = ModbusRxLen; rxLen = ModbusRxLen;

memcpy(rxBuf, ModbusRxBuf, rxLen); memcpy(rxBuf, ModbusRxBuf, rxLen);


/*拼接crc校验码(高前低后),接收到的数据帧crc校验码是低前高后*/
frame.crc = ((uint16_t)(rxBuf[rxLen - 1])) | ((uint16_t)rxBuf[rxLen - 2] << 8); frame.crc = ((uint16_t)(rxBuf[rxLen - 1])) | ((uint16_t)rxBuf[rxLen - 2] << 8);
if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0) if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0)
{ {
/****************************crc错误处理******************************/
/*crc校验错误,直接丢弃*/
continue;
} }



frame.slaveAddres = rxBuf[0]; frame.slaveAddres = rxBuf[0];
if(frame.slaveAddres != SLAVE_ADDRES) if(frame.slaveAddres != SLAVE_ADDRES)
{ {
/*****************************从机地址错误处理************************/
/*从机地址错误,直接丢弃*/
continue;
} }



frame.func = rxBuf[1]; frame.func = rxBuf[1];
frame.opeAddres = ((uint16_t)rxBuf[2] << 8) | ((uint16_t)rxBuf[3]); frame.opeAddres = ((uint16_t)rxBuf[2] << 8) | ((uint16_t)rxBuf[3]);
frame.opeNum = ((uint16_t)rxBuf[4] << 8) | ((uint16_t)rxBuf[5]); frame.opeNum = ((uint16_t)rxBuf[4] << 8) | ((uint16_t)rxBuf[5]);

/*功能码分类*/
switch(frame.func) switch(frame.func)
{ {
case 0x01:/*读线圈*/ case 0x01:/*读线圈*/
ModbusReadCoil(frame.opeAddres, frame.opeNum); ModbusReadCoil(frame.opeAddres, frame.opeNum);

break; break;


case 0x03:/*读寄存器*/ case 0x03:/*读寄存器*/
ModbusReadReg(frame.opeAddres, frame.opeNum); ModbusReadReg(frame.opeAddres, frame.opeNum);

break; break;


case 0x0F:/*写多个线圈*/ case 0x0F:/*写多个线圈*/
@@ -139,8 +140,6 @@ void AppTaskModbusParse (void *p_arg)
memcpy(frame.wData, &rxBuf[7], frame.wNum); memcpy(frame.wData, &rxBuf[7], frame.wNum);


ModbusWriteCoil(frame.opeAddres, frame.opeNum, frame.wData); ModbusWriteCoil(frame.opeAddres, frame.opeNum, frame.wData);

break; break;


case 0x10:/*写多个寄存器*/ case 0x10:/*写多个寄存器*/
@@ -148,45 +147,60 @@ void AppTaskModbusParse (void *p_arg)
memcpy(frame.wData, &rxBuf[7], frame.wNum); memcpy(frame.wData, &rxBuf[7], frame.wNum);


ModbusWriteReg(frame.opeAddres, frame.opeNum, frame.wData); ModbusWriteReg(frame.opeAddres, frame.opeNum, frame.wData);

break; break;
// case 0x05:/*写单个线圈*/
// ModbusWriteCoil(frame.opeAddres, 1, frame.wData);


default:/*功能码错误*/
// break;


// case 0x06:/*写单个寄存器*/


// ModbusWriteReg(frame.opeAddres, 1, frame.wData);
// break;


break;
default:/*功能码错误*/
ModbusErr = ERR_FUNC;
ModbusErrReply(frame.func, ERR_FUNC);


break;
} }
/*启动发送*/
ModbusSend(ModbusTxBuf, ModbusTxLen); ModbusSend(ModbusTxBuf, ModbusTxLen);
} }
} }


uint8_t ModbusReadCoil(uint16_t addres, uint16_t num) uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
{ {
uint16_t byteIndI;
uint8_t bitIndI;
uint16_t byteIndI; /*字节索引*/
uint8_t bitIndI; /*位索引*/
uint16_t byteIndO; uint16_t byteIndO;
uint8_t bitIndO; uint8_t bitIndO;


uint8_t dataLen;

uint8_t index;
uint8_t readVal;
uint8_t writeVal;
uint8_t dataLen; /*响应帧返回字节数*/


uint8_t index; /*发送数组索引*/
uint8_t readVal; /*读取到的形式值*/
uint8_t writeVal; /*写入的形式值*/


if(addres > 0x270F || (addres + num) > 0x270F)
/*操作地址超限*/
if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
{ {
/********************地址超限处理*****************/
ModbusErr = ERR_OPE_ADDRES;
return ModbusErrReply(0x01, ERR_OPE_ADDRES);
}
/*操作数量超限*/
if(num == 0 || num > 2000)
{
ModbusErr = ERR_DATA;
return ModbusErrReply(0x01, ERR_DATA);
} }



/*不能num/8+1,当为8的整数时会多一个*/
dataLen = (num + 7) / 8; dataLen = (num + 7) / 8;


memset(&ModbusTxBuf[3], 0, 253);/*清零发送数组*/

/*清零发送数组*/
memset(&ModbusTxBuf[3], 0, 253);


for(uint16_t i = 0; i < num; i++) for(uint16_t i = 0; i < num; i++)
{ {
@@ -196,20 +210,23 @@ uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
byteIndI = (addres + i) / 8; byteIndI = (addres + i) / 8;
bitIndI = (addres + i) % 8; bitIndI = (addres + i) % 8;


/*位掩码读取线圈值*/
readVal = ModbusCoil[byteIndI] & ((uint8_t)1 << bitIndI); readVal = ModbusCoil[byteIndI] & ((uint8_t)1 << bitIndI);
/*读取到的值为0则不进行操作*/
if(readVal != 0) if(readVal != 0)
{ {
index = 3 + byteIndO; index = 3 + byteIndO;
/*将读取到的值移位到要写入的位*/
writeVal = (uint8_t)1u << bitIndO; writeVal = (uint8_t)1u << bitIndO;


ModbusTxBuf[index] |= writeVal; ModbusTxBuf[index] |= writeVal;
} }
} }


ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = 0x01;
ModbusTxBuf[2] = dataLen;/*响应帧返回数据字节数*/
ModbusTxBuf[0] = SLAVE_ADDRES; /*从机地址*/
ModbusTxBuf[1] = 0x01; /*功能码*/
ModbusTxBuf[2] = dataLen; /*响应帧返回数据字节数*/
AddCrc16(ModbusTxBuf, 3 + dataLen); AddCrc16(ModbusTxBuf, 3 + dataLen);
ModbusTxLen = 5 + dataLen; ModbusTxLen = 5 + dataLen;
} }
@@ -224,14 +241,19 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
uint8_t readVal; uint8_t readVal;
uint8_t writeVal; uint8_t writeVal;



if(addres > 0x270F || (addres + num) > 0x270F)
/*操作地址超限*/
if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
{
ModbusErr = ERR_OPE_ADDRES;
return ModbusErrReply(0x0F, ERR_OPE_ADDRES);
}
/*操作数量超限*/
if(num == 0 || num > 1968)
{ {
/********************地址超限处理*****************/
ModbusErr = ERR_DATA;
return ModbusErrReply(0x0F, ERR_DATA);
} }


for(uint16_t i = 0; i < num; i++) for(uint16_t i = 0; i < num; i++)
{ {
byteIndI = (addres + i) / 8; byteIndI = (addres + i) / 8;
@@ -240,10 +262,11 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
byteIndO = i / 8; byteIndO = i / 8;
bitIndO = i % 8; bitIndO = i % 8;


/*位掩码读取要写入的值*/
readVal = data[byteIndO] | ((uint8_t)1 << bitIndO); readVal = data[byteIndO] | ((uint8_t)1 << bitIndO);
/*将写入值移位到要写入的位*/
writeVal = (uint8_t)1 << bitIndI; writeVal = (uint8_t)1 << bitIndI;



if(readVal != 0) if(readVal != 0)
{ {
ModbusCoil[byteIndI] |= writeVal; ModbusCoil[byteIndI] |= writeVal;
@@ -274,17 +297,24 @@ uint8_t ModbusReadReg(uint16_t addres, uint16_t num)
uint8_t dataLen; uint8_t dataLen;


if(addres > 0x270F || (addres + num) > 0x270F)
/*操作地址超限*/
if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
{ {
/********************地址错误处理*****************/
ModbusErr = ERR_OPE_ADDRES;
return ModbusErrReply(0x03, ERR_OPE_ADDRES);
}
/*操作数量超限*/
if(num == 0 || num > 125)
{
ModbusErr = ERR_DATA;
return ModbusErrReply(0x03, ERR_DATA);
} }



dataLen = num * 2; dataLen = num * 2;
for(uint16_t i = 0; i < num; i++) for(uint16_t i = 0; i < num; i++)
{ {
index = 3 + (i * 2); index = 3 + (i * 2);
/*将16位寄存器值拆分为两个8位*/
readValH = (uint8_t)(ModbusReg[addres + i] >> 8); readValH = (uint8_t)(ModbusReg[addres + i] >> 8);
readValL = (uint8_t)(ModbusReg[addres + i] & 0x00FF); readValL = (uint8_t)(ModbusReg[addres + i] & 0x00FF);


@@ -306,10 +336,17 @@ uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
uint8_t writeValL; uint8_t writeValL;
uint16_t writeVal; uint16_t writeVal;
if(addres > 0x270F || (addres + num) > 0x270F)
/*操作地址超限*/
if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
{ {
/********************地址错误处理*****************/
ModbusErr = ERR_OPE_ADDRES;
return ModbusErrReply(0x10, ERR_OPE_ADDRES);
}
/*操作数量超限*/
if(num == 0 || num > 123)
{
ModbusErr = ERR_DATA;
return ModbusErrReply(0x10, ERR_DATA);
} }




@@ -320,6 +357,7 @@ uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
writeValH = data[index]; writeValH = data[index];
writeValL = data[index + 1]; writeValL = data[index + 1];
/*将要写入两个8位值拼接为16位*/
writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF); writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
ModbusReg[addres + i] = writeVal; ModbusReg[addres + i] = writeVal;
} }
@@ -337,15 +375,28 @@ uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
} }


uint16_t Crc16(const uint8_t *data, uint16_t length);
uint8_t ModbusErrReply(uint8_t func, uint8_t err)
{
ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = func;
ModbusTxBuf[2] = err;
AddCrc16(ModbusTxBuf, 3);
ModbusTxLen = 5;

return err;
}





void AddCrc16(uint8_t *data, uint16_t length) void AddCrc16(uint8_t *data, uint16_t length)
{ {
uint8_t *dataT = data;
uint16_t crc16 = Crc16(data, length); uint16_t crc16 = Crc16(data, length);


/*低前高后*/ /*低前高后*/
data[length] = (uint8_t)(crc16 & 0x00FF);
data[length + 1] = (uint8_t)(crc16 >> 8);
dataT[length] = (uint8_t)(crc16 & 0x00FF);
dataT[length + 1] = (uint8_t)(crc16 >> 8);
} }


/*crc16校验*/ /*crc16校验*/


+ 5
- 0
modbus/modbus.h 查看文件

@@ -5,6 +5,11 @@


#define SLAVE_ADDRES 0x01 #define SLAVE_ADDRES 0x01


#define ERR_FUNC 0x01
#define ERR_OPE_ADDRES 0x02
#define ERR_DATA 0x03
#define ERR_SLAVE 0x04

typedef struct Modbus_Frame typedef struct Modbus_Frame
{ {
uint8_t slaveAddres; /*从机地址*/ uint8_t slaveAddres; /*从机地址*/


Loading…
取消
儲存