283 lines
7.9 KiB
C
283 lines
7.9 KiB
C
|
|
#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);
|
|||
|
|
|
|||
|
|
}
|