欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語(yǔ)言rs485,Go語(yǔ)言之父

RS485和MODBUS的區(qū)別

RS485是一個(gè)物理接口,簡(jiǎn)單的說(shuō)是硬件。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、賓縣ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的賓縣網(wǎng)站制作公司

MODBUS是一種國(guó)際標(biāo)準(zhǔn)的通訊協(xié)議,用于不同廠商之間的設(shè)備交換數(shù)據(jù)(一般是工業(yè)用途);

所謂協(xié)議,也可以理解為上面有人說(shuō)的“語(yǔ)言”吧,簡(jiǎn)單的說(shuō)是軟件。

一般情況下,兩臺(tái)設(shè)備通過(guò)MODBUS協(xié)議傳輸數(shù)據(jù):

最早是用RS232C作為硬件接口,(也就是普通電腦上的串行通訊口(串口));

也有用RS422的,也有常用的RS485,這種接口傳輸距離遠(yuǎn),在一般工業(yè)現(xiàn)場(chǎng)用的比較多MODBUS協(xié)議又分MODBUS RTU,MODBUS ASCII和后來(lái)發(fā)展的MODBUS

TCP三種模式:

其中前兩種(MODBUS RTU,MODBUS ASCII)所用的物理硬件接口都是串行(Serial)通訊口(RS232,RS422,RS485)。

而MODBUS TCP則是為了順應(yīng)當(dāng)今世界發(fā)展潮流,什么都可以用Ethernet網(wǎng)或Internet來(lái)連接,傳送數(shù)據(jù)。所以又MODBUS TCP模式,該模式的硬件接口就是以太網(wǎng)(Ethernet)口了,也就是我們電腦上一般用的網(wǎng)絡(luò)口了。

急!請(qǐng)教RS485串口通訊的問(wèn)題

你用vb還是vc?

看OnComm事件應(yīng)該是vb吧。

(參照出處):

MSComm控件使用詳解

摘要:本文詳細(xì)介紹了MSComm控件在串口編程中使用。

目 次

MSComm控件兩種處理通訊的方式

CommPort屬性

RThreshold 屬性

CTSHolding 屬性

SThreshold 屬性

CDHolding 屬性

DSRHolding 屬性

Settings 屬性

InputLen 屬性

EOFEnable 屬性

Handshake 常數(shù)

OnComm 常數(shù)

InputMode 常數(shù)

錯(cuò)誤消息

MSComm 控件通過(guò)串行端口傳輸和接收數(shù)據(jù),為應(yīng)用程序提供串行通訊功能。MSComm控件在串口編程時(shí)非常方便,程序員不必去花時(shí)間去了解較為復(fù)雜的API函數(shù),而且在VC、VB、Delphi等語(yǔ)言中均可使用。 Microsoft Communications Control(以下簡(jiǎn)稱MSComm)是Microsoft公司提供的簡(jiǎn)化Windows下串行通信編程的ActiveX控件,它為應(yīng)用程序提供了通過(guò)串行接口收發(fā)數(shù)據(jù)的簡(jiǎn)便方法。具體的來(lái)說(shuō),它提供了兩種處理通信問(wèn)題的方法:一是事件驅(qū)動(dòng)(Event-driven)方法,一是查詢法。

1.MSComm控件兩種處理通訊的方式

MSComm控件提供下列兩種處理通訊的方式:事件驅(qū)動(dòng)方式和查詢方式。

1.1 事件驅(qū)動(dòng)方式

事件驅(qū)動(dòng)通訊是處理串行端口交互作用的一種非常有效的方法。在許多情況下,在事件發(fā)生時(shí)需要得到通知,例如,在串口接收緩沖區(qū)中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 線上一個(gè)字符到達(dá)或一個(gè)變化發(fā)生時(shí)。在這些情況下,可以利用 MSComm 控件的 OnComm 事件捕獲并處理這些通訊事件。OnComm 事件還可以檢查和處理通訊錯(cuò)誤。所有通訊事件和通訊錯(cuò)誤的列表,參閱 CommEvent 屬性。在編程過(guò)程中,就可以在OnComm事件處理函數(shù)中加入自己的處理代碼。這種方法的優(yōu)點(diǎn)是程序響應(yīng)及時(shí),可靠性高。每個(gè)MSComm 控件對(duì)應(yīng)著一個(gè)串行端口。如果應(yīng)用程序需要訪問(wèn)多個(gè)串行端口,必須使用多個(gè) MSComm 控件。

1.2 查詢方式

