Kaynağa Gözat

实现错误处理

main
the_deepest 6 gün önce
ebeveyn
işleme
a9d2034129
5 değiştirilmiş dosya ile 1132 ekleme ve 991 silme
  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
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


+ 12
- 12
iar/settings/uCOS_Modbus.dnx Dosyayı Görüntüle

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

+ 893
- 894
iar/uCOS_Modbus.dep
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


+ 102
- 51
modbus/modbus.c Dosyayı Görüntüle

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




/*0x270F+1=K10000*/
/*0x270F + 1 = K10000 */
uint8_t ModbusCoil[1250]; /*10000/8=1250*/
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);
int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length);
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 ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data);


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

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

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

memcpy(rxBuf, ModbusRxBuf, rxLen);

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


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


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

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

break;

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

break;

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

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

break;

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

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

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);
}
}

uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
{
uint16_t byteIndI;
uint8_t bitIndI;
uint16_t byteIndI; /*字节索引*/
uint8_t bitIndI; /*位索引*/
uint16_t byteIndO;
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;

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

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

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;
bitIndI = (addres + i) % 8;

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

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);
ModbusTxLen = 5 + dataLen;
}
@@ -224,14 +241,19 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
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(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++)
{
byteIndI = (addres + i) / 8;
@@ -240,10 +262,11 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
byteIndO = i / 8;
bitIndO = i % 8;

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


if(readVal != 0)
{
ModbusCoil[byteIndI] |= writeVal;
@@ -274,17 +297,24 @@ uint8_t ModbusReadReg(uint16_t addres, uint16_t num)
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;
for(uint16_t i = 0; i < num; i++)
{
index = 3 + (i * 2);
/*将16位寄存器值拆分为两个8位*/
readValH = (uint8_t)(ModbusReg[addres + i] >> 8);
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;
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];
writeValL = data[index + 1];
/*将要写入两个8位值拼接为16位*/
writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
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)
{
uint8_t *dataT = data;
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校验*/


+ 5
- 0
modbus/modbus.h Dosyayı Görüntüle

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

#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
{
uint8_t slaveAddres; /*从机地址*/


Yükleniyor…
İptal
Kaydet