// // Created by DELL on 2024/10/18. // #include "modbus_slave.h" #include "port.h" #include "mb.h" #include "cmsis_os2.h" extern uint8_t error_count; 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; uint8_t led_count = 0; uint16_t reg_value; eMBInit(MB_RTU, slave_addr, 2, 9600, MB_PAR_NONE); eMBEnable(); for (;;) { eMBPoll(); if ((led_count > 10) && (get_reg_value(INNER_ERROR2_REG_ADDRESS) || get_reg_value(INNER_ERROR1_REG_ADDRESS))) { reg_value ++; if (reg_value > 20) { HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin); // HAL_GPIO_WritePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin, GPIO_PIN_RESET); } } else { HAL_GPIO_WritePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin, GPIO_PIN_SET); reg_value = 0; } led_count++; osDelay(5); } } void start_485_slave(uint8_t address)//启动485从机 { osThreadNew(slave_485_task, (void *) address, &task_attributes); }