|
|
#include "modbus_processer.hpp"
#include <stdbool.h>
#include <stdint.h>
/***********************485rx**************************/ // ���յ��˶�������
// volatile uint16_t s_modbus_uart_rx_off = 0;
// ��ǰ�Ƿ����ڴ������յ�������
// volatile bool s_modbus_uart_rx_buf_is_processing = false;
/***********************485tx**************************/ static modbus_processer_t* g_processer;
#define GET_UINT16(uint8) (uint16_t)(((uint16_t)((uint8)[0]) << 8) + (uint8)[1])
void modbus_processer_process_data(uint8_t* rx, uint16_t len); void modbus_processer_init(modbus_processer_t* processer) { g_processer = processer; }
void ModbusProcessRxData(uint8_t* rxraw, uint8_t length, ModbusMasterData_t* rxparsed) { rxparsed->functionCode = (ModbusFunctionCode)rxraw[1]; if (rxraw[1] == ModbusOrder01 || rxraw[1] == ModbusOrder02 || rxraw[1] == ModbusOrder03 || rxraw[1] == ModbusOrder04) { /**
* @brief * �����ǹ����壬���Ծ���001��ֵ���� */ rxparsed->d.O01.startbit = rxraw[2] * 256 + rxraw[3]; rxparsed->d.O01.numbit = rxraw[4] * 256 + rxraw[5]; } else if (rxraw[1] == ModbusOrder0F || rxraw[1] == ModbusOrder10) { /**
* @brief * �����ǹ����壬���Ծ���0F��ֵ���� */ rxparsed->d.O0F.startbit = rxraw[2] * 256 + rxraw[3]; rxparsed->d.O0F.numbit = rxraw[4] * 256 + rxraw[5]; rxparsed->d.O0F.bytenum = rxraw[6]; rxparsed->d.O0F.bit = &rxraw[7]; } else { /**
* @brief Not support now */ } }
#define UINT16ToUINT8(u16d, u8addbegin) \
{ \ (u8addbegin)[0] = u16d >> 8; \ (u8addbegin)[1] = (uint8_t)u16d; \ }
void ModbusCreateTx_setReg(uint8_t* txbuffer, uint8_t length, uint16_t off, uint16_t regdata) { if (3 + off * 2 > length - 2) { return; } txbuffer[3 + off * 2] = regdata >> 8; txbuffer[3 + off * 2 + 1] = (uint8_t)regdata; }
void ModbusCreateTxData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, ModbusSlaveData_t* txdata) { /**
* @brief TODO:����txbuffer���ȼ��� */ if (length < 4) return; txbuffer[0] = txdata->deviceId; txbuffer[1] = (uint8_t)txdata->functionCode; *sendlength = 0; volatile uint16_t _sendlength = 0; volatile uint16_t i = 0;
if (txdata->functionCode == ModbusOrder01 || txdata->functionCode == ModbusOrder02 || txdata->functionCode == ModbusOrder03 || txdata->functionCode == ModbusOrder04) { /**
* @brief 01,02 ָ������bit */
// ��ȡ��������״̬
// sendLen =
// add(1byte)+functionCode(1byte)+addNum(1)+crc(2) = 5+numbyte
volatile uint16_t numbyte = txdata->d.O01.bytenum; _sendlength = 5 + numbyte; if (length < _sendlength) return; txbuffer[2] = txdata->d.O01.bytenum; if (txdata->d.O01.byte_table != nullptr) { for (i = 0; i < numbyte; i++) { txbuffer[3 + i] = txdata->d.O01.byte_table[i]; } } } else if (txdata->functionCode == ModbusOrder0F || txdata->functionCode == ModbusOrder10) { // ���������
// sendLen = add(1byte)+functionCode(1byte)+startAdd(2)+addNum(2)+crc(2) = 8
_sendlength = 8; if (length < _sendlength) return;
UINT16ToUINT8(txdata->d.O0F.startbit, &txbuffer[2]); UINT16ToUINT8(txdata->d.O0F.bitnum, &txbuffer[4]); } else { /**
* @brief Not support now */ } // calculate crc
if (_sendlength > 2) { modbus_pack_crc_to_packet(txbuffer, _sendlength); } *sendlength = _sendlength; }
void ModbusCreateExceptionData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, uint8_t deviceid, uint8_t functioncode, ModbusStatus status) { /**
* @brief TODO:����txbuffer���ȼ��� */ volatile uint16_t _sendlength = 0; volatile uint16_t i = 0;
if (length < 4) return; txbuffer[0] = deviceid; txbuffer[1] = functioncode | 0x80; txbuffer[2] = (uint8_t)status; *sendlength = 0; // sendLen = add(1byte)+functionCode(1byte)+exception(1)+crc(2) = 4
_sendlength = 4; modbus_pack_crc_to_packet(txbuffer, _sendlength); *sendlength = _sendlength; return; } #if 0
void modbus_processer_try_process_data(void) { /**
* @brief * ����modbusЭ�飬������3.5���ַ�ʱ������Ȼû���յ����� */ // bool receive_one_packet = false; // ��Ϊkeil��������ע��
if (s_modbus_uart_rx_off != 0) { uint16_t modbus_uart_rx_off_before = s_modbus_uart_rx_off;
g_processer->port_delay_us(g_processer->modbus_baundrate_one_packet_delay_us);
g_processer->port_enter_critical(); if (s_modbus_uart_rx_off == modbus_uart_rx_off_before) { s_modbus_uart_rx_buf_is_processing = true; } g_processer->port_exit_critical();
if (s_modbus_uart_rx_buf_is_processing) { modbus_processer_process_data(g_processer->modbus_processer_rx_buf, s_modbus_uart_rx_off); g_processer->port_enter_critical(); s_modbus_uart_rx_off = 0; s_modbus_uart_rx_buf_is_processing = false; g_processer->port_exit_critical(); } } } #endif
/***********************************************************************************************************************
* ==================================================modbus��Ϣ����=================================================== * ***********************************************************************************************************************/ void modbus_processer_process_data(uint8_t* rx, uint16_t rxlen) { /**
* @brief modbus���������Ժ����������д������� * */ // �������ǹ㲥��Ϣ���߲��ǵ�ǰ�豸����Ϣ������
if (rx[0] != 0 && rx[0] != g_processer->modbus_device_id) { return; } // CRCУ��ʧ��
if (!modbus_checkcrc16(rx, rxlen)) { return; } // if(functioncode)
static ModbusMasterData_t rxorder; static ModbusSlaveData_t txorder; // �����ܵ������ݽ�������
ModbusProcessRxData(rx, rxlen, &rxorder); // static uint16_t txsendlen = 0; // ��Ϊkeil��������ע��
txorder.deviceId = g_processer->modbus_device_id; // ������
txorder.functionCode = rxorder.functionCode;
modbus_processer_context_t context = {0}; context.tx = &txorder; context.rx = &rxorder; g_processer->process_rx(&context); }
/***********************************************************************************************************************
* ======================================================Extern======================================================= * ***********************************************************************************************************************/
ModbusFunctionCode modbus_get_function_code(modbus_processer_context_t* context) { //
return context->tx->functionCode; } void modbus_set_tx_reg_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regdata) { uint16_t off = regoff - context->rx->d.O03.startreg; ModbusCreateTx_setReg(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, off, //
regdata); } void modbus_set_tx_regs_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t* regdata, int reglen) { for (int i = 0; i < reglen; i++) { modbus_set_tx_reg_03(context, regoff + i, regdata[i]); } }
uint16_t modbus_get_reg_10(modbus_processer_context_t* context, uint16_t regoff) { uint16_t off = regoff - context->rx->d.O10.startreg; uint8_t* data = context->rx->d.O10.reg; if ((off + 1) * 2 <= context->rx->d.O10.bytenum) { uint16_t u16 = GET_UINT16(&data[off * 2]); return u16; } else { uint16_t u16 = data[off * 2]; return u16; } } uint8_t* modbus_get_buf_10(modbus_processer_context_t* context, uint16_t regoff) { uint16_t off = regoff - context->rx->d.O10.startreg; uint8_t* data = context->rx->d.O10.reg; return &data[off * 2]; } bool modbus_if_register_exists_03(modbus_processer_context_t* context, uint16_t regoff) { uint16_t startreg = context->rx->d.O03.startreg; uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg; return regoff >= startreg && regoff < endreg; } bool modbus_if_registers_exists_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regnum) { return (modbus_if_register_exists_03(context, regoff) && modbus_if_register_exists_03(context, regoff + regnum - 1)); }
bool modbus_if_register_exists_10(modbus_processer_context_t* context, uint16_t regoff) { uint16_t startreg = context->rx->d.O10.startreg; uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg; return regoff >= startreg && regoff < endreg; } void modbus_send_03(modbus_processer_context_t* context, ModbusStatus modbus_status) { uint16_t sendlegth = 0; if (modbus_status == Modbus_OK) { /**
* @brief ���� */ context->tx->functionCode = context->rx->functionCode; context->tx->deviceId = g_processer->modbus_device_id; context->tx->d.O03.bytenum = context->rx->d.O03.numreg * 2; context->tx->d.O03.reg = nullptr; // ������Ӧ��
ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx); // �������Ժ�����������
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth); } else { // LOGD("error");
/**
* @brief �쳣 */ // �����쳣����
ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
g_processer->modbus_processer_tx_buf_size, //
&sendlegth, //
g_processer->modbus_device_id, //
context->rx->functionCode, //
modbus_status); // �������ɷ���Ӧ��
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth); } } void modbus_send_10(modbus_processer_context_t* context, ModbusStatus modbus_status) { uint16_t sendlegth = 0; if (modbus_status == Modbus_OK) { context->tx->functionCode = context->rx->functionCode; context->tx->deviceId = g_processer->modbus_device_id; context->tx->d.O10.regnum = context->rx->d.O10.numreg; context->tx->d.O10.startreg = context->rx->d.O10.startreg; // ������ִ��������
ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx); g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth); } else { // �����쳣��������
ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
g_processer->modbus_processer_tx_buf_size, //
&sendlegth, //
g_processer->modbus_device_id, //
context->rx->functionCode, //
modbus_status); g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth); } }
|