查詢方式實(shí)質(zhì)上還是事件驅(qū)動(dòng),但在有些情況下,這種方式顯得更為便捷。在程序的每個(gè)關(guān)鍵功能之后,可以通過(guò)檢查 CommEvent 屬性的值來(lái)查詢事件和錯(cuò)誤。如果應(yīng)用程序較小,并且是自保持的,這種方法可能是更可取的。例如,如果寫一個(gè)簡(jiǎn)單的電話撥號(hào)程序,則沒(méi)有必要對(duì)每接收一個(gè)字符都產(chǎn)生事件,因?yàn)槲ㄒ坏却邮盏淖址钦{(diào)制解調(diào)器的“確定”響應(yīng)。

2.MSComm 控件的常用屬性

MSComm 控件有很多重要的屬性,但首先必須熟悉幾個(gè)屬性。

CommPort 設(shè)置并返回通訊端口號(hào)。

Settings 以字符串的形式設(shè)置并返回波特率、奇偶校驗(yàn)、數(shù)據(jù)位、停止位。

PortOpen 設(shè)置并返回通訊端口的狀態(tài)。也可以打開(kāi)和關(guān)閉端口。

Input 從接收緩沖區(qū)返回和刪除字符。

Output 向傳輸緩沖區(qū)寫一個(gè)字符串。

下面分別描述:

CommPort屬性 設(shè)置并返回通訊端口號(hào)。

語(yǔ)法 object.CommPort[value ] (value 一整型值,說(shuō)明端口號(hào)。)

說(shuō)明 在設(shè)計(jì)時(shí),value 可以設(shè)置成從 1 到 16 的任何數(shù)(缺省值為 1)。但是如果用 PortOpen 屬性打開(kāi)一個(gè)并不存在的端口時(shí),MSComm 控件會(huì)產(chǎn)生錯(cuò)誤 68(設(shè)備無(wú)效)。

注意:必須在打開(kāi)端口之前設(shè)置 CommPort 屬性。

RThreshold 屬性:在 MSComm 控件設(shè)置 CommEvent 屬性為 comEvReceive 并產(chǎn)生 OnComm 之前,設(shè)置并返回的要接收的字符數(shù)。

語(yǔ)法 object.Rthreshold [ = value ](value 整型表達(dá)式,說(shuō)明在產(chǎn)生 OnComm 事件之前要接收的字符數(shù)。 )

說(shuō)明 當(dāng)接收字符后,若 Rthreshold 屬性設(shè)置為 0(缺省值)則不產(chǎn)生 OnComm 事件。例如,設(shè)置 Rthreshold 為 1,接收緩沖區(qū)收到每一個(gè)字符都會(huì)使 MSComm 控件產(chǎn)生 OnComm 事件。

CTSHolding 屬性:確定是否可通過(guò)查詢 Clear To Send (CTS) 線的狀態(tài)發(fā)送數(shù)據(jù)。Clear To Send 是調(diào)制解調(diào)器發(fā)送到相聯(lián)計(jì)算機(jī)的信號(hào),指示傳輸可以進(jìn)行。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。

語(yǔ)法: object.CTSHolding(Boolean)

Mscomm 控件的 CTSHolding 屬性設(shè)置值:

True Clear To Send 線為高電平。

False Clear To Send 線為低電平。

說(shuō)明:如果 Clear To Send 線為低電平 (CTSHolding = False) 并且超時(shí)時(shí),MSComm 控件設(shè)置 CommEvent 屬性為 comEventCTSTO (Clear To Send Timeout) 并產(chǎn)生 OnComm 事件。

Clear To Send 線用于 RTS/CTS (Request To Send/Clear To Send) 硬件握手。如果需要確定 Clear To Send 線的狀態(tài),CTSHolding 屬性給出一種手工查詢的方法。

詳細(xì)信息 有關(guān)握手協(xié)議,請(qǐng)參閱 Handshaking 屬性。

SThreshold 屬性: MSComm 控件設(shè)置 CommEvent 屬性為 comEvSend 并產(chǎn)生 OnComm 事件之前,設(shè)置并返回傳輸緩沖區(qū)中允許的最小字符數(shù)。

語(yǔ)法 object.SThreshold [ = value ]

value 整形表達(dá)式,代表在 OnComm 事件產(chǎn)生之前在傳輸緩沖區(qū)中的最小字符數(shù)。

說(shuō)明:若設(shè)置 Sthreshold 屬性為 0(缺省值),數(shù)據(jù)傳輸事件不會(huì)產(chǎn)生 OnComm 事件。若設(shè)置 Sthreshold 屬性為 1,當(dāng)傳輸緩沖區(qū)完全空時(shí),MSComm 控件產(chǎn)生 OnComm 事件。如果在傳輸緩沖區(qū)中的字符數(shù)小于 value,CommEvent 屬性設(shè)置為 comEvSend,并產(chǎn)生 OnComm 事件。comEvSend 事件僅當(dāng)字符數(shù)與 Sthreshold 交叉時(shí)被激活一次。例如,如果 Sthreshold 等于 5,僅當(dāng)在輸出隊(duì)列中字符數(shù)從 5 降到 4 時(shí),comEvSend 才發(fā)生。如果在輸出隊(duì)列中從沒(méi)有比 Sthreshold 多的字符,comEvSend 事件將絕不會(huì)發(fā)生。

Handshake 常數(shù)

常數(shù) 值 描述

comNone 0 無(wú)握手。

comXonXoff 1 XOn/Xoff 握手。

comRTS 2 Request-to-send/clear-to-send 握手。

comRTSXOnXOff 3 Request-to-send 和 clear-to-send 握手皆可。

OnComm 常數(shù)

常數(shù) 值 描述

comEvSend 1 發(fā)送事件。

comEvReceive 2 接收事件。

comEvCTS 3 clear-to-send 線變化。

comEvDSR 4 data-set ready 線變化。

comEvCD 5 carrier detect 線變化。

comEvRing 6 振鈴檢測(cè)。

comEvEOF 7 文件結(jié)束。

Error 常數(shù)

常數(shù) 值 描述

comEventBreak 1001 接收到中斷信號(hào)

comEventCTSTO 1002 Clear-to-send 超時(shí)

comEventDSRTO 1003 Data-set ready 超時(shí)

comEventFrame 1004 幀錯(cuò)誤

comEventOverrun 1006 端口超速

comEventCDTO 1007 Carrier detect 超時(shí)

comEventRxOver 1008 接收緩沖區(qū)溢出

comEventRxParity 1009 Parity 錯(cuò)誤

comEventTxFull 1010 傳輸緩沖區(qū)滿

comEventDCB 1011 檢索端口 設(shè)備控制塊 (DCB) 時(shí)的意外錯(cuò)誤

InputMode 常數(shù)

常數(shù) 值 描述

comInputModeText 0 (缺?。┩ㄟ^(guò) Input 屬性以文本方式取回?cái)?shù)據(jù)。

