Parcourir la source

代码结构调整,增加0x05、0x06功能码解析

main
the_deepest il y a 6 jours
Parent
révision
714aff7c78
7 fichiers modifiés avec 1039 ajouts et 957 suppressions
  1. +1
    -10
      app/inc/hardware.h
  2. +1
    -5
      app/main.c
  3. +1
    -7
      app/src/hardware.c
  4. +13
    -13
      iar/settings/uCOS_Modbus.dnx
  5. +866
    -866
      iar/uCOS_Modbus.dep
  6. +138
    -53
      modbus/modbus.c
  7. +19
    -3
      modbus/modbus.h

+ 1
- 10
app/inc/hardware.h Voir le fichier

@@ -1,20 +1,11 @@
#ifndef __HARDWARE_H
#define __HARDWARE_H

/*接收数组大小*/
#define MODBUS_RX_BUF_SIZE 256
/*发送数组大小*/
#define MODBUS_TX_BUF_SIZE 256

/*modbus通信波特率*/
#define MODBUS_USART_BAUDRATE 115200
#include"modbus.h"


extern uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE];
extern uint16_t ModbusRxLen;
extern uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE];
extern uint16_t ModbusTxLen;



void ModbusHardwareInit(void);


+ 1
- 5
app/main.c Voir le fichier

@@ -4,20 +4,16 @@
/*定义信号量*/
OS_EVENT* ModbusReceived; /*接收到modbus请求报文*/


/*定义任务栈*/
static OS_STK AppTaskStartStk[APP_TASK_START_STK_SIZE];
static OS_STK AppTaskModbusParseStk[APP_TASK_MODBUS_PARSE_STK_SIZE];


/*定义任务主体函数*/
void AppTaskStart (void *p_arg);
static void AppTaskStart (void *p_arg);
void AppTaskModbusParse (void *p_arg);





int main()
{
Sys_Config(); /* stm32系统初始化配置 */


+ 1
- 7
app/src/hardware.c Voir le fichier

@@ -2,12 +2,6 @@
#include "hardware.h"


uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE]; /*接收数组*/
uint16_t ModbusRxLen = 0; /*接收数据长度*/
uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE]; /*发送数组*/
uint16_t ModbusTxLen = 0; /*发送数据长度*/


void ModbusGpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
@@ -79,7 +73,7 @@ void ModbusDmaInit(void)
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); /*设置DMA外设端地址为USART1数据寄存器地址*/
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ModbusRxBuf; /*设置DMA存储器目标地址*/
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /*传输方向为内存->外设*/
DMA_InitStructure.DMA_BufferSize = MODBUS_RX_BUF_SIZE; /*设置传输字节数*/
DMA_InitStructure.DMA_BufferSize = 256; /*设置传输字节数*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*禁止外设地址递增*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*使能内存地址自增*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /*设置外设数据宽度为1字节(8位)*/


+ 13
- 13
iar/settings/uCOS_Modbus.dnx Voir le fichier

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

+ 866
- 866
iar/uCOS_Modbus.dep
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 138
- 53
modbus/modbus.c Voir le fichier

@@ -1,28 +1,31 @@
#include "stm32f4xx.h"
#include "hardware.h"
#include "ucos_ii.h"
#include "os.h"
#include "app_cfg.h"
#include "sys_cfg.h"
#include "string.h"
#include "modbus.h"

extern OS_EVENT* ModbusReceived; /*接收到modbus请求报文*/


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

uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE]; /*接收数组*/
uint16_t ModbusRxLen = 0; /*接收数据长度*/
uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE]; /*发送数组*/
uint16_t ModbusTxLen = 0; /*发送数据长度*/


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);
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);
uint8_t ModbusReadCoils(uint16_t addres, uint16_t num);
uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data);
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);


/*USART接收空闲中断*/
@@ -91,7 +94,7 @@ void ModbusSend(uint8_t *txBuf, uint16_t len)
/*modbus协议帧解析任务*/
void AppTaskModbusParse (void *p_arg)
{
INT8U err;
OS_ERR err;
MODBUS_FRAME frame;
uint16_t rxLen;
uint8_t rxBuf[256];
@@ -106,10 +109,11 @@ void AppTaskModbusParse (void *p_arg)
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 - 2])) | ((uint16_t)rxBuf[rxLen - 1] << 8);
if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0)
{
/*crc校验错误,直接丢弃*/
ModbusErr = ERR_CRC;
continue;
}

