MS-DTU/MS-DTU-V1/User/modbus_slave.c

283 lines
7.9 KiB
C
Raw Permalink Normal View History

2025-04-03 14:18:58 +08:00
#include "includes.h"
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Modbus_Task(uint8_t c);
// modbusͨѶ<CDA8><D1B6><EFBFBD><EFBFBD>
#pragma pack(push, 1)
typedef struct
{
uint8_t id; // ͨ<>ŵ<EFBFBD>ַ
uint8_t cmd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint16_t reg; // <20>Ĵ<EFBFBD><C4B4><EFBFBD><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;
typedef struct
{
uint8_t id; // ͨ<>ŵ<EFBFBD>ַ
uint8_t cmd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint16_t reg; // <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ
// union
// {
// uint16_t data[13];
//
// };
uint16_t staDiff; //30001
uint16_t diff; //<2F><>ѹֵ
uint16_t volumePct; //30003 <20>ݻ<EFBFBD><DDBB>ٷֱ<D9B7>
uint16_t volumeH; // <20>ݻ<EFBFBD>H
uint16_t volumeL; // <20>ݻ<EFBFBD>L
uint16_t weightH; // <20><><EFBFBD><EFBFBD>H
uint16_t weightL; // <20><><EFBFBD><EFBFBD>L
uint16_t highMMWC;
uint16_t press;
int16_t tempr; //30010<31><EFBFBD>
uint16_t source; //30011<31><31><EFBFBD><EFBFBD>
uint16_t v_H; //
uint16_t v_L; //
// uint16_t staVacuum; // <20><><EFBFBD>ռ<EFBFBD>״̬
// uint16_t vacuum; // <20><><EFBFBD>նȣ<D5B6>
// int16_t vacuum_tempr;//30016 <20><><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>
///////////////////
uint16_t crc;
} modbus_readdata_t;
#pragma pack(pop)
// modbus rtu <20><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
#define MODBUS_1ST_REG (30001) // <20><>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ
#define MODBUS_LAST_REG (30016) // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ
#define MODBUS_ADR_REG (40001) // ͨ<>ŵ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ
// modbus rtu<74><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MODBUS_ERR_ILF (0x01) // <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MODBUS_ERR_ILA (0x02) // <20><>ЧͨѶ<CDA8><D1B6>ַ
#define MODBUS_ERR_ILD (0x03) // <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>ֵ
#define MODBUS_ERR_FID (0x04) // ִ<><D6B4>ʧ<EFBFBD><CAA7>
#define MODBUS_ERR_ACK (0x05) // ACK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD><D1BD>ܲ<EFBFBD><DCB2>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>У<EFBFBD>
#define MODBUS_ERR_BUSY (0x06) // <20>豸æ<E8B1B8><C3A6><EFBFBD>ܾ<EFBFBD>
#define MODBUS_ERR_NAK (0x07) // NAK<41><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>ִ<EFBFBD>У<EFBFBD>
// modbus rtu <20><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
//uint8_t MODBUS_RTU_Buf[(MODBUS_LAST_REG - MODBUS_1ST_REG + 1) * 2];
modbus_readdata_t modbus_data;
void Slave_IRQHandler(USART_Handle *huart)
{
uint8_t u8DTU = (uint8_t) huart->Instance->RDR;
/* Handle received data */
Modbus_Task(u8DTU);
}
void Slave_Init()
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
//LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
/**USART3 GPIO Configuration
PC10 ------> USART3_TX
PC11 ------> USART3_RX
PA15 ------> USART3_DE
Pb10 ------> LPRX
Pb11 ------> LPTX
Pb1 ------> LP_DE
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_10|LL_GPIO_PIN_11;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
//GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
#define RS485_EN() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_1);
#define RS485_DIS() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_1);
/*---------------------------------------------------------------------------------------------------------*/
/* RS485 Transmit Control (Address Byte: Parity Bit =1 , Data Byte:Parity Bit =0) */
/*---------------------------------------------------------------------------------------------------------*/
static void RS485_SendDataByte(uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
/* Set UART parity as SPACE and skip baud rate setting */
// UART_SetLine_Config(UART1, 0, UART_WORD_LEN_8, UART_PARITY_SPACE, UART_STOP_BIT_1);
/* Send data */
// UART_Transmit_IT(&huart3, pu8TxBuf, u32WriteBytes);
RS485_EN();
delay_us(1);
// <20><><EFBFBD>ó<EFBFBD>ʱ<EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
modbus_outTick = GetDelayTick(500);
UART_Transmit_IT(&hlpuart1, pu8TxBuf, u32WriteBytes);
delay_ms(9); // <20><><EFBFBD><EFBFBD>8ms<6D><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>9ms
RS485_DIS();
}
void Slave_Open()
{
// LL_USART_InitTypeDef USART_InitStruct = {0};
// huart3.RxISR = Slave_IRQHandler;
// /* Peripheral clock enable */
// LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);
// /* USART3 interrupt Init */
// NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
// NVIC_EnableIRQ(USART3_IRQn);
// /* USER CODE BEGIN USART3_Init 1 */
// /* USER CODE END USART3_Init 1 */
// USART_InitStruct.BaudRate = 9600;
// USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
// USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
// USART_InitStruct.Parity = LL_USART_PARITY_NONE;
// USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
// USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
// USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
// LL_USART_Init(USART3, &USART_InitStruct);
// LL_USART_EnableDEMode(USART3);
// LL_USART_SetDESignalPolarity(USART3, LL_USART_DE_POLARITY_HIGH);
// LL_USART_SetDEAssertionTime(USART3, 0);
// LL_USART_SetDEDeassertionTime(USART3, 0);
// LL_USART_ConfigAsyncMode(USART3);
// SET_BIT(USART3->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
// LL_USART_Enable(USART3);
LL_LPUART_InitTypeDef LPUART_InitStruct = {0};
hlpuart1.RxISR = Slave_IRQHandler;
/* Peripheral clock enable */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(LPUART1_IRQn);
LPUART_InitStruct.BaudRate = 9600;
LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B;
LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1;
LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE;
LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX;
LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE;
LL_LPUART_Init(LPUART1, &LPUART_InitStruct);
LL_LPUART_EnableDEMode(LPUART1);
LL_LPUART_SetDESignalPolarity(LPUART1, LL_LPUART_DE_POLARITY_HIGH);
LL_LPUART_SetDEAssertionTime(LPUART1, 0);
LL_LPUART_SetDEDeassertionTime(LPUART1, 0);
SET_BIT(LPUART1->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
LL_LPUART_Enable(LPUART1);
}
uint32_t Fill_MODBUS_RTU_Buf()
{
return 1;
}
// <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_readdata_t *req)
{
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ŵ<EFBFBD>ַ
if(req->id != 0x01)
return;
if(req->cmd != 0x04)
return;
}
// ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t modbus_idx2 = 0;
uint8_t MODBUS_BUFF[sizeof(modbus_readdata_t)] = {0};
uint16_t CRC2=0;
void Modbus_Task(uint8_t c)
{
uint8_t len = 0;
////////////
uint16_t i;
uint8_t frameOk, frameErr;
uint32_t mask;
//rs_data_t *rsData = (rs_data_t *) (RS_TranFrame.data + sizeof(mask));
if(modbus_idx2 == 0 && c != 0x01)
return;
MODBUS_BUFF[modbus_idx2++] = c;
// printf("\n***\n***\n*** read data[%d]=%d ***\n***\n***\n",len,c);
// <20><>֤<EFBFBD><D6A4><EFBFBD>Ⱥ<EFBFBD>CRCֵ
len=sizeof(modbus_readdata_t)-1;
if(modbus_idx2 == len)
{
if(MODBUS_RTU_CRC16(MODBUS_BUFF, sizeof(modbus_readdata_t)) == 0)
{
MODBUS_RTU_CMD((modbus_readdata_t *) MODBUS_BUFF);
modbus_idx2 = 0;
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>
memmove(MODBUS_BUFF, MODBUS_BUFF + 1, --modbus_idx2);
}
}
}
void modbus_read_data(void)
{
// uint8_t id; // ͨ<>ŵ<EFBFBD>ַ
// uint8_t cmd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// uint16_t reg; // <20>Ĵ<EFBFBD><C4B4><EFBFBD><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;
// static uint8_t BUFF2[sizeof(modbus_request_t)] = {0x01,0x04,0x00,0x00,0x00,0x0d,0x31,0xcf};
static uint8_t BUFF2[sizeof(modbus_request_t)] = {0};
uint8_t len=0;
// <20><><EFBFBD><EFBFBD>CRC
BUFF2[len++]=0x01; //addr
BUFF2[len++]=0x04; //cmd
BUFF2[len++]=0x00; //regaddr
BUFF2[len++]=0x00; //regaddr
BUFF2[len++]=0x00; //cnt
BUFF2[len++]=0x0d; //cnt
crc = MODBUS_RTU_CRC16(BUFF2, len);
crc = htons(crc);
memmove(BUFF2 + len, &crc, 2);
len += 2;
RS485_SendDataByte(BUFF2, len);
}