comInputModeBinary 1 通過(guò) Input 屬性以二進(jìn)制方式檢取回?cái)?shù)據(jù)。

CDHolding 屬性:通過(guò)查詢 Carrier Detect (CD) 線的狀態(tài)確定當(dāng)前是否有傳輸。Carrier Detect 是從調(diào)制解調(diào)器發(fā)送到相聯(lián)計(jì)算機(jī)的一個(gè)信號(hào),指示調(diào)制解調(diào)器正在聯(lián)機(jī)。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。

語(yǔ)法 object.CDHolding

設(shè)置值:CDHolding 屬性的設(shè)置值為:

設(shè)置 描述

True Carrier Detect 線為高電平

False Carrier Detect 線為低電平

說(shuō)明:注意當(dāng) Carrier Detect 線為高電平 (CDHolding = True) 且超時(shí)時(shí),MSComm 控件設(shè)置CommEvent 屬性為 comEventCDTO(Carrier Detect 超時(shí)錯(cuò)誤),并產(chǎn)生 OnComm 事件。

注意 在主機(jī)應(yīng)用程序中捕獲一個(gè)丟失的傳輸是特別重要的,例如一個(gè)公告板,因?yàn)楹艚姓呖梢噪S時(shí)掛起(放棄傳輸)。

Carrier Detect 也被稱為 Receive Line Signal Detect (RLSD)。

數(shù)據(jù)類型 Boolean

DSRHolding 屬性:確定 Data Set Ready (DSR) 線的狀態(tài)。Data Set Ready 信號(hào)由調(diào)制解調(diào)器發(fā)送到相連計(jì)算機(jī),指示作好操作準(zhǔn)備。該屬性在設(shè)計(jì)時(shí)無(wú)效,在運(yùn)行時(shí)為只讀。

語(yǔ)法:object.DSRHolding

object 所在處表示對(duì)象表達(dá)式,其值是“應(yīng)用于”列表中的對(duì)象。

DSRHolding 屬性返回以下值:

值 描述

True Data Set Ready 線高

False Data Set Ready 線低

說(shuō)明:當(dāng) Data Set Ready 線為高電平 (DSRHolding = True) 且超時(shí)時(shí),MSComm 控件設(shè)置 CommEvent 屬性為 comEventDSRTO(數(shù)據(jù)準(zhǔn)備超時(shí))并產(chǎn)生 OnComm 事件。

當(dāng)為 Data Terminal Equipment (DTE) 機(jī)器寫 Data Set Ready/Data Terminal Ready 握手例程時(shí)該屬性是十分有用的。

數(shù)據(jù)類型:Boolean

Settings 屬性: 設(shè)置并返回波特率、奇偶校驗(yàn)、數(shù)據(jù)位、停止位參數(shù)。

語(yǔ)法: object.Settings[ = value]

說(shuō)明:當(dāng)端口打開(kāi)時(shí),如果 value 非法,則 MSComm 控件產(chǎn)生錯(cuò)誤 380(非法屬性值)。

Value 由四個(gè)設(shè)置值組成,有如下的格式:

"BBBB,P,D,S"

BBBB 為波特率,P 為奇偶校驗(yàn),D 為數(shù)據(jù)位數(shù),S 為停止位數(shù)。value 的缺省值是:

"9600,N,8,1"

InputLen 屬性:設(shè)置并返回 Input 屬性從接收緩沖區(qū)讀取的字符數(shù)。

語(yǔ)法 object.InputLen [ = value]

InputLen 屬性語(yǔ)法包括下列部分:

value 整型表達(dá)式,說(shuō)明 Input 屬性從接收緩沖區(qū)中讀取的字符數(shù)。

說(shuō)明:InputLen 屬性的缺省值是 0。設(shè)置 InputLen 為 0 時(shí),使用 Input 將使 MSComm 控件讀取接收緩沖區(qū)中全部的內(nèi)容。

若接收緩沖區(qū)中 InputLen 字符無(wú)效,Input 屬性返回一個(gè)零長(zhǎng)度字符串 ("")。在使用 Input 前,用戶可以選擇檢查 InBufferCount 屬性來(lái)確定緩沖區(qū)中是否已有需要數(shù)目的字符。該屬性在從輸出格式為定長(zhǎng)數(shù)據(jù)的機(jī)器讀取數(shù)據(jù)時(shí)非常有用。