@@ -117,6 +121,7 @@ void AppTaskModbusParse (void *p_arg)
if(frame.slaveAddres != SLAVE_ADDRES)
{
/*从机地址错误,直接丢弃*/
ModbusErr = ERR_SLAVE_ADDRES;
continue;
}

@@ -128,41 +133,38 @@ void AppTaskModbusParse (void *p_arg)
switch(frame.func)
{
case 0x01:/*读线圈*/
ModbusReadCoil(frame.opeAddres, frame.opeNum);
ModbusErr = ModbusReadCoils(frame.opeAddres, frame.opeNum);
break;

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

case 0x0F:/*写多个线圈*/
frame.wNum = rxBuf[6];
memcpy(frame.wData, &rxBuf[7], frame.wNum);

ModbusWriteCoil(frame.opeAddres, frame.opeNum, frame.wData);
ModbusErr = ModbusWriteCoils(frame.opeAddres, frame.opeNum, frame.wData);
break;

case 0x10:/*写多个寄存器*/
frame.wNum = rxBuf[6];
memcpy(frame.wData, &rxBuf[7], frame.wNum);

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

// break;

// case 0x06:/*写单个寄存器*/
case 0x05:/*写单个线圈*/
memcpy(frame.wData, &rxBuf[4], 2);
ModbusErr = ModbusWriteCoil(frame.opeAddres, frame.wData);
break;

// ModbusWriteReg(frame.opeAddres, 1, frame.wData);
// break;
case 0x06:/*写单个寄存器*/
memcpy(frame.wData, &rxBuf[4], 2);
ModbusErr = ModbusWriteReg(frame.opeAddres, frame.wData);
break;

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

ModbusErr = ModbusErrReply(frame.func, ERR_FUNC);
break;
}
/*启动发送*/
@@ -170,7 +172,7 @@ void AppTaskModbusParse (void *p_arg)
}
}

uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
uint8_t ModbusReadCoils(uint16_t addres, uint16_t num)
{
uint16_t byteIndI; /*字节索引*/
uint8_t bitIndI; /*位索引*/
@@ -186,13 +188,11 @@ uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
/*操作地址超限*/
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);
}

@@ -229,9 +229,11 @@ uint8_t ModbusReadCoil(uint16_t addres, uint16_t num)
ModbusTxBuf[2] = dataLen; /*响应帧返回数据字节数*/
AddCrc16(ModbusTxBuf, 3 + dataLen);
ModbusTxLen = 5 + dataLen;

return 0;
}

uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data)
{
uint16_t byteIndI;
uint8_t bitIndI;
@@ -244,13 +246,11 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
/*操作地址超限*/
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);
}
@@ -267,46 +267,46 @@ uint8_t ModbusWriteCoil(uint16_t addres, uint16_t num, uint8_t *data)
/*将写入值移位到要写入的位*/
writeVal = (uint8_t)1 << bitIndI;

/*对应位写入1*/
if(readVal != 0)
{
ModbusCoil[byteIndI] |= writeVal;
}
/*对应位写入0*/
else
{
ModbusCoil[byteIndI] &= (~writeVal);
}

ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = 0x0F;
/*操作地址*/
ModbusTxBuf[2] = (uint8_t)(addres >> 8);
ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
/*成功写入的数量*/
ModbusTxBuf[4] = (uint8_t)(num >> 8);
ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
AddCrc16(ModbusTxBuf, 6);
ModbusTxLen = 8;
}
ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = 0x0F;
/*操作地址*/
ModbusTxBuf[2] = (uint8_t)(addres >> 8);
ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
/*成功写入的数量*/
ModbusTxBuf[4] = (uint8_t)(num >> 8);
ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
AddCrc16(ModbusTxBuf, 6);
ModbusTxLen = 8;

return 0;
}

uint8_t ModbusReadReg(uint16_t addres, uint16_t num)
uint8_t ModbusReadRegs(uint16_t addres, uint16_t num)
{
uint8_t index;
uint8_t readValH;
uint8_t readValL;
uint8_t dataLen;

/*操作地址超限*/
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);
}

@@ -326,9 +326,11 @@ uint8_t ModbusReadReg(uint16_t addres, uint16_t num)
ModbusTxBuf[2] = dataLen;
AddCrc16(ModbusTxBuf, 3 + dataLen);
ModbusTxLen = 5 + dataLen;

