沐鸣娱乐


        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        一、RS485基础通信例程实现的功能描述

        开发板通过UART1接口 SP485EEN芯片实现和电脑端串口调试助手的通信。并实现如下两个收发范例功能:
        如果PC端通过485向开发板发送5字节数据 ,且5字节数据为06 07 08 09 0A ,则黄色LED1闪烁一次
        开发板每隔1秒通过485向PC端发送5字节数据 ,01 02 03 04 05

        二、本实验教学目的

        掌握基于ShineBlink的 :
        UART通信(占用RX1,TX1)
        GPIO控制485转换芯片的方向(D2引脚控制485芯片的方向,高电平)
        -GPIO控制LED1亮灭(D8连接黄色LED1)

        三、本实验涉及的模块
        485接口在开发板上的位置如下 :

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        注意,为了使用485接口,必须将P7和P8跳线帽短接才能让TX1引脚、RX1引脚和485转换芯片连接 。

        四 、完整源代码
        以下代码实现了如下功能:
        如果PC端通过485向开发板发送5字节数据 ,且5字节数据为06 07 08 09 0A,则黄色LED1闪烁一次
        开发板每隔1秒通过485向PC端发送5字节数据,01 02 03 04 05

        1. LIB_GpioOutputConfig("D8","STANDARD") –初始化GPIO控制黄色LED1
        2. LIB_GpioOutputConfig("D2","STANDARD") –初始化GPIO控制Max485 RE DE 收发控制
        3. –配置Uart1串口波特率为19200 ,用作485通讯
        4. LIB_Uart1Config("BAUDRATE_19200")
        5. –使能MAX485发送
        6. function SendEn()
        7. LIB_GpioWrite("D2",1)
        8. end
        9. –使能MAX485接收
        10. function recvEn()
        11. LIB_GpioWrite("D2",0)
        12. end
        13. –使能10毫秒定时器开始工作
        14. LIB_10msTimerConfig("ENABLE")
        15. cnt_10ms = 0
        16. –定义10毫秒定时器的中断函数
        17. function LIB_10msTimerCallback()
        18. cnt_10ms = cnt_10ms 1
        19. end
        20. –开始大循环
        21. while(GC(1) == true)
        22. do
        23. –每1秒发送5字节数据给PC端
        24. if cnt_10ms >= 100 then –1000ms
        25. cnt_10ms = 0
        26. send_data = {1,2,3,4,5}
        27. SendEn()
        28. LIB_Uart1BlockSend(send_data)
        29. RecvEn()
        30. end
        31. –查询是否收到PC端发来的5字节数据,并验证
        32. recv_flag,recv_data = LIB_Uart1Recv()
        33. if recv_flag == 1 and #recv_data == 5 then
        34. if recv_data[1] == 6 and recv_data[2] == 7 and recv_data[3] == 8 and recv_data[4] == 9 and recv_data[5] == 10 then
        35. LIB_GpioToggle("D8") –切换LED状态
        36. end
        37. end
        38. end

        复制代码

        五 、实验现象

        将开发板的485接口通过485转USB工具和PC端连接以后,将上面的代码复制到开发板的虚拟TF卡中并开始运行,之后每秒钟可以在PC端串口调试助手收到开发板发来的5字节数据(01 02 03 04 05) ,并且当调试助手向开发板下发(06 07 08 09 0a)以后 ,开发板的黄色LED灯会闪烁以下 ,如下图:

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        注意 :软件需要勾选“HEX显示”和"HEX发送"。设备和上位机(Modbus主机)通信的实现简介 :下文介绍了如何用ShineBlink作为设备端(Modbus从机)来和上位机(Modbus主机)来通信,并在ShineBlink设备端实现了0x03功能码(读取多个保持寄存器)和0x05功能码(写单个线圈)的程序代码。一、实现环境设备作为Modbus从机通过RS485总线上位机通信,我们在电脑上运行知名的Modbus Poll调试软件作为上位机来模拟Modbus主机 ,Modbus Poll软件可以到其官网上下载。二、设备介绍设备作为Modbus网络中的其中一个节点有如下特性:串口属性:19200、N 、8 、1设备地址:21(0x15)设备支持的Modbus功能码 :0x05 写单个线圈0x03 读取多个保持寄存器功能介绍 :0x05 ,上位机通过向设备发送0x05功能码,对线圈地址为0x0000的线圈写入值0xFF00时,设备开始运行,对线圈地址为0x0000的线圈写入值0x0000时 ,设备停止运行 。0x03,上位机通过向设备发送0x03功能码,读取保持寄存器起始地址为0x0000的9个保持寄存器(每个保持寄存器值为16bit无符号数据) ,每个寄存器对应的数据如下:

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        三、Modbus通信实现代码实例

        以下代码不仅实现了03和05功能码,并实现了将各种异常情况回复给Modbus主机。

        1. –程序中用到的全局变量定义
        2. Pm25Percent = 0
        3. HchoPercent = 0
        4. TvocPercent = 0
        5. MeshPercent = 0.0
        6. Temprature1 = 0.00
        7. Temprature2 = 0.00
        8. Wind485DisSpeed = 0
        9. DevIsRunning = 0 –控制设备运行或停止
        10. FaultCode = 0 –故障代码
        11. –ModBus通信函数定义
        12. function ModbusProcess()
        13. local sdata = {}
        14. –查询是否收到Modbus主机发来的消息
        15. flag, data = LIB_Uart1Recv()
        16. if flag == 1 then
        17. –判断消息是不是发给本机,是本机的才理会
        18. if data[1] == PI[2] then –PI[2], Modbus本机地址(1-247)
        19. –判断Modbus功能码
        20. if data[2] == 0x05 then — 0x05 写单个线圈
        21. –这里定义线圈地址为0x0000的线圈为开机/关机控制信号
        22. if data[3] == 0x00 and data[4] == 0x00 then
        23. if data[5] == 0xff and data[6] == 0x00 then –ON
        24. DevIsRunning = 1 –置1开机全局变量
        25. elseif data[5] == 0x00 and data[6] == 0x00 then –OFF
        26. DevIsRunning = 0 –置0开机全局变量
        27. else
        28. –这里需回复非法数据03异常消息(非法数据值),读者可自行完成
        29. end
        30. –回复OK,把收到的数据原封不动回传
        31. LIB_GpioWrite("D2",1) –使能485模块发送
        32. LIB_Uart1BlockSend(data)
        33. LIB_GpioWrite("D2",0) –使能485模块接收
        34. else
        35. –回复异常消息(非法数据地址)
        36. sdata[1] = data[1] –本机地址
        37. sdata[2] = data[2] 0x80 –异常的时候功能码加0x80
        38. sdata[3] = 0x02 –异常码0x02表示设备不支持此数据地址
        39. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
        40. sdata[4] = CRC & 0x00ff –低位在前
        41. sdata[5] = CRC >> 8 –高位在后
        42. LIB_GpioWrite("D2",1) –使能485模块发送
        43. LIB_Uart1BlockSend(sdata)
        44. LIB_GpioWrite("D2",0) –使能485模块接收
        45. end
        46. –这里用0x03而不用0x04是因为很多主机只支持03 06 16指令,所以就随大流咯
        47. elseif data[2] == 0x03 then –0x03 读多个保持寄存器
        48. –这里定义起始地址为0x0000的这些寄存器存放传感器数据,且读取的寄存器个数必须是9个
        49. if data[3] == 0x00 and data[4] == 0x00 and data[5] == 0x00 and data[6] == 0x09 then
        50. sdata[1] = data[1] –本机地址
        51. sdata[2] = data[2] –功能码
        52. sdata[3] = 18 –数据域字节数: 9个寄存器一共18字节
        53. sdata[4] = Pm25Percent >> 8
        54. sdata[5] = Pm25Percent & 0x00ff
        55. sdata[6] = HchoPercent >> 8
        56. sdata[7] = HchoPercent & 0x00ff
        57. sdata[8] = TvocPercent >> 8
        58. sdata[9] = TvocPercent & 0x00ff
        59. sdata[10] = math.floor(MeshPercent) >> 8
        60. sdata[11] = math.floor(MeshPercent) & 0x00ff
        61. sdata[12] = math.floor(Temprature1) >> 8
        62. sdata[13] = math.floor(Temprature1) & 0x00ff
        63. sdata[14] = math.floor(Temprature2) >> 8
        64. sdata[15] = math.floor(Temprature2) & 0x00ff
        65. sdata[16] = Wind485DisSpeed >> 8
        66. sdata[17] = Wind485DisSpeed & 0x00ff
        67. sdata[18] = DevIsRunning >> 8
        68. sdata[19] = DevIsRunning & 0x00ff
        69. sdata[20] = FaultCode >> 8
        70. sdata[21] = FaultCode & 0x00ff
        71. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
        72. sdata[22] = CRC & 0x00ff –低位在前
        73. sdata[23] = CRC >> 8 –高位在后
        74. –回复传感器数据
        75. LIB_GpioWrite("D2",1) –使能485模块发送
        76. LIB_Uart1BlockSend(sdata)
        77. LIB_GpioWrite("D2",0) –使能485模块接收
        78. else
        79. –回复异常消息(非法数据地址)
        80. sdata[1] = data[1] –本机地址
        81. sdata[2] = data[2] 0x80 –异常的时候功能码加0x80
        82. sdata[3] = 0x02 –异常码0x02表示设备不支持此数据地址
        83. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
        84. sdata[4] = CRC & 0x00ff –低位在前
        85. sdata[5] = CRC >> 8 –高位在后
        86. LIB_GpioWrite("D2",1) –使能485模块发送
        87. LIB_Uart1BlockSend(sdata)
        88. LIB_GpioWrite("D2",0) –使能485模块接收
        89. end
        90. else
        91. –回复异常消息(非法功能码)
        92. sdata[1] = data[1] –本机地址
        93. sdata[2] = data[2] 0x80 –异常的时候功能码加0x80
        94. sdata[3] = 0x01 –异常码0x01表示设备不支持此功能码
        95. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
        96. sdata[4] = CRC & 0x00ff –低位在前
        97. sdata[5] = CRC >> 8 –高位在后
        98. LIB_GpioWrite("D2",1) –使能485模块发送
        99. LIB_Uart1BlockSend(sdata)
        100. LIB_GpioWrite("D2",0) –使能485模块接收
        101. end
        102. end
        103. end
        104. end
        105. –开始初始化ShineBlink
        106. –配置Uart1串口波特率为19200 ,接485模块
        107. LIB_Uart1Config("BAUDRATE_19200")
        108. –485发送和接收控制引脚
        109. LIB_GpioOutputConfig("D2","STANDARD")
        110. LIB_GpioWrite("D2",0) –使能485模块接收
        111. –开始大循环
        112. while(GC(1) == true)
        113. do
        114. –Modbus通信处理
        115. ModbusProcess()
        116. end

        复制代码

        四 、Modbus Poll 上位机实验流程
        (1)配置0x03读取保持寄存器功能(Setup)

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        (2)建立Modbus串行通信连接(Connectiong)

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        (3)建立连接后的数据通信
        1. 上位机每秒钟自动下发0x03指令读取设备的起始地址为0x0000的9个保持寄存器的值

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        通信数据日志:

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        上面设备回复的23个字节数据举例说明 :例如:15 03 12 00 06 00 00 00 01 00 00 00 16 00 16 00 00 00 00 00 00 D5 16数据结尾的CRC算法采用Modbus Crc16

        1. 本机地址:0x15
        2. 功能码:0x03
        3. 字节数:18字节(9个16bit无符号寄存器)
        4. 寄存器1:0x0006 表示pm25=6
        5. 寄存器2:0x0000 表示hch0=0
        6. 寄存器3:0x0001 表示tvoc=1
        7. 寄存器4:0x0000 表示mesh=6
        8. 寄存器5:0x0016 表示temprature1=21度
        9. 寄存器6 :0x0016 表示temprature2=21度
        10. 寄存器7:0x0000 表示windspeed=0
        11. 寄存器8:0x0000 表示running=0
        12. 寄存器9:0x0000 表示faultcode=0
        13. CRC_L:0xD5
        14. CRC_H:0x16

        复制代码
        2. 上位机下发开机命令(功能码0x05,向线圈地址为0x0000处写单个线圈值0xFF00)

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        通信数据日志 :

        低代码物联网开发板RS485串口及Modbus范例可接入机智云

        3. 上位机下发停机命令(功能码0x05, 向线圈地址为0x0000处写单个线圈值0x0000)

        上位机发送: 15 05 00 00 00 00 CE DE 设备应回复: 15 05 00 00 00 00 CE DE

        相关新闻

        联系我们
        联系我们
        分享本页
        返回顶部

          XML地图