EOFEnable 屬性:確定在輸入過(guò)程中 MSComm 控件是否尋找文件結(jié)尾 (EOF) 字符。如果找到 EOF 字符,將停止輸入并激活 OnComm 事件,此時(shí) CommEvent 屬性設(shè)置為 comEvEOF,

語(yǔ)法:object.EOFEnable [ = value ]

EOFEnable 屬性語(yǔ)法包括下列部分:

value 布爾表達(dá)式,確定當(dāng)找到 EOF 字符時(shí),OnComm 事件是否被激活,如“設(shè)置值”中所描述。

value 的設(shè)置值:

True 當(dāng) EOF 字符找到時(shí) OnComm 事件被激活。

False (缺?。┊?dāng) EOF 字符找到時(shí) OnComm 事件不被激活。

說(shuō)明:當(dāng) EOFEnable 屬性設(shè)置為 False,OnComm 控件將不在輸入流中尋找 EOF 字符。

錯(cuò)誤消息(MS Comm 控件)

下表列出 MSComm 控件可以捕獲的錯(cuò)誤:

值 描述

380 無(wú)效屬性值 comInvalidPropertyValue

383 屬性為只讀 comSetNotSupported

394 屬性為只讀 comGetNotSupported

8000 端口打開(kāi)時(shí)操作不合法 comPortOpen

8001 超時(shí)值必須大于 0

8002 無(wú)效端口號(hào) comPortInvalid

8003 屬性只在運(yùn)行時(shí)有效

8004 屬性在運(yùn)行時(shí)為只讀

8005 端口已經(jīng)打開(kāi) comPortAlreadyOpen

8006 設(shè)備標(biāo)識(shí)符無(wú)效或不支持該標(biāo)識(shí)符

8007 不支持設(shè)備的波特率

8008 指定的字節(jié)大小無(wú)效

8009 缺省參數(shù)錯(cuò)誤

8010 硬件不可用(被其它設(shè)備鎖定)

8011 函數(shù)不能分配隊(duì)列

8012 設(shè)備沒(méi)有打開(kāi) comNoOpen

8013 設(shè)備已經(jīng)打開(kāi)

8014 不能使用 comm 通知

8015 不能設(shè)置 comm 狀態(tài) comSetCommStateFailed

8016 不能設(shè)置 comm 事件屏蔽

8018 僅當(dāng)端口打開(kāi)時(shí)操作才有效 comPortNotOpen

8019 設(shè)備忙

8020 讀 comm 設(shè)備錯(cuò)誤 comReadError

8021 為該端口檢索設(shè)備控制塊時(shí)的內(nèi)部錯(cuò)誤 comDCBError

///-----------------------------------------------------

串口數(shù)據(jù)接收方式

1、 在OnComm 事件中接收數(shù)據(jù):

這種方式能充分MSCOMM控件的特性。OnComm 事件還可以檢查和處理通訊錯(cuò)誤;可以通過(guò)檢查 CommEvent 屬性的值來(lái)查詢事件和錯(cuò)誤;對(duì)于不定長(zhǎng)數(shù)據(jù)以及對(duì)數(shù)據(jù)進(jìn)行處理比較復(fù)雜的情況,此法不是很方便。

Private Sub MSComm_OnComm ()

Select Case MSComm1.CommEvent

' 錯(cuò)誤

Case comEventBreak ' 收到 Break。

Case comEventCDTO ' CD (RLSD) 超時(shí)。

Case comEventCTSTO ' CTS Timeout。

Case comEventDSRTO ' DSR Timeout。

Case comEventFrame ' Framing Error

Case comEventOverrun '數(shù)據(jù)丟失。

Case comEventRxOver'接收緩沖區(qū)溢出。

Case comEventRxParity' Parity 錯(cuò)誤。

Case comEventTxFull '傳輸緩沖區(qū)已滿。

Case comEventDCB '獲取 DCB] 時(shí)意外錯(cuò)誤

' 事件

Case comEvCD ' CD 線狀態(tài)變化。

Case comEvCTS ' CTS 線狀態(tài)變化。

Case comEvDSR ' DSR 線狀態(tài)變化。

Case comEvRing ' Ring Indicator 變化。

Case comEvReceive ' 收到 RThreshold # of chars.

Case comEvSend ' 傳輸緩沖區(qū)有 Sthreshold 個(gè)字符 '

Case comEvEof ' 輸入數(shù)據(jù)流中發(fā)現(xiàn) EOF 字符

End Select

End Sub

2.輪循法采集數(shù)據(jù):

A、定時(shí)器輪循法

對(duì)于數(shù)據(jù)包方式收發(fā)數(shù)據(jù)以及不需即時(shí)響應(yīng)情況,用輪循法更好些。實(shí)際上輪循法最大的好處在于集中處理數(shù)據(jù)而且不太占用CPU。輪循法要注意定時(shí)采集的時(shí)間片段大?。贿@里用二進(jìn)制收發(fā)模式;使屬性RThreshold、SThreshold為0,屏蔽ONCOMM事件。

InputMode = comInputModeBinary

RThreshold = 0

SThreshold = 0

Private Sub TmrComm_Timer()

'采用輪循法采集數(shù)據(jù)

