ShipCentralControl/Anjiehui7_DTU/User/modbus_slave.c

245 lines
5.2 KiB
C
Raw Normal View History

2025-04-03 15:59:48 +08:00
#include "includes.h"
// Modbus(RS485<38>ӿڣ<D3BF><DAA3><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ÿ30<33><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// modbusͨѶ<CDA8><D1B6><EFBFBD><EFBFBD>
#pragma pack(push, 1)
// RF<52><46><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD>֡<EFBFBD><D6A1>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MODBUS_SENDM_DATA_COUNT 512
loopbuff_t Modbus_SendM;
uint8_t Modbus_SendM_Data[sizeof(ext_data_t) * (MODBUS_SENDM_DATA_COUNT + 1)] = {0};
// RF<52><46><EFBFBD>ڽ<EFBFBD><DABD>յ<EFBFBD><D5B5><EFBFBD>Ϣ֪ͨ
SemaphoreHandle_t Modbus_SendQ = NULL; // <20><>ֵ<EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-04-30 14:53:16 +08:00
typedef struct
{
uint8_t id; // ͨ<>ŵ<EFBFBD>ַ
uint8_t cmd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t index; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t all; // <20><><EFBFBD><EFBFBD>
// union
// {
// uint16_t cnt; // <20><>ȡ<EFBFBD><C8A1><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// uint16_t data; // д<><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// };
// uint16_t crc;
} modbus_request_t;
2025-04-03 15:59:48 +08:00
#pragma pack(pop)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
#define HEART_SENDBUFF_SIZE 64
uint8_t Heart_sendBuff[HEART_SENDBUFF_SIZE];
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1>Ļ<EFBFBD><C4BB><EFBFBD>
uint8_t Modbus_sendBuff[TASK_SENDBUFF_SIZE];
2025-04-30 14:53:16 +08:00
void ReadModbus_Task(uint8_t c);
2025-04-03 15:59:48 +08:00
static void RS485_SendDataByte(uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
/* Send data */
UART_Transmit(&huart4, pu8TxBuf, u32WriteBytes);
}
2025-04-30 14:53:16 +08:00
void Slave_IRQHandler(USART_Handle *huart)
{
uint8_t u8DTU = (uint8_t) huart->Instance->DR;
/* Handle received data */
ReadModbus_Task(u8DTU);
}
2025-04-03 15:59:48 +08:00
void Modbus_Open()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
LoopBuff_Create(&Modbus_SendM, sizeof(ext_data_t), MODBUS_SENDM_DATA_COUNT, 0, (uint32_t) Modbus_SendM_Data);
// <20><><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD>
Modbus_SendQ = xSemaphoreCreateBinary();
}
uint8_t pack_heart_send_data()
{
uint8_t i;
uint16_t crc;
// <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>modbus<75>ӻ<EFBFBD><D3BB><EFBFBD>Ӧ<EFBFBD>ĸ<EFBFBD>ʽ<EFBFBD><CABD>
memset(Heart_sendBuff, 0, HEART_SENDBUFF_SIZE);
i = 0;
// PSN
memmove(Heart_sendBuff + i, dcBuff.configBottle.PSN, 6);
i += 6;
Heart_sendBuff[i++] = 0x02; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3BA><EFBFBD><EFBFBD>
// <20><><EFBFBD>ݳ<EFBFBD><DDB3>ȣ<EFBFBD><C8A3><EFBFBD>Ԥ<EFBFBD><D4A4>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸ģ<DEB8>λ<EFBFBD><CEBB>ΪHeart_sendBuff[7]
Heart_sendBuff[i++] = 0;
// Ӳ<><D3B2><EFBFBD>
Heart_sendBuff[i++] = dcBuff.powerInfo.hardVer.minor;
// <20><><EFBFBD><EFBFBD><EFBFBD>
Heart_sendBuff[i++] = dcBuff.powerInfo.softVer.minor;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Heart_sendBuff[i++] = dcBuff.powerInfo.softDate.year;
Heart_sendBuff[i++] = dcBuff.powerInfo.softDate.month;
Heart_sendBuff[i++] = dcBuff.powerInfo.softDate.day;
// <20><>Ƶ<EFBFBD>Լ<EFBFBD>״̬
Heart_sendBuff[i++] = RF_initStatus;
// <20><><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>״̬
Heart_sendBuff[i++] = Ethernet_initStatus;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
Heart_sendBuff[i++] = Ethernet_IsConnected();
// GPRS<52><53><EFBFBD><EFBFBD>״̬
Heart_sendBuff[i++] = dcBuff.dtuData.networked;
// GPRS<52>ź<EFBFBD>ǿ<EFBFBD><C7BF>
Heart_sendBuff[i++] = dcBuff.dtuData.rssi;
// GPRS<52><53><EFBFBD><EFBFBD>״̬
Heart_sendBuff[i++] = dcBuff.dtuData.connected;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
i += 41;
// <20>޸<EFBFBD><DEB8><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
Heart_sendBuff[7] = i - 8;
// У<><D0A3><EFBFBD><EFBFBD>
crc = MODBUS_RTU_CRC16((uint8_t *) Heart_sendBuff, i);
*(uint16_t *)(Heart_sendBuff + i) = htons(crc);
i += 2;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Heart_sendBuff[i++] = 0x0d;
Heart_sendBuff[i++] = 0x0a;
return i;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Modbus_Task(void *p_arg)
{
uint8_t i;
uint32_t heartTick = 0;
ext_data_t Gprs;
while(TRUE)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>Ͷ<EFBFBD><CDB6>еļ<D0B5>¼
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>õ<EFBFBD>ִ<EFBFBD>У<EFBFBD>
xSemaphoreTake(Modbus_SendQ, 1000);
if(IsTickOut(heartTick))
{
heartTick = GetDelayTick(30000); // 30<33><30><EFBFBD>Ժ<EFBFBD><D4BA>ٷ<EFBFBD>
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
// i = pack_heart_send_data();
// RS485_SendDataByte(Heart_sendBuff, i);
}
if(LoopBuff_GetCount(&Modbus_SendM))
{
// ȡ<><C8A1><EFBFBD><EFBFBD>
memmove(&Gprs, LoopBuff_GetDataPtr(&Modbus_SendM, Modbus_SendM.info.rdPtr), sizeof(ext_data_t));
LoopBuff_RemoveItems(&Modbus_SendM, 1);
i = pack_modbus_tran_data(&Gprs);
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
RS485_SendDataByte(Modbus_sendBuff, i);
}
}
}
2025-04-30 14:53:16 +08:00
// <20><><EFBFBD><EFBFBD>modbus rtu<74><75><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD>CRC<52>İ<EFBFBD><C4B0><EFBFBD>
void MODBUS_RTU_CMD(modbus_request_t *req)
{
2025-05-07 10:50:40 +08:00
static uint8_t BUFF[100]; // <20><>Ӧ<EFBFBD><D3A6>
uint8_t err = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t len = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
2025-04-30 14:53:16 +08:00
2025-05-07 10:50:40 +08:00
uint16_t id; // ͨ<>ŵ<EFBFBD>ַ
uint16_t reg; // <20><><EFBFBD>ݵ<EFBFBD>ַ
uint16_t cnt; // <20><><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>
uint16_t crc;
2025-04-30 14:53:16 +08:00
2025-05-07 10:50:40 +08:00
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ŵ<EFBFBD>ַ
if(req->id != dcBuff.configBottle.addr && req->id != 0)
return;
// <20><><EFBFBD>շ<EFBFBD><D5B7><EFBFBD>֡
memset(BUFF, 0, sizeof(BUFF));
2025-04-30 14:53:16 +08:00
2025-05-07 10:50:40 +08:00
BUFF[len++] = dcBuff.configBottle.addr; // <20>ӻ<EFBFBD><D3BB><EFBFBD>ַ
BUFF[len++] = req->cmd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-04-30 14:53:16 +08:00
// reg = ntohs(req->reg); // <20><><EFBFBD>ݼĴ<DDBC><C4B4><EFBFBD>
// if(req->cmd == 0x03 || req->cmd == 0x06)
// reg += 40001;
// else if(req->cmd == 0x04)
// reg += 30001;
// else
// err = MODBUS_ERR_ILF; // <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
2025-05-07 10:50:40 +08:00
if(err == 0)
{
if(req->cmd == 0x03) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
2025-04-30 14:53:16 +08:00
// cnt = ntohs(req->cnt); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// if(reg != MODBUS_ADR_REG || cnt != 1)
// err = MODBUS_ERR_NAK; // <20><><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>ִ<EFBFBD><D6B4>
// else
// {
// // <20><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ͨѶ<CDA8><D1B6>ַˢ<D6B7>»<EFBFBD><C2BB><EFBFBD>
// id = htons(dcBuff.configBottle.addr);
// BUFF[len++] = 2; // <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
// memmove(BUFF + len, (uint8_t *) &id, 2);
// len += 2;
// }
2025-05-07 10:50:40 +08:00
}
}
2025-04-30 14:53:16 +08:00
//
// if(err != 0)
// {
// BUFF[1] |= 0x80; // <20><><EFBFBD><EFBFBD>ָʾ
// BUFF[len++] = err; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// }
2025-05-07 10:50:40 +08:00
// <20><><EFBFBD><EFBFBD>CRC
crc = MODBUS_RTU_CRC16(BUFF, len);
crc = htons(crc);
2025-04-30 14:53:16 +08:00
2025-05-07 10:50:40 +08:00
memmove(BUFF + len, &crc, 2);
len += 2;
2025-04-30 14:53:16 +08:00
2025-05-07 10:50:40 +08:00
if(req->id != 0)
{
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
RS485_SendDataByte(BUFF, len);
}
2025-04-30 14:53:16 +08:00
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ReadModbus_Task(uint8_t c)
{
static uint8_t BUFF[sizeof(modbus_request_t)] = {0};
static uint8_t len = 0;
// ȡ<><C8A1><EFBFBD><EFBFBD>
BUFF[len++] = c;
// <20><>֤<EFBFBD><D6A4><EFBFBD>Ⱥ<EFBFBD>CRCֵ
if(len == sizeof(modbus_request_t))
{
if(MODBUS_RTU_CRC16(BUFF, sizeof(modbus_request_t)) == 0)
{
MODBUS_RTU_CMD((modbus_request_t *) BUFF);
len = 0;
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>
memmove(BUFF, BUFF + 1, --len);
}
}
}