一、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 - LIB_GpioOutputConfig("D8","STANDARD") --初始化GPIO控制黃色LED1
- LIB_GpioOutputConfig("D2","STANDARD") --初始化GPIO控制Max485 RE DE 收發控制
- --配置Uart1序列槽波特率為19200,用作485通訊
- LIB_Uart1Config("BAUDRATE_19200")
- --使能MAX485發送
- function SendEn()
- LIB_GpioWrite("D2",1)
- end
- --使能MAX485接收
- function RecvEn()
- LIB_GpioWrite("D2",0)
- end
- --使能10毫秒定時器開始工作
- LIB_10msTimerConfig("ENABLE")
- cnt_10ms = 0
- --定義10毫秒定時器的中斷函數
- function LIB_10msTimerCallback()
- cnt_10ms = cnt_10ms + 1
- end
- --開始大循環
- while(GC(1) == true)
- do
- --每1秒發送5位元組資料給PC端
- if cnt_10ms >= 100 then --1000ms
- cnt_10ms = 0
- send_data = {1,2,3,4,5}
- SendEn()
- LIB_Uart1BlockSend(send_data)
- RecvEn()
- end
- --查詢是否收到PC端發來的5位元組資料,并驗證
- recv_flag,recv_data = LIB_Uart1Recv()
- if recv_flag == 1 and #recv_data == 5 then
- 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
- LIB_GpioToggle("D8") --切換LED狀态
- end
- end
- 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主機。 - --程式中用到的全局變量定義
- Pm25Percent = 0
- HchoPercent = 0
- TvocPercent = 0
- MeshPercent = 0.0
- Temprature1 = 0.00
- Temprature2 = 0.00
- Wind485DisSpeed = 0
- DevIsRunning = 0 --控制裝置運作或停止
- FaultCode = 0 --故障代碼
- --ModBus通信函數定義
- function ModbusProcess()
- local sdata = {}
- --查詢是否收到Modbus主機發來的消息
- flag, data = LIB_Uart1Recv()
- if flag == 1 then
- --判斷消息是不是發給本機,是本機的才理會
- if data[1] == PI[2] then --PI[2], Modbus本機位址(1-247)
- --判斷Modbus功能碼
- if data[2] == 0x05 then -- 0x05 寫單個線圈
- --這裡定義線圈位址為0x0000的線圈為開機/關機控制信号
- if data[3] == 0x00 and data[4] == 0x00 then
- if data[5] == 0xff and data[6] == 0x00 then --ON
- DevIsRunning = 1 --置1開機全局變量
- elseif data[5] == 0x00 and data[6] == 0x00 then --OFF
- DevIsRunning = 0 --置0開機全局變量
- else
- --這裡需回複非法資料03異常消息(非法資料值),讀者可自行完成
- end
- --回複OK,把收到的資料原封不動回傳
- LIB_GpioWrite("D2",1) --使能485子產品發送
- LIB_Uart1BlockSend(data)
- LIB_GpioWrite("D2",0) --使能485子產品接收
- else
- --回複異常消息(非法資料位址)
- sdata[1] = data[1] --本機位址
- sdata[2] = data[2]+0x80 --異常的時候功能碼加0x80
- sdata[3] = 0x02 --異常碼0x02表示裝置不支援此資料位址
- CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
- sdata[4] = CRC & 0x00ff --低位在前
- sdata[5] = CRC >> 8 --高位在後
- LIB_GpioWrite("D2",1) --使能485子產品發送
- LIB_Uart1BlockSend(sdata)
- LIB_GpioWrite("D2",0) --使能485子產品接收
- end
- --這裡用0x03而不用0x04是因為很多主機隻支援03 06 16指令,是以就随大流咯
- elseif data[2] == 0x03 then --0x03 讀多個保持寄存器
- --這裡定義起始位址為0x0000的這些寄存器存放傳感器資料,且讀取的寄存器個數必須是9個
- if data[3] == 0x00 and data[4] == 0x00 and data[5] == 0x00 and data[6] == 0x09 then
- sdata[1] = data[1] --本機位址
- sdata[2] = data[2] --功能碼
- sdata[3] = 18 --資料域位元組數: 9個寄存器一共18位元組
- sdata[4] = Pm25Percent >> 8
- sdata[5] = Pm25Percent & 0x00ff
- sdata[6] = HchoPercent >> 8
- sdata[7] = HchoPercent & 0x00ff
- sdata[8] = TvocPercent >> 8
- sdata[9] = TvocPercent & 0x00ff
- sdata[10] = math.floor(MeshPercent) >> 8
- sdata[11] = math.floor(MeshPercent) & 0x00ff
- sdata[12] = math.floor(Temprature1) >> 8
- sdata[13] = math.floor(Temprature1) & 0x00ff
- sdata[14] = math.floor(Temprature2) >> 8
- sdata[15] = math.floor(Temprature2) & 0x00ff
- sdata[16] = Wind485DisSpeed >> 8
- sdata[17] = Wind485DisSpeed & 0x00ff
- sdata[18] = DevIsRunning >> 8
- sdata[19] = DevIsRunning & 0x00ff
- sdata[20] = FaultCode >> 8
- sdata[21] = FaultCode & 0x00ff
- CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
- sdata[22] = CRC & 0x00ff --低位在前
- sdata[23] = CRC >> 8 --高位在後
- --回複傳感器資料
- LIB_GpioWrite("D2",1) --使能485子產品發送
- LIB_Uart1BlockSend(sdata)
- LIB_GpioWrite("D2",0) --使能485子產品接收
- else
- --回複異常消息(非法資料位址)
- sdata[1] = data[1] --本機位址
- sdata[2] = data[2]+0x80 --異常的時候功能碼加0x80
- sdata[3] = 0x02 --異常碼0x02表示裝置不支援此資料位址
- CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
- sdata[4] = CRC & 0x00ff --低位在前
- sdata[5] = CRC >> 8 --高位在後
- LIB_GpioWrite("D2",1) --使能485子產品發送
- LIB_Uart1BlockSend(sdata)
- LIB_GpioWrite("D2",0) --使能485子產品接收
- end
- else
- --回複異常消息(非法功能碼)
- sdata[1] = data[1] --本機位址
- sdata[2] = data[2]+0x80 --異常的時候功能碼加0x80
- sdata[3] = 0x01 --異常碼0x01表示裝置不支援此功能碼
- CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
- sdata[4] = CRC & 0x00ff --低位在前
- sdata[5] = CRC >> 8 --高位在後
- LIB_GpioWrite("D2",1) --使能485子產品發送
- LIB_Uart1BlockSend(sdata)
- LIB_GpioWrite("D2",0) --使能485子產品接收
- end
- end
- end
- end
-
- --開始初始化ShineBlink
- --配置Uart1序列槽波特率為19200,接485子產品
- LIB_Uart1Config("BAUDRATE_19200")
- --485發送和接收控制引腳
- LIB_GpioOutputConfig("D2","STANDARD")
- LIB_GpioWrite("D2",0) --使能485子產品接收
-
- --開始大循環
- while(GC(1) == true)
- do
- --Modbus通信處理
- ModbusProcess()
- 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 D5 16資料結尾的CRC算法采用Modbus Crc16 - 本機位址:0x15
- 功能碼:0x03
- 位元組數:18位元組(9個16bit無符号寄存器)
- 寄存器1:0x0006 表示pm25=6
- 寄存器2:0x0000 表示hch0=0
- 寄存器3:0x0001 表示tvoc=1
- 寄存器4:0x0000 表示mesh=6
- 寄存器5:0x0016 表示temprature1=21度
- 寄存器6:0x0016 表示temprature2=21度
- 寄存器7:0x0000 表示windspeed=0
- 寄存器8:0x0000 表示running=0
- 寄存器9:0x0000 表示faultcode=0
- CRC_L:0xD5
- 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 |