Dim Rx_buff() As Byte

Dim okstring As String

Dim ReceivedLen As Integer

On Error GoTo ErrorHandler

TmrComm.Enabled = False '關(guān)閉定時(shí)器

If commport.InBufferCount 0 Then

ReceivedLen = commport.InBufferCount

Rx_buff = commport.Input

okstring = StrConv(tempbyte, vbUnicode)

If ReceivedLen = 6 Then

If Chr(tempbyte(0)) = ":" And tempbyte(3) = h0a Then

....

End If

If Instr(okstring ,":@END*",vbBinaryCompare) Then

....

End If

End If

TmrComm.Enabled = True '打開(kāi)定時(shí)器

End Sub

B、直接輪循法

此法用于接收少量控制命令字;

' 保存輸入子串的緩沖區(qū)

Dim Instring As String

' 使用 COM1。

MSComm1.CommPort = 1

' 9600 波特,無(wú)奇偶校驗(yàn),8 位數(shù)據(jù),一個(gè)停止位。

MSComm1.Settings = "9600,N,8,1"

' 當(dāng)輸入占用時(shí),

' 告訴控件讀入整個(gè)緩沖區(qū)。

MSComm1.InputLen = 0

' 打開(kāi)端口。

MSComm1.PortOpen = True

' 將 attention 命令送到調(diào)制解調(diào)器。

MSComm1.Output = "ATV1Q0" Chr$(13)

' 確保

' 調(diào)制解調(diào)器以"OK"響應(yīng)。

' 等待數(shù)據(jù)返回到串行端口。

Do

DoEvents

Buffer$ = Buffer$ MSComm1.Input

Loop Until InStr(Buffer$, "OK" vbCRLF)

' 從串行端口讀 "OK" 響應(yīng)。

' 關(guān)閉串行端口。

MSComm1.PortOpen = False

如何處理不定長(zhǎng)數(shù)據(jù)的接收

在處理串口通訊時(shí),經(jīng)常會(huì)遇到不定長(zhǎng)數(shù)據(jù)的接收。由于通訊任務(wù)不同及編程要求的差異所以采用的方法也有所不同。本文就此問(wèn)題進(jìn)行探討。不定長(zhǎng)數(shù)據(jù)從數(shù)據(jù)格式上分,可分為有格式和無(wú)格式。

一、無(wú)格式不定長(zhǎng)數(shù)據(jù)的接收

這種格式在實(shí)際串口通訊中用得不多,一般只用傳送字符串?dāng)?shù)據(jù)。問(wèn)題在于怎么判斷接收結(jié)束。一般用時(shí)間延遲的方法解決。

A、對(duì)于非握手式通訊,可用一個(gè)定時(shí)器定時(shí)輪循接收,并假定每個(gè)輪循接收完成。用ONCOMM事件接收也可,只是不如定時(shí)器定時(shí)輪循接收簡(jiǎn)便。

B、對(duì)于握手方式通訊,可用直接輪循法提高接收的準(zhǔn)確性。下面是實(shí)現(xiàn)此法的函數(shù):

Function sComm(sCommand As String, comReceive As MSComm) As String

Dim nReceiveCount As Integer

If comReceive.PortOpen = False Then

comReceive.PortOpen = True

End If

comReceive.Output = sCommand

Do

nReceiveCount = comReceive.InBufferCount

sleep (2) 'API 函數(shù),掛起當(dāng)前進(jìn)程一段時(shí)間

Loop Until comReceive.InBufferCount = nReceiveCount

If comReceive.PortOpen = True Then

sComm = comReceive.Input

End If

End Function

注:此函數(shù)參照了xth一文。

此法一般是能確保數(shù)據(jù)接收的正確,但由于WINDOWS是多任務(wù)操作系統(tǒng),當(dāng)有耗時(shí)的進(jìn)程運(yùn)行時(shí)會(huì)丟失數(shù)據(jù)。如果系統(tǒng)會(huì)出現(xiàn)這種情況,可增大函數(shù)sleep()的參數(shù)值。

二、不定長(zhǎng)格式數(shù)據(jù)的接收

對(duì)于不定長(zhǎng)數(shù)據(jù)接收最好的方法是制定通訊協(xié)議,比如定義開(kāi)始字符和結(jié)束字符。由于單片機(jī)系統(tǒng)通訊一般不太復(fù)雜,沒(méi)必要去制定一套象通用計(jì)算機(jī)間通訊的協(xié)議,而根據(jù)單片機(jī)系統(tǒng)的大小和性能要求制定通訊協(xié)議。實(shí)際上為便于交流、維護(hù)以及一致性,可制定一套可伸縮的通訊協(xié)議。定義了開(kāi)始字符和結(jié)束字符就容易實(shí)現(xiàn)不定長(zhǎng)格式數(shù)據(jù)通訊,但在實(shí)際通訊編程還是容易出現(xiàn)一些比較隱蔽的通訊錯(cuò)誤。下面就常用方法分別進(jìn)行分析。

A、定時(shí)器輪循法。

