// // Created by DELL on 2024/10/18. // #include "modbus_slave.h" #include "port.h" #include "mb.h" #include "cmsis_os2.h" USHORT usSRegHoldStart = S_REG_HOLDING_START; static USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS]; const static osThreadAttr_t task_attributes = { .name = "slave_485_task", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityHigh, }; /** * 输入型寄存器读写回调函数 * @param pucRegBuffer * @param usAddress * @param usNRegs * @return */ eMBErrorCode eMBRegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs) { return MB_ENOERR; } /** * 保持型寄存器读写回调函数 * @param pucRegBuffer * @param usAddress * @param usNRegs * @param eMode * @return */ eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode) { eMBErrorCode eStatus = MB_ENOERR; USHORT iRegIndex; USHORT *pusRegHoldingBuf; USHORT REG_HOLDING_START; USHORT REG_HOLDING_NREGS; USHORT usRegHoldStart; pusRegHoldingBuf = usSRegHoldBuf; REG_HOLDING_START = S_REG_HOLDING_START; REG_HOLDING_NREGS = S_REG_HOLDING_NREGS; usRegHoldStart = usSRegHoldStart; /* it already plus one in modbus function method. */ usAddress--; if ((usAddress >= REG_HOLDING_START) && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS)) { iRegIndex = usAddress - usRegHoldStart; switch (eMode) { /* read current register values from the protocol stack. */ case MB_REG_READ: while (usNRegs > 0) { *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8); *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF); iRegIndex++; usNRegs--; } break; /* write current register values with new values from the protocol stack. */ case MB_REG_WRITE: while (usNRegs > 0) { pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8; pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++; iRegIndex++; usNRegs--; } break; } } else { eStatus = MB_ENOREG; } return eStatus; } uint16_t get_reg_value(uint16_t addr) { if (addr >= S_REG_HOLDING_NREGS) { return 0; } return usSRegHoldBuf[addr]; } void set_reg_value(uint16_t addr, uint16_t value) { if (addr >= S_REG_HOLDING_NREGS) { return; } usSRegHoldBuf[addr] = value; } /** * 从机任务 * @param pv */ _Noreturn static void slave_485_task(void *pv) { eMBErrorCode code; uint8_t slave_addr = (uint8_t) pv; eMBInit(MB_RTU, slave_addr, 3, 9600, MB_PAR_NONE); eMBEnable(); for (;;) { eMBPoll(); osDelay(5); } } void start_485_slave(uint8_t address)//启动485从机 { usSRegHoldBuf[0] = address; // init current communication address osThreadNew(slave_485_task, (void *) address, &task_attributes); }