return 0;
}

uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data)
{
uint8_t index;

@@ -339,17 +341,14 @@ uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
/*操作地址超限*/
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);
}


for(uint16_t i = 0; i < num; i++)
{
index = i * 2;
@@ -372,9 +371,95 @@ uint8_t ModbusWriteReg(uint16_t addres, uint16_t num, uint8_t *data)
ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
AddCrc16(ModbusTxBuf, 6);
ModbusTxLen = 8;

return 0;
}

uint8_t ModbusWriteCoil(uint16_t addres, uint8_t *data)
{
uint16_t byteIndI;
uint8_t bitIndI;

uint16_t readVal;
uint8_t writeVal;

/*操作地址超限*/
if(addres > 0x270F)
{
return ModbusErrReply(0x0F, ERR_OPE_ADDRES);
}
byteIndI = addres / 8;
bitIndI = addres % 8;
/*位掩码读取要写入的值*/
readVal = ((uint16_t)data[0] << 8) | ((uint16_t)data[1] & 0x00FF);
/*将写入值移位到要写入的位*/
writeVal = (uint8_t)1 << bitIndI;

/*置on*/
if(readVal == 0xFF00)
{
ModbusCoil[byteIndI] |= writeVal;
}
/*置off*/
else if(readVal == 0x0000)
{
ModbusCoil[byteIndI] &= (~writeVal);
}
else
{
return ModbusErrReply(0x05, ERR_DATA);
}

ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = 0x0F;
/*操作地址*/
ModbusTxBuf[2] = (uint8_t)(addres >> 8);
ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
/*成功写入*/
ModbusTxBuf[4] = data[0];
ModbusTxBuf[5] = data[1];
AddCrc16(ModbusTxBuf, 6);
ModbusTxLen = 8;

return 0;
}

uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data)
{
uint8_t writeValH;
uint8_t writeValL;
uint16_t writeVal;
/*操作地址超限*/
if(addres > 0x270F)
{
return ModbusErrReply(0x10, ERR_OPE_ADDRES);
}

writeValH = data[0];
writeValL = data[1];
/*将要写入两个8位值拼接为16位*/
writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
ModbusReg[addres] = writeVal;
ModbusTxBuf[0] = SLAVE_ADDRES;
ModbusTxBuf[1] = 0x10;
/*操作地址*/
ModbusTxBuf[2] = (uint8_t)(addres >> 8);
ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
/*成功写入*/
ModbusTxBuf[4] = writeValH;
ModbusTxBuf[5] = writeValL;
AddCrc16(ModbusTxBuf, 6);
ModbusTxLen = 8;
return 0;
}



uint8_t ModbusErrReply(uint8_t func, uint8_t err)
{
ModbusTxBuf[0] = SLAVE_ADDRES;


+ 19
- 3
modbus/modbus.h Voir le fichier

@@ -3,13 +3,28 @@

#include "ucos_ii.h"


/*接收数组大小*/
#define MODBUS_RX_BUF_SIZE 256
/*发送数组大小*/
#define MODBUS_TX_BUF_SIZE 256

/*modbus通信波特率*/
#define MODBUS_USART_BAUDRATE 115200

/*从机地址*/
#define SLAVE_ADDRES 0x01

/*错误码*/
#define ERR_FUNC 0x01
#define ERR_OPE_ADDRES 0x02
#define ERR_DATA 0x03
#define ERR_SLAVE 0x04

#define ERR_CRC 0x1F
#define ERR_SLAVE_ADDRES 0x2F

/*modbus帧结构*/
typedef struct Modbus_Frame
{
uint8_t slaveAddres; /*从机地址*/
@@ -17,14 +32,15 @@ typedef struct Modbus_Frame
uint16_t opeAddres; /*操作地址*/
uint16_t opeNum; /*操作数量*/
uint8_t wNum; /*写入字节数*/
uint8_t wData[256]; /*写入数据*/
uint8_t wData[256]; /*写入数据*/
uint16_t crc; /*CRC校验码*/
}MODBUS_FRAME;


/*接收到数据帧信号量*/
extern OS_EVENT *ModbusReceived;


void AppTaskModbusParse(void *p_arg);
void AppTaskModbusSend(void *p_arg);


#endif

Chargement…
Annuler
Enregistrer