假定每個(gè)輪循期數(shù)據(jù)接收完畢,并在每個(gè)輪循期處理數(shù)據(jù),由于有開(kāi)始字符和結(jié)束字符很容易確定接收數(shù)據(jù)的完整性。好象合理設(shè)定輪循時(shí)間值就萬(wàn)無(wú)一失了,但被動(dòng)接收數(shù)據(jù)時(shí)無(wú)論如何也找不合適的輪循時(shí)間值,因?yàn)閱?dòng)定時(shí)器和數(shù)據(jù)到來(lái)基本不同步,這就會(huì)出現(xiàn)一次發(fā)送的數(shù)據(jù)被分在兩個(gè)輪循期接收,所以被動(dòng)接收數(shù)據(jù)時(shí)不能假定每個(gè)輪循期數(shù)據(jù)接收完畢。在接收到結(jié)束字符后才確定一次數(shù)據(jù)接收完畢就可解決此問(wèn)題。

B、OnComm事件法。

方法和定時(shí)器輪循法基本相同,因?yàn)槊看蜲nCommg事件也只能接收到一部分?jǐn)?shù)據(jù)。在VB的在線幫助中這樣注解“設(shè)置 Rthreshold 為 1,接收緩沖區(qū)收到每一個(gè)字符都會(huì)使 MSComm 控件產(chǎn)生 OnComm 事件?!薄5珜?shí)際上OnComm事件并不是每收到一個(gè)字符便觸發(fā)一次 OnComm 事件。OnComm事件是在緩沖區(qū)收到幾個(gè)甚至幾十個(gè)字節(jié)數(shù)據(jù)后才被觸發(fā)的。版主認(rèn)為這是WINDOWS多任務(wù)使操作系統(tǒng)不能實(shí)時(shí)響應(yīng)造成的。如果要在每次OnComm事件接收一個(gè)字符似乎可設(shè)INPUTLEN屬性為1,但實(shí)際行不通。VB在線幫助中“有該屬性在從輸出格式為定長(zhǎng)數(shù)據(jù)的機(jī)器讀取數(shù)據(jù)時(shí)非常有用”的注解,好象在說(shuō)對(duì)定長(zhǎng)字符有效,但版主發(fā)現(xiàn)INPUTLEN設(shè)為16,接收16個(gè)字符定長(zhǎng)數(shù)據(jù)時(shí)卻被當(dāng)作兩次接收了,一次12個(gè),一次4個(gè)。建議在OnComm事件中接收數(shù)據(jù)要定義通訊協(xié)議并檢測(cè)數(shù)據(jù)的完整性。 對(duì)于不定長(zhǎng)格式數(shù)據(jù)的接收程序員更喜歡定時(shí)器輪循法,也許OnComm事件不好控制吧。

對(duì)于不定長(zhǎng)數(shù)據(jù)的接收,最佳方法可能是在OnComm事件中啟動(dòng)定時(shí)器輪循接收,并同時(shí)停止OnComm事件的觸發(fā),接收完畢后或超時(shí)開(kāi)啟OnComm事件。

用字符方式收發(fā)碼值大于127的字符數(shù)據(jù)

VB的通訊控件友好、功能強(qiáng)大,編程速度快是眾人皆知的。加上VB的易學(xué)、易用,快速開(kāi)發(fā)等特點(diǎn),數(shù)據(jù)通訊量不是很大時(shí),在單片機(jī)通訊領(lǐng)域廣泛地使用VB開(kāi)發(fā)PC上層通訊軟件。實(shí)際開(kāi)發(fā)時(shí)會(huì)有不少問(wèn)題,這里就用字符方式收發(fā)碼值大127的字符數(shù)據(jù)進(jìn)行討論。

在實(shí)際開(kāi)發(fā)中經(jīng)常遇到通訊只是用來(lái)發(fā)送一些控制字符命令和少量數(shù)據(jù)。在VB的中文在線幫助中有“若數(shù)據(jù)只用 ANSI 字符集,則用 comInputModeText”的表述。 ANSI字符集是0-127這容易使人誤解為h88也可用“INPUTMIDE=comInputModeText”方式收發(fā)。我剛開(kāi)始用VB編通訊模塊時(shí)就為此迷惑過(guò),網(wǎng)上不少網(wǎng)友也時(shí)常問(wèn)及這種問(wèn)題。實(shí)際上在VB中0-127是可以正常收發(fā)的,大于127即H7F的只有H80和HFF能夠收發(fā),其余ANSI字符都被過(guò)濾為0。由于串口通訊是以字節(jié)收發(fā)的,數(shù)據(jù)如以comInputModeText模式收發(fā)則非字符串?dāng)?shù)據(jù)會(huì)被過(guò)濾。在VB中用“INPUTMIDE = comInputModeBinary” 就可以解決這個(gè)問(wèn)題,只是收發(fā)都必須用動(dòng)態(tài)數(shù)組來(lái)完成。用comInputModeBinary模式編程稍有點(diǎn)復(fù)雜,調(diào)試也不直觀,對(duì)于初學(xué)者不易掌握。另外軟件完成后,在實(shí)際應(yīng)用時(shí)會(huì)增加工程維護(hù)難度,因?yàn)閷?duì)于二進(jìn)制代碼不是易于理解的。比如下端機(jī)發(fā)送現(xiàn)場(chǎng)統(tǒng)計(jì)數(shù)據(jù)233,comInputModeBinary模式下串口監(jiān)測(cè)到“:A H233;",它代表A探針的溫度。一般串口監(jiān)測(cè)軟件要么用ASCII方式顯示,要么用二進(jìn)制方式顯示。用ASCII方式則不能看到H233,而二進(jìn)制方式則示不好理解,如果顯示58 65 233 59,我想沒(méi)有人喜歡這種方式(如果有更好的方式的話)。但如果顯示“:A 2 3 3 ;”不就解決問(wèn)題了!用comInputModeText方式就可完成任務(wù)了,只是多了一段數(shù)據(jù)分離程序。對(duì)于一般通訊要求這種方法不為是一種好方法。由于通訊任務(wù)是多種多樣的,有時(shí)候這種方法就有點(diǎn)力不從心了,如傳送較多的的數(shù)據(jù)時(shí),這會(huì)顯著地增加通訊量,通訊變得復(fù)雜了,對(duì)于單片機(jī)系統(tǒng)就不太合適了;還有一些特殊要求,如數(shù)據(jù)包的識(shí)別符也不適此法,但能確定傳送數(shù)據(jù)碼值范圍也可用此法。下面介紹另一種方法,此法適用比較廣,傳送二進(jìn)制數(shù)據(jù)通訊量增加也不大。

