226 lines
6.4 KiB
C++
226 lines
6.4 KiB
C++
|
|
#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 ********/
|