YouSuanZhi/Core/Src/Modbus/MODBUS-Port-STM32.C

226 lines
6.4 KiB
C++
Raw Normal View History

2026-03-17 02:42:36 +00:00
#include "mb.h"
#include "mbport.h"
#include "mbutils.h"
#include "cmsis_os2.h"
#define MB_USART USART1
#define MB_TIMER TIM7
#include "portEvent.c"
#include "portSerial.c"
#include "portTimer.c"
/* ----------------------- Defines ------------------------------------------*/
#define REG_INPUT_START 1
#define REG_INPUT_NREGS 80
USHORT usRegInputBuf[REG_INPUT_NREGS];
#define REG_HOLDING_START 1
#define REG_HOLDING_NREGS 80
USHORT usRegHoldingBuf[REG_HOLDING_NREGS];
#define REG_DISC_START 1
#define REG_DISC_SIZE 80
UCHAR ucRegDiscBuf[(REG_DISC_SIZE+7U)/8U];
#define REG_COILS_START 1
#define REG_COILS_SIZE 80
UCHAR ucRegCoilsBuf[(REG_COILS_SIZE+7U)/8U];
#define REG_NVRAM_START 1001
#define REG_NVRAM_NREGS 1000
extern void delay_us(uint32_t us);
/* ----------------------- Static variables ---------------------------------*/
// 读数字寄存器 功能码0x04
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
int16_t iRegIndex;
delay_us( 50u );
if( ( usAddress >= REG_INPUT_START )
&& ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
{
iRegIndex = (int16_t)( usAddress - REG_INPUT_START );
while( usNRegs > 0 )
{
*pucRegBuffer++ = (uint8_t)( usRegInputBuf[iRegIndex] >> 8 );
*pucRegBuffer++ = (uint8_t)( usRegInputBuf[iRegIndex] & 0xFF );
iRegIndex++;
usNRegs--;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
// 寄存器的读写函数 支持的命令为读 0x03 和写0x06
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
int16_t iRegIndex;
delay_us( 50u );
if( ( usAddress >= REG_HOLDING_START ) && ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
{ // 访问的地址空间是RAM映像区
iRegIndex = (int16_t)( usAddress - REG_HOLDING_START );
switch ( eMode )
{
case MB_REG_READ:
while( usNRegs > 0 )
{
*pucRegBuffer++ = (uint8_t)( usRegHoldingBuf[iRegIndex] >> 8 );
*pucRegBuffer++ = (uint8_t)( usRegHoldingBuf[iRegIndex] & 0xFF );
iRegIndex++;
usNRegs--;
}
break;
case MB_REG_WRITE:
while( usNRegs > 0 )
{
usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
iRegIndex++;
usNRegs--;
}
}
}
else if( ( usAddress >= REG_NVRAM_START ) && ( usAddress + usNRegs <= REG_NVRAM_START + REG_NVRAM_NREGS ) )
{ // 访问的地址空间是 NVRAM 区
iRegIndex = ( int )( usAddress - REG_NVRAM_START );
switch ( eMode )
{
case MB_REG_READ:
// while( usNRegs > 0 )
// {
// *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[iRegIndex] >> 8 );
// *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[iRegIndex] & 0xFF );
// iRegIndex++;
// usNRegs--;
// }
// NVRAM_Load( iRegIndex * 2u, pucRegBuffer, usNRegs * 2u );
break;
case MB_REG_WRITE:
// NVRAM_Save( iRegIndex * 2u, pucRegBuffer, usNRegs * 2u );
// while( usNRegs > 0 )
// {
// usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
// usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
// iRegIndex++;
// usNRegs--;
// }
break;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
// 读/写开关寄存器 0x01 0x05
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
int16_t iNCoils = (int16_t)usNCoils;
uint16_t usBitOffset;
delay_us( 50u );
/* Check if we have registers mapped at this block. */
if( ( usAddress >= REG_COILS_START ) &&
( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )
{
usBitOffset = (uint16_t)( usAddress - REG_COILS_START );
switch ( eMode )
{
/* Read current values and pass to protocol stack. */
case MB_REG_READ:
while( iNCoils > 0 )
{
*pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset, (uint8_t)( iNCoils > 8 ? 8 : iNCoils ));
iNCoils -= 8;
usBitOffset += 8;
}
break;
/* Update current register values. */
case MB_REG_WRITE:
while( iNCoils > 0 )
{
xMBUtilSetBits( ucRegCoilsBuf, usBitOffset, (uint8_t)( iNCoils > 8 ? 8 : iNCoils ), *pucRegBuffer++ );
iNCoils -= 8;
}
break;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
// 读开关寄存器 0x02
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
eMBErrorCode eStatus = MB_ENOERR;
int16_t iNDiscrete = ( int16_t )usNDiscrete;
uint16_t usBitOffset;
delay_us( 50u );
/* Check if we have registers mapped at this block. */
if( ( usAddress >= REG_DISC_START ) &&
( usAddress + usNDiscrete <= REG_DISC_START + REG_DISC_SIZE ) )
{
usBitOffset = ( uint16_t )( usAddress - REG_DISC_START );
while( iNDiscrete > 0 )
{
*pucRegBuffer++ = xMBUtilGetBits( ucRegDiscBuf, usBitOffset, (uint8_t)( iNDiscrete > 8 ? 8 : iNDiscrete ) );
iNDiscrete -= 8;
usBitOffset += 8;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
osThreadId_t MBRunTaskHandle;
const osThreadAttr_t MBRunTask_attributes = {
.name = "MBRunTask",
.stack_size = 128 * 10,
.priority = (osPriority_t) osPriorityHigh,
};
// 初始化MODBUS
void MODBUS_Init( uint8_t MBAddress )
{
// osThreadDef( ModbusPoll, osPriorityHigh, 1u, 0u );
// osThreadCreate( osThread( ModbusPoll ), NULL );
MBRunTaskHandle = osThreadNew( ModbusPoll, NULL, &MBRunTask_attributes);
eMBInit( MB_RTU, MBAddress, 1, 115200u, MB_PAR_NONE ); // 初始化 FreeModbus 为RTU模式 从机地址为1 Uart1 9600 无校验
eMBEnable(); // 启动 FreeModbus
}
/******** (C) COPYRIGHT 2020 青岛顺昕电子科技有限公司 **** End Of File ********/