這種方法實(shí)際上很簡(jiǎn)單,實(shí)際運(yùn)用中有不少采用此法。原理是一碼分為二碼。如設(shè)7E為臨界字符,對(duì)于7E則分為7E和0兩個(gè)ASCII碼,依此類推,8F分為7E和11。接收合并時(shí)遇到7E則將7E和后一個(gè)ASCII碼相加為下字符。下面給出C語(yǔ)言函數(shù),VB轉(zhuǎn)換一下便可。

由于C語(yǔ)言不能返回兩個(gè)參數(shù),所以用數(shù)組指針。

void Filt(char code[],char c)

{

if(c=='F')

{

if(code[0]=0X7E)

{

code[1]=code[0]-0X7E;

code[0]=0X7E;

}

else

{

code[1]=0XFF; /*0XFF作為標(biāo)記code[1]不可能產(chǎn)生0XFF*/

}

}

else if(c=='H')

{

if(code[0]!=0X7E)

{

code[1]=0xFE; /*轉(zhuǎn)換完成標(biāo)記*/

}

else

{

if(code[1]==0XFE)

{

code[1]=0XFF; /*接收下一個(gè)碼的標(biāo)記*/

}

else

{

code[0]=code[0]+code[1];

code[1]=0XFE;

}

}

}

發(fā)送時(shí):

char SendChar[2]; /*存儲(chǔ)發(fā)送的值*/

....

SendChar[0]=c; /*c為待發(fā)ASCII碼*/

Filt(SendChar,'F');

if(SendChar(1)==0XFF)

{

..... /*發(fā)送SendChar[0]*/

}

else

{

...... /*發(fā)送SendChar[0],SendChar[1]*/

}

接收時(shí):

char ReceiveChar[2]; /*存儲(chǔ)接收的值*/

.....

ReceiveChar[0]=c0; /*c0接收的ASCII碼*/

Filt(ReceiveChar,'H');

if(ReceiveChar[1]==0xFF)

{

ReceiveChar[1]=c1; /*c1為下一個(gè)*/

Filt(ReceiveChar,'H);

}

else if(ReceiveChar[1]==0xFE)

{

...... /*存儲(chǔ)轉(zhuǎn)換后的ReceiveChar[0]*/

}

以上代碼僅提供一種思路,實(shí)際情況視編程需要而定。

串口通訊問(wèn)答錄

1、Q:各位vb高手:我有一個(gè)問(wèn)題想請(qǐng)教一下。我從COM口用BIN方式接收到數(shù)據(jù)(一串漢字),存入一BYTE數(shù)組,但無(wú)法還原為一串漢字,我認(rèn)為是ANSI和UNICODE的轉(zhuǎn)換,請(qǐng)問(wèn)如何轉(zhuǎn)換。

例:字符串“我”,按BIN方式接收成一BYTE數(shù)組,其值為“206,210”,如用“CHR(206)+CHR(210)”卻無(wú)法得到“我”,實(shí)際上“我”=CHR(-12860)請(qǐng)問(wèn)如何能實(shí)現(xiàn)BYTE數(shù)組(206,210)與字符串“我”之間的轉(zhuǎn)換?萬(wàn)分感謝?。?!

JY

1999.10

A:經(jīng)CHR(206)+CHR(210)轉(zhuǎn)換后實(shí)際上變成了兩個(gè)UNICODE字符,四個(gè)字節(jié)了。漢字的收發(fā)必須用BINARY方式。下面的程序能實(shí)現(xiàn)漢字收發(fā)。

發(fā):

Dim ytemp() As Byte

Dim stemp As String

stemp = "你好!"

ytemp = StrConv(stemp, vbFromUnicode)

Debug.Print UBound(ytemp)

MSComm1.Output = ytemp

收:

Private Sub mscTest_OnComm()

'中文收發(fā)

Dim yTemp() As Byte

Dim stemp As String

Dim i As Integer

If mscTest.InBufferCount 0 Then

i = mscTest.InBufferCount

yTemp = mscTest.Input

stemp = StrConv(yTemp, vbUnicode)

txtTest1.Text = stemp

End If

End Sub

Deson

1999-10-16

--------------------------------------------------------------------------------

2、Q:各位大俠,在下被兩個(gè)問(wèn)題困擾多時(shí),實(shí)在無(wú)法找到答案,請(qǐng)各位多多指教。

1、在用MSCOMM控件設(shè)計(jì)通訊程序時(shí),我始終無(wú)法將ASC碼大于127的值發(fā)送出去,查閱了VB論壇以前的文章,按部就班也不行,部分 VB 程序如下,請(qǐng)指教:

Private Sub OkBtn_Click()

Dim Data() as byte

Dim Temp as variant

redim data(10)

For i = 0 to 10

Data(i) = int(rnd()*256)

next

temp = data

mscomm.output = temp

end Sub

A:接收方式使用了文本方式,用二進(jìn)制方式即可。

go語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的簡(jiǎn)單網(wǎng)關(guān)

網(wǎng)關(guān)=反向代理+負(fù)載均衡+各種策略,技術(shù)實(shí)現(xiàn)也有多種多樣,有基于 nginx 使用 lua 的實(shí)現(xiàn),比如 openresty、kong;也有基于 zuul 的通用網(wǎng)關(guān);還有就是 golang 的網(wǎng)關(guān),比如 tyk。

這篇文章主要是講如何基于 golang 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的網(wǎng)關(guān)。

轉(zhuǎn)自: troy.wang/docs/golang/posts/golang-gateway/

整理:go語(yǔ)言鐘文文檔:

啟動(dòng)兩個(gè)后端 web 服務(wù)(代碼)

這里使用命令行工具進(jìn)行測(cè)試

具體代碼

直接使用基礎(chǔ)庫(kù) httputil 提供的NewSingleHostReverseProxy即可,返回的reverseProxy對(duì)象實(shí)現(xiàn)了serveHttp方法,因此可以直接作為 handler。

具體代碼

director中定義回調(diào)函數(shù),入?yún)?http.Request,決定如何構(gòu)造向后端的請(qǐng)求,比如 host 是否向后傳遞,是否進(jìn)行 url 重寫,對(duì)于 header 的處理,后端 target 的選擇等,都可以在這里完成。

director在這里具體做了:

modifyResponse中定義回調(diào)函數(shù),入?yún)?http.Response,用于修改響應(yīng)的信息,比如響應(yīng)的 Body,響應(yīng)的 Header 等信息。

