modbus slave
Modbus 协议广泛应用在工业机器人和电机控制领域,比如机械臂,6轴或者8轴机器人领域,很多都是使用modbus来进行通信的。自从 1979 年出现工业串行链路的事实标准以来,MODBUS 使成千上万的自动化设备能够通信。
网上有很多开源的modbus协议栈,比较有名的像libmodbus, freemodbus,mbus等等,这些协议栈都是老外写的,都是别人自做的,本来学好一个协议栈最好的方法就是自己手写代码来实现完整的功能,这样才能锻炼提高自己的编码水平和能力。所以这期我就来手写一个modbus从站来代替这些开源的协议,做点与众不同的事情。多做原创!!!!
首先来分析modbus的数据帧格式:

整个协议栈分为地址域,功能码,数据和差错校验。
MODBUS 数据模型如下

主要功能码如下:

01 (0x01)读线圈
02 (0x02)读离散量输入
03 (0x03)读保持寄存器
04(0x04)读输入寄存器
05 (0x05)写单个线圈
06 (0x06)写单个寄存器
15 (0x0F) 写多个线圈
16 (0x10) 写多个寄存器
主要就是上面这8种功能码,就可以满足99%以上的modbus应用领域了。
好了,下面来看核心代码实现:

然后进入这8个功能码,解析实现每种功能,非常的简单。
1,(0x01)读线圈


2.(0x02)读离散量输入


(0x03)读保持寄存器

(0x04)读输入寄存器

(0x05)写单个线圈

(0x06)写单个寄存器

(0x0F) 写多个线圈

(0x10) 写多个寄存器

主函数main中添加功能函数
#include "hal_data.h"
#include "usart9.h"
#include "usart6.h"
#include "modbusSlave.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/*******************************************************************************************************************//**
-
main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
-
is called by main() when no RTOS is used.
*********************************************************************************************************************/
void hal_entry(void)
{
/ TODO: add your own code here */
UART9_Init();UART6_Init();
printf("modbus_slave test\r\n");
while(1)
{
if(user_uart6_wait_receive( ) == REV_OK)
{
modbus_slave();
user_uart6_clear();
}
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*******************************************************************************************************************//**
-
This function is called at various points during the startup process. This implementation uses the event that is
-
called right before main() to set up the pins.
-
@param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart (bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
R_FACI_LP->DFLCTL = 1U;
#endif
}
if (BSP_WARM_START_POST_C == event)
{
R_IOPORT_Open(&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#if BSP_CFG_SDRAM_ENABLED
R_BSP_SdramInit(true);
#endif
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif

编译烧录代码


打开modbus poll软件

1.读取线圈

2.读离散量输入


3。读保持寄存器


4。读输入寄存器


5。写单个线圈


6。写单个寄存器


7。写多个线圈


8。写多个寄存器


所有modbus slave的8种功能全部测试合格!!!!
详情看视频
|