最終依舊是返回一個(gè)ReverseProxy,然后將這個(gè)對(duì)象作為 handler 傳入即可。

參考 2.2 中的NewSingleHostReverseProxy,只需要實(shí)現(xiàn)一個(gè)類似的、支持多 targets 的方法即可,具體實(shí)現(xiàn)見(jiàn)后面。

作為一個(gè)網(wǎng)關(guān)服務(wù),在上面 2.3 的基礎(chǔ)上,需要支持必要的負(fù)載均衡策略,比如:

隨便 random 一個(gè)整數(shù)作為索引,然后取對(duì)應(yīng)的地址即可,實(shí)現(xiàn)比較簡(jiǎn)單。

具體代碼

使用curIndex進(jìn)行累加計(jì)數(shù),一旦超過(guò) rss 數(shù)組的長(zhǎng)度,則重置。

具體代碼

輪詢帶權(quán)重,如果使用計(jì)數(shù)遞減的方式,如果權(quán)重是5,1,1那么后端 rs 依次為a,a,a,a,a,b,c,a,a,a,a…,其中 a 后端會(huì)瞬間壓力過(guò)大;參考 nginx 內(nèi)部的加權(quán)輪詢,或者應(yīng)該稱之為平滑加權(quán)輪詢,思路是:

后端真實(shí)節(jié)點(diǎn)包含三個(gè)權(quán)重:

操作步驟:

具體代碼

一致性 hash 算法,主要是用于分布式 cache 熱點(diǎn)/命中問(wèn)題;這里用于基于某 key 的 hash 值,路由到固定后端,但是只能是基本滿足流量綁定,一旦后端目標(biāo)節(jié)點(diǎn)故障,會(huì)自動(dòng)平移到環(huán)上最近的那么個(gè)節(jié)點(diǎn)。

實(shí)現(xiàn):

具體代碼

每一種不同的負(fù)載均衡算法,只需要實(shí)現(xiàn)添加以及獲取的接口即可。

然后使用工廠方法,根據(jù)傳入的參數(shù),決定使用哪種負(fù)載均衡策略。

具體代碼

作為網(wǎng)關(guān),中間件必不可少,這類包括請(qǐng)求響應(yīng)的模式,一般稱作洋蔥模式,每一層都是中間件,一層層進(jìn)去,然后一層層出來(lái)。

中間件的實(shí)現(xiàn)一般有兩種,一種是使用數(shù)組,然后配合 index 計(jì)數(shù);一種是鏈?zhǔn)秸{(diào)用。

具體代碼

標(biāo)題名稱:go語(yǔ)言rs485,Go語(yǔ)言之父
當(dāng)前鏈接:http://chinadenli.net/article4/hesgoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作云服務(wù)器、電子商務(wù)、Google網(wǎng)站內(nèi)鏈、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司