① 求:VB 與VB之間使用API通信常式。
訊編程節省了很多時間。在基於對話框的應用中加入一個MSComm控制項非常簡單。只需進行以下操作即可:
打開「Project->Add To Project->Components and Controls->Registered Activex Controls」,然後選擇控制項:Microsoft Communication Control,version 6.0插入到當前的工程中。這樣就將類 CMSComm 的相關文件 mscomm.cpp 和 mscomm.h 一並加入到了工程中。編程時只需將控制項對話中的 MSComm 控制項拖至你的應用對話框中就OK了。
MSComm控制項提供了兩種處理通信的方法:
1.事件驅動通信,是一種功能很強的處理串口活動的方法。例如,當在CD(Carrier Detect)線或RTS(Request To Send)線上有字元到達或發生了改變,在這種情況下,可以使用MSComm控制項的OnComm事件捕獲和處理這些通信事件。OnComm也可以捕獲和處理通信中的錯誤。
2.可以在每個重要的程序功能之後檢查CommEvent屬性的值來檢測事件和通信錯誤。
使用的每個MSComm控制項都與一個串口對應。如果在應用程序中需要訪問多個串口,必須使用多個MSComm控制項,可以在Windows 控制面板中修改串口地址的中斷地址。
MSComm 控制項有很多重要的屬性,
CommPort 屬性 : 設置並返回通訊埠號。
語法 : object.CommPort[value ] (value 一整型值,說明埠號。)
說明 : 在設計時,value 可以設置成從 1 到 16 的任何數(預設值為 1)。但是如果用 PortOpen 屬性打開一個並不存在的埠時,MSComm 控制項會產生錯誤 68(設備無效)。
RThreshold 屬性:在MSComm控制項設置CommEvent屬性為comEReceive並產生 OnComm 之前,設置並返回的要接收的字元數。
語法: object.Rthreshold [ = value ](value 整型表達式,說明在產生 OnComm 事件之前要接收的字元數。 )
說明 :當接收字元後,若 Rthreshold 屬性設置為 0(預設值)則不產生 OnComm 事件。例如,設置 Rthreshold 為 1,接收緩沖區收到每一個字元都會使 MSComm 控制項產生 OnComm 事件。
CTSHolding 屬性:確定是否可通過查詢 Clear To Send (CTS) 線的狀態發送數據。Clear To Send 是數據機發送到相聯計算機的信號,指示傳輸可以進行。該屬性在設計時無效,在運行時為只讀。
語法 : object.CTSHolding(Boolean)
Mscomm 控制項的 CTSHolding 屬性設置值:
1.True Clear To Send 線為高電平。
2.False Clear To Send 線為低電平。
說明:如果 Clear To Send 線為低電平 (CTSHolding = False) 並且超時時,MSComm控制項設置CommEvent屬性為comEventCTSTO(Clear To Send Timeout)並產生OnComm事件。。
Clear To Send 線用於 RTS/CTS (Request To Send/Clear To Send) 硬體握手。如果需要確定 Clear To Send 線的狀態,CTSHolding 屬性給出一種手工查詢的方法。
SThreshold屬性:在MSComm控制項設置CommEvent屬性為comEvSend 並產生 OnComm 事件之前,設置並返回傳輸緩沖區中允許的最小字元數。
語法 : object.SThreshold [ = value ] value整形表達式,代表在 OnComm 事件產生之前在傳輸緩沖區中的最小字元數。
說明:若設置 Sthreshold 屬性為 0(預設值),數據傳輸事件不會產生 OnComm 事件。若設置 Sthreshold 屬性為 1,當傳輸緩沖區完全空時,MSComm 控制項產生 OnComm 事件。如果在傳輸緩沖區中的字元數小於 value,CommEvent 屬性設置為 comEvSend,並產生 OnComm 事件。comEvSend 事件僅當字元數與 Sthreshold 交叉時被激活一次。例如,如果 Sthreshold 等於 5,僅當在輸出隊列中字元數從 5 降到 4 時,comEvSend 才發生。如果在輸出隊列中從沒有比 Sthreshold 多的字元,comEvSend 事件將絕不會發生。
comInputModeText 0 (預設)通過 Input 屬性以文本方式取回數據。
comInputModeBinary 1 通過 Input 屬性以二進制方式檢取回數據。
CDHolding 屬性:通過查詢 Carrier Detect (CD) 線的狀態確定當前是否有傳輸。Carrier Detect 是從數據機發送到相聯計算機的一個信號,指示數據機正在聯機。該屬性在設計時無效,在運行時為只讀。
語法 object.CDHolding
設置值:CDHolding 屬性的設置值為:
設置 描述
True Carrier Detect 線為高電平
False Carrier Detect 線為低電平
說明:注意當 Carrier Detect 線為高電平 (CDHolding = True) 且超時時,MSComm 控制項設置CommEvent 屬性為 comEventCDTO(Carrier Detect 超時錯誤),並產生 OnComm 事件。
在主機應用程序中捕獲一個丟失的傳輸是特別重要的,例如一個公告板,因為呼叫者可以隨時掛起(放棄傳輸)。
Carrier Detect 也被稱為 Receive Line Signal Detect (RLSD)。 數據類型 Boolean
DSRHolding 屬性:確定 Data Set Ready (DSR) 線的狀態。Data Set Ready 信號由數據機發送到相連計算機,指示作好操作準備。該屬性在設計時無效,在運行時為只讀。
語法:object.DSRHolding
object 所在處表示對象表達式,其值是「應用於」列表中的對象。
DSRHolding 屬性返回以下值:
值 描述
True Data Set Ready 線高
False Data Set Ready 線低
說明:當 Data Set Ready 線為高電平 (DSRHolding = True) 且超時時,MSComm 控制項設置 CommEvent 屬性為 comEventDSRTO(數據准備超時)並產生 OnComm 事件。
當為Data Terminal Equipment (DTE) 機器寫 Data set Ready/Data Terminal Ready握手常式時該屬性十分有用。
數據類型:Boolean
Settings 屬性: 設置並返回波特率、奇偶校驗、數據位、停止位參數。
語法: object.Settings[ = value]
說明:當埠打開時,如果 value 非法,則 MSComm 控制項產生錯誤 380(非法屬性值)。
Value 由四個設置值組成,有如下的格式:
"BBBB,P,D,S "
BBBB 為波特率,P為奇偶校驗,D為數據位數,S為停止位數。value 的預設值是: "9600,N,8,1 "
InputLen 屬性:設置並返回 Input 屬性從接收緩沖區讀取的字元數。
語法 : object.InputLen [ = value] InputLen 屬性語法包括下列部分: value 整型表達式,說明 Input 屬性從接收緩沖區中讀取的字元數。
說明:InputLen 屬性的預設值是 0。設置 InputLen 為 0 時,使用 Input 將使 MSComm 控制項讀取接收緩沖區中全部.
CommEvent屬性為通信事件或錯誤返回下列值之一。在該控制項的對象庫中也可以找到這些常量。
常量 值 描述
ComEventBreak 1001 收到了斷開信號
ComEventCTSTO 1002 Clear To Send Timeout。在發送字元時,在系統指定的事1件內,CTS(Clear To Send)線是低電平
ComEventDSRTO 1003 Data Set Ready Timeout。在發送字元時,在系統指定的事件內,DSR(Data Set Ready)線是低電平
ComEventFrame 1004 數據幀錯誤。硬體檢測到一個數據幀錯誤
ComEventOverrun 1006 埠溢出。硬體中的字元尚未讀,下一個字元又到達,並且丟失
ComEventCDTO 1007 Carrier Detect Time。在發送字元時,在系統指定的事件內,CD(Carrier Detect)線是低電平。CD
也稱為RLSD(Receive Line Singal Detect,接收線信號檢測)
ComEventRxOver 1008 接收緩沖區溢出。在接收緩沖區中沒有空間
ComEventRxParity 1009 奇偶校驗錯。硬體檢測到奇偶校驗錯誤7
ComEventTxFull 1010 發送緩沖區滿。在對發送字元排隊時,發送緩沖區滿
ComEventDCB 1011 檢取埠DCB(Device Control Blick)時發生了沒有預料到的錯誤
通信事件包含了下面的設置:
常量 值 描述
ComEvSend 1 發送緩沖區中的字元數比Sthreshold值低
ComEvReceive 2 接收到了Rthreshold個字元。持續產生該事件,直到使用了Input屬性刪除了接收緩沖區中的數據
ComEvCTS 3 CTS(Clear To Send)線改變
ComEvDSR 4 DSR(Data Set Ready)線改變。當DSR從1到0改變時,該事件發生
ComEvCD 5 CD(Carrier Detect)線改變ComEvRing6檢測到響鈴信號。一些URAT(Universal AsynchronousReciver-
-Transmitters,通用非同步收發器)不支持該事件
ComEvEOF 7 收到了EOF字元(ASCII字元26)
Error消息(MSComm控制項)下表列出了MSComm控制項可捕獲的錯誤消息:
常量 值 描述
ComInvalidPropertyValue 380 無效的屬性值
ComSetNotSupported 383 屬性只讀
ComGetNotSupported 394 屬性只讀
ComPortOpen 8000 埠打開時該存在無效
8001 超時設置必須比0值大
ComPortInvalid 8002 無效的埠號
8003 屬性只在運行時有效
8004 屬性在運行時是只讀的
ComPortAleadyOpen 8005 埠已經打開
8006 設備標識符無效或不支持
8007 不支持設備的波特率
8008 指定的位元組大小無效
8009 預設參數錯誤
8010 硬體不可用(被其他設備鎖住)
8011 函數不能分配隊列
ComNoOpen 8012 設備沒有打開
8013 設備已經打開
8014 不能使用通信通知
ComSetCommStateFailed 8015 不能設置通信狀態
8016 不能設置通信事件屏蔽
ComPortNotOpen 8018 該存在只在埠打開是有效
8019 設備忙
ComReadError 8020 通信設備讀錯誤
ComDCBError 8021 檢取埠設備控制塊時出現內部錯誤
搞清楚以上基本屬性後,就可以開始編寫通信許程序了。在VB5.0/6.0中新建一個工程文件。添加Microsoft Comm Control 5.0組
件,在簡體Form1中加入Command命令按鈕並取名為CmdTest,MSComm控制項取名為MSComm1,加入如下程序代碼。
Private Sub cmdTestClick ( ) '打開串口
MSComml.CommPort =2 '設定Com2
If MSComml.PortOpen = False Then
MSComm1.Settings = "9600,n,8,1" '9600波特率,無校驗,8位數據位,1位停止位
MSComm1.PortOpen = True '打開串口
End if
MSComm1.OutBufferCount = 0 '清空發送緩沖區
MSComm1.InBufferCount = 0 '滑空接收緩沖區
'發送字元數據時注意必須用回車符(vbcr)結束
MSComm1.Output="This is a qood book ! " &vbCr
'潑打電話號碼或發送AT命令
MSComm1.Output = "ATDT 05778191898 , & vbCr
'發送字元數組數據時注意ByteArray必須事先定義賦值
Dim ByteArray as byte( )
'定義動態數組
ReDim ByteArray(1)
'重定義數組大小
ByteArray ( 0 ) =0
ByteArray ( 1 ) = 1
MSComm1.Output = ByteArray
End Sub
private Sub MScommEvent( )
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant
MSComm1.InputLen = 0
'接收二進制數據
MSComm1.InputMode= ComInputModeBinary
Buffer=MSComm1.Input
'接收字元數據
MSComm1.InputMode=comInputModeText
Buffer = MSComml.Input
Case else
End Select
End sub
( 程序1)
二、中文Win 95/98下的通信問題與解決方法
1.接收的數據少於發送的數據
如果通過MSComm控制項一次性傳送較多的二進制數據,那麼,很可能收到的數據不足。例如在設置為24oobps傳輸率的情況下,
一次性可以傳輸2048個字元數據 那麼在大多數情況下。一次只能收到1200個字元左右,這址出為新版的MSComm32.OCX中存在一
個影響傳輸二進制數據的臭蟲(bug).注意這不是特性。
32位Windows API函數(以下簡稱API)使用了幾個用COMMTIMEOUTS結構表示的限時變數,WriteTotalTimeOutConstant 即是其
中的一個,它被Windows內部設定為5000(即5秒),這個常量決定了在通信驅動程序停止傳輸之前花費在發送緩沖區中數據的時間
的長短,5秒鍾意味著通信速度為1200bps情況下僅能發送600個字元,24oobps情況下僅能發送1200個左右的字元。事實上,在一個
緩沖區內一次性發送更多的數據是非常可能的。這個bug同樣也能引發問題,甚至在高速串口門通信情況下,即使系統在使用流控
制,無論叢軟體流(Xon/XofI)還是硬體流(CTS/RTS)。假如數據在發送緩沖區中時,流控制停止了傳輸,如果停止時間超過5
秒鍾.則數據就會丟失。在某些環境下,5秒鍾可能相當短.不過也不必擔心, VB 5.0/6.0版本的MSComm控制項有一個新增的重要的
屬性稱為CommID, CommID指的是當串口被打開時,被API所調用的串口句柄或稱標志,這也意味著能利用API介面函數去修改這個
常量。每次串口關閉後,Windows會自動將之恢復為5000,所以,每次打開串口後需要重斬設定以下API聲明,其代碼見下程序。
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Declare Function SetCommTimeouts Lib "Kernel32"
(BYVal hFile As Long, lpComm TimeoutsAs COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "Kernel32"
(ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
Dim timeouts As COMMEOUTS
Dim Ret As Long
If Comm1.PortOpen = False Then
Comm1.PortOpen = True
End if
Ret=GetCommTimeouts ( Comm1.CommID , timeouts )
'Set some default timeouts
timeOuts.ReadIntervalTimeout = 1
timeouts.ReadTotalTimeoutMultiplier =1
timeouts.ReadTotalTimeoutConstant =1
timeouts.WriteTotalTimeoutMultiplier =1
timeouts.WriteTotalTimeoutConstant=
( Comm1.OutBufferSize\Val(Comm1.Settings))*10000+1000
Ret=SetCommTimeouts( Comm1.CommID , timeouts )
( 程序2)
2.如何發送大於128的字元數據
在通信程序中,以單字元方式逐個發送數據時,每一個數據范圍 0-255(即十六進制的00-FF)。在單字元版本的英文Win95或
DOS版的BASIC程序中,只需要將相應的數據轉換成相應的字元發送到通信埠即可。但在中文Win95/98下卻行不通,假設在中文
Win95/98下運行以下程序:
Dim i
For i=0 to 255
MSComm1.Output=chr(i)
Next i
希望在接收端得到預期的0-255之間的數據,結果卻是:前129個數據接收正確,為0-128,後面127個數據為126個0和一個255,
造成這種給果的原因在於中文Windows使用的是雙位元組字元集(DBCS)系統。DBCS系統使用0-128之間的數字表示ASCII字元,大於
128的數字僅作為前導字元,它只是顯示是一個非拉丁語系的字元,而並不代表實際意義。上述程序在調用CHR()函數時用到了
DBCS字元集,岡此產生了此類錯誤。那麼,如何發送人於128的數據呢?答案是使用字元數組,將以上程序改為:
Dim cc(255) As Byte
For i = 0 To 255
cc(i) = i
Next i
MSComm1.Output = cc
Do
DoEvents
Loop Until MSComm1.OutBufferCount = 0
'接收過程 MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant, b1,i
MSComm1.InputMode=comInputModeBinery
MSComm1.InputLen = 0
Buffer = MSComm1.Input
For i=LBound (Buffer) To UBound (Buffer )
Debug.Print Buffer ( i ) ;
Next i
Case . . . . .
3.如何發送0字元(00H,NULL)
在VisuaI C++中使用串口控制項發送0字元有些麻煩,但在VB5.0/6.0中只要注意以下兩點即可:
(1)設置MSComm控制項的屬性 NullDiscard=False;。
(2)使用二進制接收,即用 MSComm1.InputMode=ComInputModeBinary便可以解決問題;
4.如何發送遞中文字元串(DBcS字元)
VB5.0/6.0的各種參考書上均指明MSComm通信控制項不能發送或接收雙位元組字元集系統DBCS)的二進制數據,這對於我國及亞洲一些
使用DBCS字元集的國家不能不說是一大人遺憾。但是我在實踐中發現,用MSComm控制項也可以發送中文字元,具體方法有以下兩種:
(1)直接發送
直接發送即把中文字元等同於英文字元。如:MSComm1.Intput= " 這是一行中文數據!" ,但這種方法發送的中文數據不能太
長,發送緩沖區和接收緩沖區的大小需設定為中文字元的兩倍以上,而且發送與接收系統所處的操作系統版本最好要一致,否則會
出現接收或發送緩沖區溢出之類的錯誤。這種方法時用於一般要求不太高的場合。
(2)間接發送
在發送端將漢字或字元轉換為機器內碼或區位碼數據數組,然後將詠轉換後的數據發送到串口,在接收端接收到數據後,按照
相反的順序得到的數據轉換為相應的漢字或字元,在轉換過程中.要用到位運算,如取得漢字的內碼後需要將高位元組和低位元組分開,
而VB5.0/6.0中並沒有提供此類函數,以下是求整數高、低位元組的函數。
Public Function HiByte(a As Integer )
Dim b
b= a And &HFF00
b = b / 256
If b<0 Then b = b + 256
HiByte = b
End Function
Public Function LowByte(a As Integ`er)
Dim b
b = a And &HFF
LowByte = b
End Function
5.如何用單機進行通信測試
通常在寫好了通信程序後需要兩台PC或一台Pc、一台單片機.將通信口連接後進行測試,但很多時候因條件限制僅有單台PC機,
測試項目很簡單,那麼能否測試呢?當然可以,而且方法也很簡單。對於九針的串口,找一個廢棄的串口滑鼠,剝外滑鼠線,將連
接2、3針的線對接即可;對於25針的串口,找一枚曲別針(最好有塑料外套的)將它扯直,剝削去兩頭的塑料後在兩頭各彎一個圓
圈,中間對忻後直接套接在串口的2、3針上即可。如果但心不夠安全,則可以將5針按地。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
關於mscomm的用法,提高篇......[mgwmj]&;
MSCOMM控制項是個好東西,如果您能夠充分了解他,他會為您衷心的效勞。
大致看了一下下午有關討論MSCOMM的話題,覺得有必要說說我的心得,我一般只做硬體,沒有系統的學過軟體,只是業余時間
學學用用,多少掌握了一點,也在此拿出來玩玩,不知有錯沒有,我可是以為我已經做的很好了^_^
這是一個VB通用串口事件驅動接收程序。一次性接收一個數據包,數據包可以為任意位元組,保證不會丟失一個數據!
Private Sub MSComm_OnComm()
Dim S() As Byte
Dim SS(1024) As Byte
Static N As Long
Static T As Variant
If (MSComm.CommEvent = comEvReceive) Then
S = MSComm.Input '只要有數據就收進來,哪怕只是一個
If (Timer - T > 0.01) Then '間隔10MS以上就認為是一個新的包
text1="" 'text1用於搜集和顯示接收(HEX格式)
N = 0
End If
T = Timer
For i = 0 To UBound(S) '一個數據包可能產生若干個oncomm事件
Text1.Text = Text1.Text & Right("0" & Hex(S(i)) & "H", 3) + " "
SS(N+i)=S(i) '接收數據包緩存於SS()
N=N+UBound(S)
Next i
End If
End Sub
② 請問 使用vb mscomm 握手的代碼應該如何寫
MSComm 作為一個串列通訊控制項為程序員串口通訊編程節省了很多時間。在基於對話框的應用中加入一個MSComm控制項非常簡單。只需進行以下操作即可:
打開「Project->Add To Project->Components and Controls->Registered Activex Controls」,然後選擇控制項:Microsoft Communication Control,version 6.0插入到當前的工程中。這樣就將類 CMSComm 的相關文件 mscomm.cpp 和 mscomm.h 一並加入到了工程中。編程時只需將控制項對話中的 MSComm 控制項拖至你的應用對話框中就OK了。
MSComm控制項提供了兩種處理通信的方法:
1.事件驅動通信,是一種功能很強的處理串口活動的方法。例如,當在CD(Carrier Detect)線或RTS(Request To Send)線上有字元到達或發生了改變,在這種情況下,可以使用MSComm控制項的OnComm事件捕獲和處理這些通信事件。OnComm也可以捕獲和處理通信中的錯誤。
2.可以在每個重要的程序功能之後檢查CommEvent屬性的值來檢測事件和通信錯誤。
使用的每個MSComm控制項都與一個串口對應。如果在應用程序中需要訪問多個串口,必須使用多個MSComm控制項,可以在Windows 控制面板中修改串口地址的中斷地址。
MSComm 控制項有很多重要的屬性,
CommPort 屬性 : 設置並返回通訊埠號。
語法 : object.CommPort[value ] (value 一整型值,說明埠號。)
說明 : 在設計時,value 可以設置成從 1 到 16 的任何數(預設值為 1)。但是如果用 PortOpen 屬性打開一個並不存在的埠時,MSComm 控制項會產生錯誤 68(設備無效)。
RThreshold 屬性:在MSComm控制項設置CommEvent屬性為comEReceive並產生 OnComm 之前,設置並返回的要接收的字元數。
語法: object.Rthreshold [ = value ](value 整型表達式,說明在產生 OnComm 事件之前要接收的字元數。 )
說明 :當接收字元後,若 Rthreshold 屬性設置為 0(預設值)則不產生 OnComm 事件。例如,設置 Rthreshold 為 1,接收緩沖區收到每一個字元都會使 MSComm 控制項產生 OnComm 事件。
CTSHolding 屬性:確定是否可通過查詢 Clear To Send (CTS) 線的狀態發送數據。Clear To Send 是數據機發送到相聯計算機的信號,指示傳輸可以進行。該屬性在設計時無效,在運行時為只讀。
語法 : object.CTSHolding(Boolean)
Mscomm 控制項的 CTSHolding 屬性設置值:
1.True Clear To Send 線為高電平。
2.False Clear To Send 線為低電平。
說明:如果 Clear To Send 線為低電平 (CTSHolding = False) 並且超時時,MSComm控制項設置CommEvent屬性為comEventCTSTO(Clear To Send Timeout)並產生OnComm事件。。
Clear To Send 線用於 RTS/CTS (Request To Send/Clear To Send) 硬體握手。如果需要確定 Clear To Send 線的狀態,CTSHolding 屬性給出一種手工查詢的方法。
SThreshold屬性:在MSComm控制項設置CommEvent屬性為comEvSend 並產生 OnComm 事件之前,設置並返回傳輸緩沖區中允許的最小字元數。
語法 : object.SThreshold [ = value ] value整形表達式,代表在 OnComm 事件產生之前在傳輸緩沖區中的最小字元數。
說明:若設置 Sthreshold 屬性為 0(預設值),數據傳輸事件不會產生 OnComm 事件。若設置 Sthreshold 屬性為 1,當傳輸緩沖區完全空時,MSComm 控制項產生 OnComm 事件。如果在傳輸緩沖區中的字元數小於 value,CommEvent 屬性設置為 comEvSend,並產生 OnComm 事件。comEvSend 事件僅當字元數與 Sthreshold 交叉時被激活一次。例如,如果 Sthreshold 等於 5,僅當在輸出隊列中字元數從 5 降到 4 時,comEvSend 才發生。如果在輸出隊列中從沒有比 Sthreshold 多的字元,comEvSend 事件將絕不會發生。
comInputModeText 0 (預設)通過 Input 屬性以文本方式取回數據。
comInputModeBinary 1 通過 Input 屬性以二進制方式檢取回數據。
CDHolding 屬性:通過查詢 Carrier Detect (CD) 線的狀態確定當前是否有傳輸。Carrier Detect 是從數據機發送到相聯計算機的一個信號,指示數據機正在聯機。該屬性在設計時無效,在運行時為只讀。
語法 object.CDHolding
設置值:CDHolding 屬性的設置值為:
設置 描述
True Carrier Detect 線為高電平
False Carrier Detect 線為低電平
說明:注意當 Carrier Detect 線為高電平 (CDHolding = True) 且超時時,MSComm 控制項設置CommEvent 屬性為 comEventCDTO(Carrier Detect 超時錯誤),並產生 OnComm 事件。
在主機應用程序中捕獲一個丟失的傳輸是特別重要的,例如一個公告板,因為呼叫者可以隨時掛起(放棄傳輸)。
Carrier Detect 也被稱為 Receive Line Signal Detect (RLSD)。 數據類型 Boolean
DSRHolding 屬性:確定 Data Set Ready (DSR) 線的狀態。Data Set Ready 信號由數據機發送到相連計算機,指示作好操作準備。該屬性在設計時無效,在運行時為只讀。
語法:object.DSRHolding
object 所在處表示對象表達式,其值是「應用於」列表中的對象。
DSRHolding 屬性返回以下值:
值 描述
True Data Set Ready 線高
False Data Set Ready 線低
說明:當 Data Set Ready 線為高電平 (DSRHolding = True) 且超時時,MSComm 控制項設置 CommEvent 屬性為 comEventDSRTO(數據准備超時)並產生 OnComm 事件。
當為Data Terminal Equipment (DTE) 機器寫 Data set Ready/Data Terminal Ready握手常式時該屬性十分有用。
數據類型:Boolean
Settings 屬性: 設置並返回波特率、奇偶校驗、數據位、停止位參數。
語法: object.Settings[ = value]
說明:當埠打開時,如果 value 非法,則 MSComm 控制項產生錯誤 380(非法屬性值)。
Value 由四個設置值組成,有如下的格式:
"BBBB,P,D,S "
BBBB 為波特率,P為奇偶校驗,D為數據位數,S為停止位數。value 的預設值是: "9600,N,8,1 "
InputLen 屬性:設置並返回 Input 屬性從接收緩沖區讀取的字元數。
語法 : object.InputLen [ = value] InputLen 屬性語法包括下列部分: value 整型表達式,說明 Input 屬性從接收緩沖區中讀取的字元數。
說明:InputLen 屬性的預設值是 0。設置 InputLen 為 0 時,使用 Input 將使 MSComm 控制項讀取接收緩沖區中全部.
CommEvent屬性為通信事件或錯誤返回下列值之一。在該控制項的對象庫中也可以找到這些常量。
常量 值 描述
ComEventBreak 1001 收到了斷開信號
ComEventCTSTO 1002 Clear To Send Timeout。在發送字元時,在系統指定的事1件內,CTS(Clear To Send)線是低電平
ComEventDSRTO 1003 Data Set Ready Timeout。在發送字元時,在系統指定的事件內,DSR(Data Set Ready)線是低電平
ComEventFrame 1004 數據幀錯誤。硬體檢測到一個數據幀錯誤
ComEventOverrun 1006 埠溢出。硬體中的字元尚未讀,下一個字元又到達,並且丟失
ComEventCDTO 1007 Carrier Detect Time。在發送字元時,在系統指定的事件內,CD(Carrier Detect)線是低電平。CD
也稱為RLSD(Receive Line Singal Detect,接收線信號檢測)
ComEventRxOver 1008 接收緩沖區溢出。在接收緩沖區中沒有空間
ComEventRxParity 1009 奇偶校驗錯。硬體檢測到奇偶校驗錯誤7
ComEventTxFull 1010 發送緩沖區滿。在對發送字元排隊時,發送緩沖區滿
ComEventDCB 1011 檢取埠DCB(Device Control Blick)時發生了沒有預料到的錯誤
通信事件包含了下面的設置:
常量 值 描述
ComEvSend 1 發送緩沖區中的字元數比Sthreshold值低
ComEvReceive 2 接收到了Rthreshold個字元。持續產生該事件,直到使用了Input屬性刪除了接收緩沖區中的數據
ComEvCTS 3 CTS(Clear To Send)線改變
ComEvDSR 4 DSR(Data Set Ready)線改變。當DSR從1到0改變時,該事件發生
ComEvCD 5 CD(Carrier Detect)線改變ComEvRing6檢測到響鈴信號。一些URAT(Universal AsynchronousReciver-
-Transmitters,通用非同步收發器)不支持該事件
ComEvEOF 7 收到了EOF字元(ASCII字元26)
Error消息(MSComm控制項)下表列出了MSComm控制項可捕獲的錯誤消息:
常量 值 描述
ComInvalidPropertyValue 380 無效的屬性值
ComSetNotSupported 383 屬性只讀
ComGetNotSupported 394 屬性只讀
ComPortOpen 8000 埠打開時該存在無效
8001 超時設置必須比0值大
ComPortInvalid 8002 無效的埠號
8003 屬性只在運行時有效
8004 屬性在運行時是只讀的
ComPortAleadyOpen 8005 埠已經打開
8006 設備標識符無效或不支持
8007 不支持設備的波特率
8008 指定的位元組大小無效
8009 預設參數錯誤
8010 硬體不可用(被其他設備鎖住)
8011 函數不能分配隊列
ComNoOpen 8012 設備沒有打開
8013 設備已經打開
8014 不能使用通信通知
ComSetCommStateFailed 8015 不能設置通信狀態
8016 不能設置通信事件屏蔽
ComPortNotOpen 8018 該存在只在埠打開是有效
8019 設備忙
ComReadError 8020 通信設備讀錯誤
ComDCBError 8021 檢取埠設備控制塊時出現內部錯誤
搞清楚以上基本屬性後,就可以開始編寫通信許程序了。在VB5.0/6.0中新建一個工程文件。添加Microsoft Comm Control 5.0組
件,在簡體Form1中加入Command命令按鈕並取名為CmdTest,MSComm控制項取名為MSComm1,加入如下程序代碼。
Private Sub cmdTestClick ( ) '打開串口
MSComml.CommPort =2 '設定Com2
If MSComml.PortOpen = False Then
MSComm1.Settings = "9600,n,8,1" '9600波特率,無校驗,8位數據位,1位停止位
MSComm1.PortOpen = True '打開串口
End if
MSComm1.OutBufferCount = 0 '清空發送緩沖區
MSComm1.InBufferCount = 0 '滑空接收緩沖區
'發送字元數據時注意必須用回車符(vbcr)結束
MSComm1.Output="This is a qood book ! " &vbCr
'潑打電話號碼或發送AT命令
MSComm1.Output = "ATDT 05778191898 , & vbCr
'發送字元數組數據時注意ByteArray必須事先定義賦值
Dim ByteArray as byte( )
'定義動態數組
ReDim ByteArray(1)
'重定義數組大小
ByteArray ( 0 ) =0
ByteArray ( 1 ) = 1
MSComm1.Output = ByteArray
End Sub
private Sub MScommEvent( )
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant
MSComm1.InputLen = 0
'接收二進制數據
MSComm1.InputMode= ComInputModeBinary
Buffer=MSComm1.Input
'接收字元數據
MSComm1.InputMode=comInputModeText
Buffer = MSComml.Input
Case else
End Select
End sub
( 程序1)
二、中文Win 95/98下的通信問題與解決方法
1.接收的數據少於發送的數據
如果通過MSComm控制項一次性傳送較多的二進制數據,那麼,很可能收到的數據不足。例如在設置為24oobps傳輸率的情況下,
一次性可以傳輸2048個字元數據 那麼在大多數情況下。一次只能收到1200個字元左右,這址出為新版的MSComm32.OCX中存在一
個影響傳輸二進制數據的臭蟲(bug).注意這不是特性。
32位Windows API函數(以下簡稱API)使用了幾個用COMMTIMEOUTS結構表示的限時變數,WriteTotalTimeOutConstant 即是其
中的一個,它被Windows內部設定為5000(即5秒),這個常量決定了在通信驅動程序停止傳輸之前花費在發送緩沖區中數據的時間
的長短,5秒鍾意味著通信速度為1200bps情況下僅能發送600個字元,24oobps情況下僅能發送1200個左右的字元。事實上,在一個
緩沖區內一次性發送更多的數據是非常可能的。這個bug同樣也能引發問題,甚至在高速串口門通信情況下,即使系統在使用流控
制,無論叢軟體流(Xon/XofI)還是硬體流(CTS/RTS)。假如數據在發送緩沖區中時,流控制停止了傳輸,如果停止時間超過5
秒鍾.則數據就會丟失。在某些環境下,5秒鍾可能相當短.不過也不必擔心, VB 5.0/6.0版本的MSComm控制項有一個新增的重要的
屬性稱為CommID, CommID指的是當串口被打開時,被API所調用的串口句柄或稱標志,這也意味著能利用API介面函數去修改這個
常量。每次串口關閉後,Windows會自動將之恢復為5000,所以,每次打開串口後需要重斬設定以下API聲明,其代碼見下程序。
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Declare Function SetCommTimeouts Lib "Kernel32"
(BYVal hFile As Long, lpComm TimeoutsAs COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "Kernel32"
(ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
Dim timeouts As COMMEOUTS
Dim Ret As Long
If Comm1.PortOpen = False Then
Comm1.PortOpen = True
End if
Ret=GetCommTimeouts ( Comm1.CommID , timeouts )
'Set some default timeouts
timeOuts.ReadIntervalTimeout = 1
timeouts.ReadTotalTimeoutMultiplier =1
timeouts.ReadTotalTimeoutConstant =1
timeouts.WriteTotalTimeoutMultiplier =1
timeouts.WriteTotalTimeoutConstant=
( Comm1.OutBufferSize\Val(Comm1.Settings))*10000+1000
Ret=SetCommTimeouts( Comm1.CommID , timeouts )
( 程序2)
2.如何發送大於128的字元數據
在通信程序中,以單字元方式逐個發送數據時,每一個數據范圍 0-255(即十六進制的00-FF)。在單字元版本的英文Win95或
DOS版的BASIC程序中,只需要將相應的數據轉換成相應的字元發送到通信埠即可。但在中文Win95/98下卻行不通,假設在中文
Win95/98下運行以下程序:
Dim i
For i=0 to 255
MSComm1.Output=chr(i)
Next i
希望在接收端得到預期的0-255之間的數據,結果卻是:前129個數據接收正確,為0-128,後面127個數據為126個0和一個255,
造成這種給果的原因在於中文Windows使用的是雙位元組字元集(DBCS)系統。DBCS系統使用0-128之間的數字表示ASCII字元,大於
128的數字僅作為前導字元,它只是顯示是一個非拉丁語系的字元,而並不代表實際意義。上述程序在調用CHR()函數時用到了
DBCS字元集,岡此產生了此類錯誤。那麼,如何發送人於128的數據呢?答案是使用字元數組,將以上程序改為:
Dim cc(255) As Byte
For i = 0 To 255
cc(i) = i
Next i
MSComm1.Output = cc
Do
DoEvents
Loop Until MSComm1.OutBufferCount = 0
'接收過程 MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant, b1,i
MSComm1.InputMode=comInputModeBinery
MSComm1.InputLen = 0
Buffer = MSComm1.Input
For i=LBound (Buffer) To UBound (Buffer )
Debug.Print Buffer ( i ) ;
Next i
Case . . . . .
3.如何發送0字元(00H,NULL)
在VisuaI C++中使用串口控制項發送0字元有些麻煩,但在VB5.0/6.0中只要注意以下兩點即可:
(1)設置MSComm控制項的屬性 NullDiscard=False;。
(2)使用二進制接收,即用 MSComm1.InputMode=ComInputModeBinary便可以解決問題;
4.如何發送遞中文字元串(DBcS字元)
VB5.0/6.0的各種參考書上均指明MSComm通信控制項不能發送或接收雙位元組字元集系統DBCS)的二進制數據,這對於我國及亞洲一些
使用DBCS字元集的國家不能不說是一大人遺憾。但是我在實踐中發現,用MSComm控制項也可以發送中文字元,具體方法有以下兩種:
(1)直接發送
直接發送即把中文字元等同於英文字元。如:MSComm1.Intput= " 這是一行中文數據!" ,但這種方法發送的中文數據不能太
長,發送緩沖區和接收緩沖區的大小需設定為中文字元的兩倍以上,而且發送與接收系統所處的操作系統版本最好要一致,否則會
出現接收或發送緩沖區溢出之類的錯誤。這種方法時用於一般要求不太高的場合。
(2)間接發送
在發送端將漢字或字元轉換為機器內碼或區位碼數據數組,然後將詠轉換後的數據發送到串口,在接收端接收到數據後,按照
相反的順序得到的數據轉換為相應的漢字或字元,在轉換過程中.要用到位運算,如取得漢字的內碼後需要將高位元組和低位元組分開,
而VB5.0/6.0中並沒有提供此類函數,以下是求整數高、低位元組的函數。
Public Function HiByte(a As Integer )
Dim b
b= a And &HFF00
b = b / 256
If b<0 Then b = b + 256
HiByte = b
End Function
Public Function LowByte(a As Integ`er)
Dim b
b = a And &HFF
LowByte = b
End Function
5.如何用單機進行通信測試
通常在寫好了通信程序後需要兩台PC或一台Pc、一台單片機.將通信口連接後進行測試,但很多時候因條件限制僅有單台PC機,
測試項目很簡單,那麼能否測試呢?當然可以,而且方法也很簡單。對於九針的串口,找一個廢棄的串口滑鼠,剝外滑鼠線,將連
接2、3針的線對接即可;對於25針的串口,找一枚曲別針(最好有塑料外套的)將它扯直,剝削去兩頭的塑料後在兩頭各彎一個圓
圈,中間對忻後直接套接在串口的2、3針上即可。如果但心不夠安全,則可以將5針按地。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
關於mscomm的用法,提高篇......[mgwmj]&;
MSCOMM控制項是個好東西,如果您能夠充分了解他,他會為您衷心的效勞。
大致看了一下下午有關討論MSCOMM的話題,覺得有必要說說我的心得,我一般只做硬體,沒有系統的學過軟體,只是業余時間
學學用用,多少掌握了一點,也在此拿出來玩玩,不知有錯沒有,我可是以為我已經做的很好了^_^
這是一個VB通用串口事件驅動接收程序。一次性接收一個數據包,數據包可以為任意位元組,保證不會丟失一個數據!
Private Sub MSComm_OnComm()
Dim S() As Byte
Dim SS(1024) As Byte
Static N As Long
Static T As Variant
If (MSComm.CommEvent = comEvReceive) Then
S = MSComm.Input '只要有數據就收進來,哪怕只是一個
If (Timer - T > 0.01) Then '間隔10MS以上就認為是一個新的包
text1="" 'text1用於搜集和顯示接收(HEX格式)
N = 0
End If
T = Timer
For i = 0 To UBound(S) '一個數據包可能產生若干個oncomm事件
Text1.Text = Text1.Text & Right("0" & Hex(S(i)) & "H", 3) + " "
SS(N+i)=S(i) '接收數據包緩存於SS()
N=N+UBound(S)
Next i
End If
End Sub
③ 怎樣用VB編程來控制智能採集模塊
使用串口控制項 吧 communiction control
要採集器自動發送數據 ,程序讀串口通訊緩沖區 ,有數據就讀出處理
④ 急!請教RS485串口通訊的問題
你用vb還是vc?
看OnComm事件應該是vb吧。
(參照出處http://www.gjwtech.com/serialcomm.htm):
MSComm控制項使用詳解
摘要:本文詳細介紹了MSComm控制項在串口編程中使用。
目 次
MSComm控制項兩種處理通訊的方式
CommPort屬性
RThreshold 屬性
CTSHolding 屬性
SThreshold 屬性
CDHolding 屬性
DSRHolding 屬性
Settings 屬性
InputLen 屬性
EOFEnable 屬性
Handshake 常數
OnComm 常數
InputMode 常數
錯誤消息
MSComm 控制項通過串列埠傳輸和接收數據,為應用程序提供串列通訊功能。MSComm控制項在串口編程時非常方便,程序員不必去花時間去了解較為復雜的API函數,而且在VC、VB、Delphi等語言中均可使用。 Microsoft Communications Control(以下簡稱MSComm)是Microsoft公司提供的簡化Windows下串列通信編程的ActiveX控制項,它為應用程序提供了通過串列介面收發數據的簡便方法。具體的來說,它提供了兩種處理通信問題的方法:一是事件驅動(Event-driven)方法,一是查詢法。
1.MSComm控制項兩種處理通訊的方式
MSComm控制項提供下列兩種處理通訊的方式:事件驅動方式和查詢方式。
1.1 事件驅動方式
事件驅動通訊是處理串列埠交互作用的一種非常有效的方法。在許多情況下,在事件發生時需要得到通知,例如,在串口接收緩沖區中有字元,或者 Carrier Detect (CD) 或 Request To Send (RTS) 線上一個字元到達或一個變化發生時。在這些情況下,可以利用 MSComm 控制項的 OnComm 事件捕獲並處理這些通訊事件。OnComm 事件還可以檢查和處理通訊錯誤。所有通訊事件和通訊錯誤的列表,參閱 CommEvent 屬性。在編程過程中,就可以在OnComm事件處理函數中加入自己的處理代碼。這種方法的優點是程序響應及時,可靠性高。每個MSComm 控制項對應著一個串列埠。如果應用程序需要訪問多個串列埠,必須使用多個 MSComm 控制項。
1.2 查詢方式
查詢方式實質上還是事件驅動,但在有些情況下,這種方式顯得更為便捷。在程序的每個關鍵功能之後,可以通過檢查 CommEvent 屬性的值來查詢事件和錯誤。如果應用程序較小,並且是自保持的,這種方法可能是更可取的。例如,如果寫一個簡單的電話撥號程序,則沒有必要對每接收一個字元都產生事件,因為唯一等待接收的字元是數據機的「確定」響應。
2.MSComm 控制項的常用屬性
MSComm 控制項有很多重要的屬性,但首先必須熟悉幾個屬性。
CommPort 設置並返回通訊埠號。
Settings 以字元串的形式設置並返回波特率、奇偶校驗、數據位、停止位。
PortOpen 設置並返回通訊埠的狀態。也可以打開和關閉埠。
Input 從接收緩沖區返回和刪除字元。
Output 向傳輸緩沖區寫一個字元串。
下面分別描述:
CommPort屬性 設置並返回通訊埠號。
語法 object.CommPort[value ] (value 一整型值,說明埠號。)
說明 在設計時,value 可以設置成從 1 到 16 的任何數(預設值為 1)。但是如果用 PortOpen 屬性打開一個並不存在的埠時,MSComm 控制項會產生錯誤 68(設備無效)。
注意:必須在打開埠之前設置 CommPort 屬性。
RThreshold 屬性:在 MSComm 控制項設置 CommEvent 屬性為 comEvReceive 並產生 OnComm 之前,設置並返回的要接收的字元數。
語法 object.Rthreshold [ = value ](value 整型表達式,說明在產生 OnComm 事件之前要接收的字元數。 )
說明 當接收字元後,若 Rthreshold 屬性設置為 0(預設值)則不產生 OnComm 事件。例如,設置 Rthreshold 為 1,接收緩沖區收到每一個字元都會使 MSComm 控制項產生 OnComm 事件。
CTSHolding 屬性:確定是否可通過查詢 Clear To Send (CTS) 線的狀態發送數據。Clear To Send 是數據機發送到相聯計算機的信號,指示傳輸可以進行。該屬性在設計時無效,在運行時為只讀。
語法: object.CTSHolding(Boolean)
Mscomm 控制項的 CTSHolding 屬性設置值:
True Clear To Send 線為高電平。
False Clear To Send 線為低電平。
說明:如果 Clear To Send 線為低電平 (CTSHolding = False) 並且超時時,MSComm 控制項設置 CommEvent 屬性為 comEventCTSTO (Clear To Send Timeout) 並產生 OnComm 事件。
Clear To Send 線用於 RTS/CTS (Request To Send/Clear To Send) 硬體握手。如果需要確定 Clear To Send 線的狀態,CTSHolding 屬性給出一種手工查詢的方法。
詳細信息 有關握手協議,請參閱 Handshaking 屬性。
SThreshold 屬性: MSComm 控制項設置 CommEvent 屬性為 comEvSend 並產生 OnComm 事件之前,設置並返回傳輸緩沖區中允許的最小字元數。
語法 object.SThreshold [ = value ]
value 整形表達式,代表在 OnComm 事件產生之前在傳輸緩沖區中的最小字元數。
說明:若設置 Sthreshold 屬性為 0(預設值),數據傳輸事件不會產生 OnComm 事件。若設置 Sthreshold 屬性為 1,當傳輸緩沖區完全空時,MSComm 控制項產生 OnComm 事件。如果在傳輸緩沖區中的字元數小於 value,CommEvent 屬性設置為 comEvSend,並產生 OnComm 事件。comEvSend 事件僅當字元數與 Sthreshold 交叉時被激活一次。例如,如果 Sthreshold 等於 5,僅當在輸出隊列中字元數從 5 降到 4 時,comEvSend 才發生。如果在輸出隊列中從沒有比 Sthreshold 多的字元,comEvSend 事件將絕不會發生。
Handshake 常數
常數 值 描述
comNone 0 無握手。
comXonXoff 1 XOn/Xoff 握手。
comRTS 2 Request-to-send/clear-to-send 握手。
comRTSXOnXOff 3 Request-to-send 和 clear-to-send 握手皆可。
OnComm 常數
常數 值 描述
comEvSend 1 發送事件。
comEvReceive 2 接收事件。
comEvCTS 3 clear-to-send 線變化。
comEvDSR 4 data-set ready 線變化。
comEvCD 5 carrier detect 線變化。
comEvRing 6 振鈴檢測。
comEvEOF 7 文件結束。
Error 常數
常數 值 描述
comEventBreak 1001 接收到中斷信號
comEventCTSTO 1002 Clear-to-send 超時
comEventDSRTO 1003 Data-set ready 超時
comEventFrame 1004 幀錯誤
comEventOverrun 1006 埠超速
comEventCDTO 1007 Carrier detect 超時
comEventRxOver 1008 接收緩沖區溢出
comEventRxParity 1009 Parity 錯誤
comEventTxFull 1010 傳輸緩沖區滿
comEventDCB 1011 檢索埠 設備控制塊 (DCB) 時的意外錯誤
InputMode 常數
常數 值 描述
comInputModeText 0 (預設)通過 Input 屬性以文本方式取回數據。
comInputModeBinary 1 通過 Input 屬性以二進制方式檢取回數據。
CDHolding 屬性:通過查詢 Carrier Detect (CD) 線的狀態確定當前是否有傳輸。Carrier Detect 是從數據機發送到相聯計算機的一個信號,指示數據機正在聯機。該屬性在設計時無效,在運行時為只讀。
語法 object.CDHolding
設置值:CDHolding 屬性的設置值為:
設置 描述
True Carrier Detect 線為高電平
False Carrier Detect 線為低電平
說明:注意當 Carrier Detect 線為高電平 (CDHolding = True) 且超時時,MSComm 控制項設置CommEvent 屬性為 comEventCDTO(Carrier Detect 超時錯誤),並產生 OnComm 事件。
注意 在主機應用程序中捕獲一個丟失的傳輸是特別重要的,例如一個公告板,因為呼叫者可以隨時掛起(放棄傳輸)。
Carrier Detect 也被稱為 Receive Line Signal Detect (RLSD)。
數據類型 Boolean
DSRHolding 屬性:確定 Data Set Ready (DSR) 線的狀態。Data Set Ready 信號由數據機發送到相連計算機,指示作好操作準備。該屬性在設計時無效,在運行時為只讀。
語法:object.DSRHolding
object 所在處表示對象表達式,其值是「應用於」列表中的對象。
DSRHolding 屬性返回以下值:
值 描述
True Data Set Ready 線高
False Data Set Ready 線低
說明:當 Data Set Ready 線為高電平 (DSRHolding = True) 且超時時,MSComm 控制項設置 CommEvent 屬性為 comEventDSRTO(數據准備超時)並產生 OnComm 事件。
當為 Data Terminal Equipment (DTE) 機器寫 Data Set Ready/Data Terminal Ready 握手常式時該屬性是十分有用的。
數據類型:Boolean
Settings 屬性: 設置並返回波特率、奇偶校驗、數據位、停止位參數。
語法: object.Settings[ = value]
說明:當埠打開時,如果 value 非法,則 MSComm 控制項產生錯誤 380(非法屬性值)。
Value 由四個設置值組成,有如下的格式:
"BBBB,P,D,S"
BBBB 為波特率,P 為奇偶校驗,D 為數據位數,S 為停止位數。value 的預設值是:
"9600,N,8,1"
InputLen 屬性:設置並返回 Input 屬性從接收緩沖區讀取的字元數。
語法 object.InputLen [ = value]
InputLen 屬性語法包括下列部分:
value 整型表達式,說明 Input 屬性從接收緩沖區中讀取的字元數。
說明:InputLen 屬性的預設值是 0。設置 InputLen 為 0 時,使用 Input 將使 MSComm 控制項讀取接收緩沖區中全部的內容。
若接收緩沖區中 InputLen 字元無效,Input 屬性返回一個零長度字元串 ("")。在使用 Input 前,用戶可以選擇檢查 InBufferCount 屬性來確定緩沖區中是否已有需要數目的字元。該屬性在從輸出格式為定長數據的機器讀取數據時非常有用。
EOFEnable 屬性:確定在輸入過程中 MSComm 控制項是否尋找文件結尾 (EOF) 字元。如果找到 EOF 字元,將停止輸入並激活 OnComm 事件,此時 CommEvent 屬性設置為 comEvEOF,
語法:object.EOFEnable [ = value ]
EOFEnable 屬性語法包括下列部分:
value 布爾表達式,確定當找到 EOF 字元時,OnComm 事件是否被激活,如「設置值」中所描述。
value 的設置值:
True 當 EOF 字元找到時 OnComm 事件被激活。
False (預設)當 EOF 字元找到時 OnComm 事件不被激活。
說明:當 EOFEnable 屬性設置為 False,OnComm 控制項將不在輸入流中尋找 EOF 字元。
錯誤消息(MS Comm 控制項)
下表列出 MSComm 控制項可以捕獲的錯誤:
值 描述
380 無效屬性值 comInvalidPropertyValue
383 屬性為只讀 comSetNotSupported
394 屬性為只讀 comGetNotSupported
8000 埠打開時操作不合法 comPortOpen
8001 超時值必須大於 0
8002 無效埠號 comPortInvalid
8003 屬性只在運行時有效
8004 屬性在運行時為只讀
8005 埠已經打開 comPortAlreadyOpen
8006 設備標識符無效或不支持該標識符
8007 不支持設備的波特率
8008 指定的位元組大小無效
8009 預設參數錯誤
8010 硬體不可用(被其它設備鎖定)
8011 函數不能分配隊列
8012 設備沒有打開 comNoOpen
8013 設備已經打開
8014 不能使用 comm 通知
8015 不能設置 comm 狀態 comSetCommStateFailed
8016 不能設置 comm 事件屏蔽
8018 僅當埠打開時操作才有效 comPortNotOpen
8019 設備忙
8020 讀 comm 設備錯誤 comReadError
8021 為該埠檢索設備控制塊時的內部錯誤 comDCBError
///-----------------------------------------------------
串口數據接收方式
1、 在OnComm 事件中接收數據:
這種方式能充分MSCOMM控制項的特性。OnComm 事件還可以檢查和處理通訊錯誤;可以通過檢查 CommEvent 屬性的值來查詢事件和錯誤;對於不定長數據以及對數據進行處理比較復雜的情況,此法不是很方便。
Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent
' 錯誤
Case comEventBreak ' 收到 Break。
Case comEventCDTO ' CD (RLSD) 超時。
Case comEventCTSTO ' CTS Timeout。
Case comEventDSRTO ' DSR Timeout。
Case comEventFrame ' Framing Error
Case comEventOverrun '數據丟失。
Case comEventRxOver'接收緩沖區溢出。
Case comEventRxParity' Parity 錯誤。
Case comEventTxFull '傳輸緩沖區已滿。
Case comEventDCB '獲取 DCB] 時意外錯誤
' 事件
Case comEvCD ' CD 線狀態變化。
Case comEvCTS ' CTS 線狀態變化。
Case comEvDSR ' DSR 線狀態變化。
Case comEvRing ' Ring Indicator 變化。
Case comEvReceive ' 收到 RThreshold # of chars.
Case comEvSend ' 傳輸緩沖區有 Sthreshold 個字元 '
Case comEvEof ' 輸入數據流中發現 EOF 字元
End Select
End Sub
2.輪循法採集數據:
A、定時器輪循法
對於數據包方式收發數據以及不需即時響應情況,用輪循法更好些。實際上輪循法最大的好處在於集中處理數據而且不太佔用CPU。輪循法要注意定時採集的時間片段大小;這里用二進制收發模式;使屬性RThreshold、SThreshold為0,屏蔽ONCOMM事件。
InputMode = comInputModeBinary
RThreshold = 0
SThreshold = 0
Private Sub TmrComm_Timer()
'採用輪循法採集數據
Dim Rx_buff() As Byte
Dim okstring As String
Dim ReceivedLen As Integer
On Error GoTo ErrorHandler
TmrComm.Enabled = False '關閉定時器
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 '打開定時器
End Sub
B、直接輪循法
此法用於接收少量控制命令字;
' 保存輸入子串的緩沖區
Dim Instring As String
' 使用 COM1。
MSComm1.CommPort = 1
' 9600 波特,無奇偶校驗,8 位數據,一個停止位。
MSComm1.Settings = "9600,N,8,1"
' 當輸入佔用時,
' 告訴控制項讀入整個緩沖區。
MSComm1.InputLen = 0
' 打開埠。
MSComm1.PortOpen = True
' 將 attention 命令送到數據機。
MSComm1.Output = "ATV1Q0" & Chr$(13)
' 確保
' 數據機以"OK"響應。
' 等待數據返回到串列埠。
Do
DoEvents
Buffer$ = Buffer$ & MSComm1.Input
Loop Until InStr(Buffer$, "OK" & vbCRLF)
' 從串列埠讀 "OK" 響應。
' 關閉串列埠。
MSComm1.PortOpen = False
如何處理不定長數據的接收
在處理串口通訊時,經常會遇到不定長數據的接收。由於通訊任務不同及編程要求的差異所以採用的方法也有所不同。本文就此問題進行探討。不定長數據從數據格式上分,可分為有格式和無格式。
一、無格式不定長數據的接收
這種格式在實際串口通訊中用得不多,一般只用傳送字元串數據。問題在於怎麼判斷接收結束。一般用時間延遲的方法解決。
A、對於非握手式通訊,可用一個定時器定時輪循接收,並假定每個輪循接收完成。用ONCOMM事件接收也可,只是不如定時器定時輪循接收簡便。
B、對於握手方式通訊,可用直接輪循法提高接收的准確性。下面是實現此法的函數:
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 函數,掛起當前進程一段時間
Loop Until comReceive.InBufferCount = nReceiveCount
If comReceive.PortOpen = True Then
sComm = comReceive.Input
End If
End Function
註:此函數參照了xth一文。
此法一般是能確保數據接收的正確,但由於WINDOWS是多任務操作系統,當有耗時的進程運行時會丟失數據。如果系統會出現這種情況,可增大函數sleep()的參數值。
二、不定長格式數據的接收
對於不定長數據接收最好的方法是制定通訊協議,比如定義開始字元和結束字元。由於單片機系統通訊一般不太復雜,沒必要去制定一套象通用計算機間通訊的協議,而根據單片機系統的大小和性能要求制定通訊協議。實際上為便於交流、維護以及一致性,可制定一套可伸縮的通訊協議。定義了開始字元和結束字元就容易實現不定長格式數據通訊,但在實際通訊編程還是容易出現一些比較隱蔽的通訊錯誤。下面就常用方法分別進行分析。
A、定時器輪循法。
假定每個輪循期數據接收完畢,並在每個輪循期處理數據,由於有開始字元和結束字元很容易確定接收數據的完整性。好象合理設定輪循時間值就萬無一失了,但被動接收數據時無論如何也找不合適的輪循時間值,因為啟動定時器和數據到來基本不同步,這就會出現一次發送的數據被分在兩個輪循期接收,所以被動接收數據時不能假定每個輪循期數據接收完畢。在接收到結束字元後才確定一次數據接收完畢就可解決此問題。
B、OnComm事件法。
方法和定時器輪循法基本相同,因為每次OnCommg事件也只能接收到一部分數據。在VB的在線幫助中這樣註解「設置 Rthreshold 為 1,接收緩沖區收到每一個字元都會使 MSComm 控制項產生 OnComm 事件。」。但實際上OnComm事件並不是每收到一個字元便觸發一次 OnComm 事件。OnComm事件是在緩沖區收到幾個甚至幾十個位元組數據後才被觸發的。版主認為這是WINDOWS多任務使操作系統不能實時響應造成的。如果要在每次OnComm事件接收一個字元似乎可設INPUTLEN屬性為1,但實際行不通。VB在線幫助中「有該屬性在從輸出格式為定長數據的機器讀取數據時非常有用」的註解,好象在說對定長字元有效,但版主發現INPUTLEN設為16,接收16個字元定長數據時卻被當作兩次接收了,一次12個,一次4個。建議在OnComm事件中接收數據要定義通訊協議並檢測數據的完整性。 對於不定長格式數據的接收程序員更喜歡定時器輪循法,也許OnComm事件不好控制吧。
對於不定長數據的接收,最佳方法可能是在OnComm事件中啟動定時器輪循接收,並同時停止OnComm事件的觸發,接收完畢後或超時開啟OnComm事件。
用字元方式收發碼值大於127的字元數據
VB的通訊控制項友好、功能強大,編程速度快是眾人皆知的。加上VB的易學、易用,快速開發等特點,數據通訊量不是很大時,在單片機通訊領域廣泛地使用VB開發PC上層通訊軟體。實際開發時會有不少問題,這里就用字元方式收發碼值大127的字元數據進行討論。
在實際開發中經常遇到通訊只是用來發送一些控制字元命令和少量數據。在VB的中文在線幫助中有「若數據只用 ANSI 字元集,則用 comInputModeText」的表述。 ANSI字元集是0-127這容易使人誤解為&h88也可用「INPUTMIDE=comInputModeText」方式收發。我剛開始用VB編通訊模塊時就為此迷惑過,網上不少網友也時常問及這種問題。實際上在VB中0-127是可以正常收發的,大於127即&H7F的只有&H80和&HFF能夠收發,其餘ANSI字元都被過濾為0。由於串口通訊是以位元組收發的,數據如以comInputModeText模式收發則非字元串數據會被過濾。在VB中用「INPUTMIDE = comInputModeBinary」 就可以解決這個問題,只是收發都必須用動態數組來完成。用comInputModeBinary模式編程稍有點復雜,調試也不直觀,對於初學者不易掌握。另外軟體完成後,在實際應用時會增加工程維護難度,因為對於二進制代碼不是易於理解的。比如下端機發送現場統計數據233,comInputModeBinary模式下串口監測到「:A &H233;",它代表A探針的溫度。一般串口監測軟體要麼用ASCII方式顯示,要麼用二進制方式顯示。用ASCII方式則不能看到&H233,而二進制方式則示不好理解,如果顯示58 65 233 59,我想沒有人喜歡這種方式(如果有更好的方式的話)。但如果顯示「:A 2 3 3 ;」不就解決問題了!用comInputModeText方式就可完成任務了,只是多了一段數據分離程序。對於一般通訊要求這種方法不為是一種好方法。由於通訊任務是多種多樣的,有時候這種方法就有點力不從心了,如傳送較多的的數據時,這會顯著地增加通訊量,通訊變得復雜了,對於單片機系統就不太合適了;還有一些特殊要求,如數據包的識別符也不適此法,但能確定傳送數據碼值范圍也可用此法。下面介紹另一種方法,此法適用比較廣,傳送二進制數據通訊量增加也不大。
這種方法實際上很簡單,實際運用中有不少採用此法。原理是一碼分為二碼。如設7E為臨界字元,對於7E則分為7E和0兩個ASCII碼,依此類推,8F分為7E和11。接收合並時遇到7E則將7E和後一個ASCII碼相加為下字元。下面給出C語言函數,VB轉換一下便可。
由於C語言不能返回兩個參數,所以用數組指針。
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作為標記code[1]不可能產生0XFF*/
}
}
else if(c=='H')
{
if(code[0]!=0X7E)
{
code[1]=0xFE; /*轉換完成標記*/
}
else
{
if(code[1]==0XFE)
{
code[1]=0XFF; /*接收下一個碼的標記*/
}
else
{
code[0]=code[0]+code[1];
code[1]=0XFE;
}
}
}
發送時:
char SendChar[2]; /*存儲發送的值*/
....
SendChar[0]=c; /*c為待發ASCII碼*/
Filt(SendChar,'F');
if(SendChar(1)==0XFF)
{
..... /*發送SendChar[0]*/
}
else
{
...... /*發送SendChar[0],SendChar[1]*/
}
接收時:
char ReceiveChar[2]; /*存儲接收的值*/
.....
ReceiveChar[0]=c0; /*c0接收的ASCII碼*/
Filt(ReceiveChar,'H');
if(ReceiveChar[1]==0xFF)
{
ReceiveChar[1]=c1; /*c1為下一個*/
Filt(ReceiveChar,'H);
}
else if(ReceiveChar[1]==0xFE)
{
...... /*存儲轉換後的ReceiveChar[0]*/
}
以上代碼僅提供一種思路,實際情況視編程需要而定。
串口通訊問答錄
1、Q:各位vb高手:我有一個問題想請教一下。我從COM口用BIN方式接收到數據(一串漢字),存入一BYTE數組,但無法還原為一串漢字,我認為是ANSI和UNICODE的轉換,請問如何轉換。
例:字元串「我」,按BIN方式接收成一BYTE數組,其值為「206,210」,如用「CHR(206)+CHR(210)」卻無法得到「我」,實際上「我」=CHR(-12860)請問如何能實現BYTE數組(206,210)與字元串「我」之間的轉換?萬分感謝!!!
JY
1999.10
A:經CHR(206)+CHR(210)轉換後實際上變成了兩個UNICODE字元,四個位元組了。漢字的收發必須用BINARY方式。下面的程序能實現漢字收發。
發:
Dim ytemp() As Byte
Dim stemp As String
stemp = "你好!"
ytemp = StrConv(stemp, vbFromUnicode)
Debug.Print UBound(ytemp)
MSComm1.Output = ytemp
收:
Private Sub mscTest_OnComm()
'中文收發
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:各位大俠,在下被兩個問題困擾多時,實在無法找到答案,請各位多多指教。
1、在用MSCOMM控制項設計通訊程序時,我始終無法將ASC碼大於127的值發送出去,查閱了VB論壇以前的文章,按部就班也不行,部分 VB 程序如下,請指教:
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:接收方式使用了文本方式,用二進制方式即可。
⑤ 用MFC怎麼做串口測試程序,我要詳細步聚!!!!!!!!
添加一個mscomm 控制項裡面有,然後設置它的波特率,波特率和下位機的波特率要一致。然後就用
Write和Read方法讀寫數據就行了。
推薦關於MSCOMM控制項的一些說明
VB5.0/6.的MSComm通信控制項提供了一系列標准通信命令的介面,它允許建立串口連接,可以連接到其他通信設備(如Modem).
還可以發送命令、進行數據交換以及監視和響應在通信過程中可能發生的各種錯誤和事件,從而可以用它創建全雙工 、事件驅
動的、高效實用的通信程序。但在實際通信軟體設計過程中,MSComm控制項並非像想像中那樣完美和容易控制.特別是在中文Wln
95/98下通信時更會出現問題。下面就從基礎開始介紹,然後逐步討淪MSComm控制項在編程中出現的問題以及編程技巧。
一、用MSComm控制項通信
1.串口通信基礎知識
一般悅來,計算機都有一個或多個串列埠,它們依次為com1、Com2、…,這些串口還提供了外部設備與pC進行數據傳輸和
皿信的通道。這些串口在CPU和外設之間充當解釋器的角色。當字元數據從CPU發送給外設時,這些字元數據將被轉換成串列比特
流數據;當接收數據時,比特流數據被轉換為字元數據傳遞給CPU,再進一步說,在操作系統方面,Windows用通信驅動程序
(COMM.DRV)調用API函數發送和接收數據,當用通信控制項或聲明調用API函數時,它門由COMM. DRV解釋並傳遞給設備驅動程序,
作為一個vB程序員,要編寫通信程序.只需知道通信控制項提供給Windows通信AP1函數的介面即可.換句話說,只需設定和監視通
信控制項的屬性和事件即可。
2.使用Mscomm控制項
在開始使用MSComm控制項之前。需要先了解其屬性、事件或錯誤
屬性 描述
CommPort 設置或返回通信埠號
Settings 以字元串的形式設置或返回波特率、奇偶校驗、數據位和停止位
PortOpen 設置或返回通信埠的狀態。也可以打開和關閉埠
Input 返回和刪除接收緩沖區中的字元
Output 將字元串寫入發送緩沖區
CommEvent屬性為通信事件或錯誤返回下列值之一。在該控制項的對象庫中也可以找到這些常量。
常量 值 描述
ComEventBreak 1001 收到了斷開信號
ComEventCTSTO 1002 Clear To Send Timeout。在發送字元時,在系統指定的事1件內,CTS(Clear To Send)線是低電平
ComEventDSRTO 1003 Data Set Ready Timeout。在發送字元時,在系統指定的事件內,DSR(Data Set Ready)線是低電平
ComEventFrame 1004 數據幀錯誤。硬體檢測到一個數據幀錯誤
ComEventOverrun 1006 埠溢出。硬體中的字元尚未讀,下一個字元又到達,並且丟失
ComEventCDTO 1007 Carrier Detect Time。在發送字元時,在系統指定的事件內,CD(Carrier Detect)線是低電平。CD
也稱為RLSD(Receive Line Singal Detect,接收線信號檢測)
ComEventRxOver 1008 接收緩沖區溢出。在接收緩沖區中沒有空間
ComEventRxParity 1009 奇偶校驗錯。硬體檢測到奇偶校驗錯誤7
ComEventTxFull 1010 發送緩沖區滿。在對發送字元排隊時,發送緩沖區滿
ComEventDCB 1011 檢取埠DCB(Device Control Blick)時發生了沒有預料到的錯誤
通信事件包含了下面的設置:
常量 值 描述
ComEvSend 1 發送緩沖區中的字元數比Sthreshold值低
ComEvReceive 2 接收到了Rthreshold個字元。持續產生該事件,直到使用了Input屬性刪除了接收緩沖區中的數據
ComEvCTS 3 CTS(Clear To Send)線改變
ComEvDSR 4 DSR(Data Set Ready)線改變。當DSR從1到0改變時,該事件發生
ComEvCD 5 CD(Carrier Detect)線改變ComEvRing6檢測到響鈴信號。一些URAT(Universal AsynchronousReciver-
-Transmitters,通用非同步收發器)不支持該事件
ComEvEOF 7 收到了EOF字元(ASCII字元26)
Error消息(MSComm控制項)下表列出了MSComm控制項可捕獲的錯誤消息:
常量 值 描述
ComInvalidPropertyValue 380 無效的屬性值
ComSetNotSupported 383 屬性只讀
ComGetNotSupported 394 屬性只讀
ComPortOpen 8000 埠打開時該存在無效
8001 超時設置必須比0值大
ComPortInvalid 8002 無效的埠號
8003 屬性只在運行時有效
8004 屬性在運行時是只讀的
ComPortAleadyOpen 8005 埠已經打開
8006 設備標識符無效或不支持
8007 不支持設備的波特率
8008 指定的位元組大小無效
8009 預設參數錯誤
8010 硬體不可用(被其他設備鎖住)
8011 函數不能分配隊列
ComNoOpen 8012 設備沒有打開
8013 設備已經打開
8014 不能使用通信通知
ComSetCommStateFailed 8015 不能設置通信狀態
8016 不能設置通信事件屏蔽
ComPortNotOpen 8018 該存在只在埠打開是有效
8019 設備忙
ComReadError 8020 通信設備讀錯誤
ComDCBError 8021 檢取埠設備控制塊時出現內部錯誤
搞清楚以上基本屬性後,就可以開始編寫通信許程序了。在VB5.0/6.0中新建一個工程文件。添加Microsoft Comm Control 5.0組
件,在簡體Form1中加入Command命令按鈕並取名為CmdTest,MSComm控制項取名為MSComm1,加入如下程序代碼。
Private Sub cmdTestClick ( ) '打開串口
MSComml.CommPort =2 '設定Com2
If MSComml.PortOpen = False Then
MSComm1.Settings = "9600,n,8,1" '9600波特率,無校驗,8位數據位,1位停止位
MSComm1.PortOpen = True '打開串口
End if
MSComm1.OutBufferCount = 0 '清空發送緩沖區
MSComm1.InBufferCount = 0 '滑空接收緩沖區
'發送字元數據時注意必須用回車符(vbcr)結束
MSComm1.Output="This is a qood book ! " &vbCr
'潑打電話號碼或發送AT命令
MSComm1.Output = "ATDT 05778191898 , & vbCr
'發送字元數組數據時注意ByteArray必須事先定義賦值
Dim ByteArray as byte( )
'定義動態數組
ReDim ByteArray(1)
'重定義數組大小
ByteArray ( 0 ) =0
ByteArray ( 1 ) = 1
MSComm1.Output = ByteArray
End Sub
private Sub MScommEvent( )
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant
MSComm1.InputLen = 0
'接收二進制數據
MSComm1.InputMode= ComInputModeBinary
Buffer=MSComm1.Input
'接收字元數據
MSComm1.InputMode=comInputModeText
Buffer = MSComml.Input
Case else
End Select
End sub
( 程序1)
二、中文Win 95/98下的通信問題與解決方法
1.接收的數據少於發送的數據
如果通過MSComm控制項一次性傳送較多的二進制數據,那麼,很可能收到的數據不足。例如在設置為24oobps傳輸率的情況下,
一次性可以傳輸2048個字元數據 那麼在大多數情況下。一次只能收到1200個字元左右,這址出為新版的MSComm32.OCX中存在一
個影響傳輸二進制數據的臭蟲(bug).注意這不是特性。
32位Windows API函數(以下簡稱API)使用了幾個用COMMTIMEOUTS結構表示的限時變數,WriteTotalTimeOutConstant 即是其
中的一個,它被Windows內部設定為5000(即5秒),這個常量決定了在通信驅動程序停止傳輸之前花費在發送緩沖區中數據的時間
的長短,5秒鍾意味著通信速度為1200bps情況下僅能發送600個字元,24oobps情況下僅能發送1200個左右的字元。事實上,在一個
緩沖區內一次性發送更多的數據是非常可能的。這個bug同樣也能引發問題,甚至在高速串口門通信情況下,即使系統在使用流控
制,無論叢軟體流(Xon/XofI)還是硬體流(CTS/RTS)。假如數據在發送緩沖區中時,流控制停止了傳輸,如果停止時間超過5
秒鍾.則數據就會丟失。在某些環境下,5秒鍾可能相當短.不過也不必擔心, VB 5.0/6.0版本的MSComm控制項有一個新增的重要的
屬性稱為CommID, CommID指的是當串口被打開時,被API所調用的串口句柄或稱標志,這也意味著能利用API介面函數去修改這個
常量。每次串口關閉後,Windows會自動將之恢復為5000,所以,每次打開串口後需要重斬設定以下API聲明,其代碼見下程序。
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Declare Function SetCommTimeouts Lib "Kernel32"
(BYVal hFile As Long, lpComm TimeoutsAs COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "Kernel32"
(ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
Dim timeouts As COMMEOUTS
Dim Ret As Long
If Comm1.PortOpen = False Then
Comm1.PortOpen = True
End if
Ret=GetCommTimeouts ( Comm1.CommID , timeouts )
'Set some default timeouts
timeOuts.ReadIntervalTimeout = 1
timeouts.ReadTotalTimeoutMultiplier =1
timeouts.ReadTotalTimeoutConstant =1
timeouts.WriteTotalTimeoutMultiplier =1
timeouts.WriteTotalTimeoutConstant=
( Comm1.OutBufferSize\Val(Comm1.Settings))*10000+1000
Ret=SetCommTimeouts( Comm1.CommID , timeouts )
( 程序2)
2.如何發送大於128的字元數據
在通信程序中,以單字元方式逐個發送數據時,每一個數據范圍 0-255(即十六進制的00-FF)。在單字元版本的英文Win95或
DOS版的BASIC程序中,只需要將相應的數據轉換成相應的字元發送到通信埠即可。但在中文Win95/98下卻行不通,假設在中文
Win95/98下運行以下程序:
Dim i
For i=0 to 255
MSComm1.Output=chr(i)
Next i
希望在接收端得到預期的0-255之間的數據,結果卻是:前129個數據接收正確,為0-128,後面127個數據為126個0和一個255,
造成這種給果的原因在於中文Windows使用的是雙位元組字元集(DBCS)系統。DBCS系統使用0-128之間的數字表示ASCII字元,大於
128的數字僅作為前導字元,它只是顯示是一個非拉丁語系的字元,而並不代表實際意義。上述程序在調用CHR()函數時用到了
DBCS字元集,岡此產生了此類錯誤。那麼,如何發送人於128的數據呢?答案是使用字元數組,將以上程序改為:
Dim cc(255) As Byte
For i = 0 To 255
cc(i) = i
Next i
MSComm1.Output = cc
Do
DoEvents
Loop Until MSComm1.OutBufferCount = 0
'接收過程 MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant, b1,i
MSComm1.InputMode=comInputModeBinery
MSComm1.InputLen = 0
Buffer = MSComm1.Input
For i=LBound (Buffer) To UBound (Buffer )
Debug.Print Buffer ( i ) ;
Next i
Case . . . . .
3.如何發送0字元(00H,NULL)
在VisuaI C++中使用串口控制項發送0字元有些麻煩,但在VB5.0/6.0中只要注意以下兩點即可:
(1)設置MSComm控制項的屬性 NullDiscard=False;。
(2)使用二進制接收,即用 MSComm1.InputMode=ComInputModeBinary便可以解決問題;
4.如何發送遞中文字元串(DBcS字元)
VB5.0/6.0的各種參考書上均指明MSComm通信控制項不能發送或接收雙位元組字元集系統DBCS)的二進制數據,這對於我國及亞洲一些
使用DBCS字元集的國家不能不說是一大人遺憾。但是我在實踐中發現,用MSComm控制項也可以發送中文字元,具體方法有以下兩種:
(1)直接發送
直接發送即把中文字元等同於英文字元。如:MSComm1.Intput= " 這是一行中文數據!" ,但這種方法發送的中文數據不能太
長,發送緩沖區和接收緩沖區的大小需設定為中文字元的兩倍以上,而且發送與接收系統所處的操作系統版本最好要一致,否則會
出現接收或發送緩沖區溢出之類的錯誤。這種方法時用於一般要求不太高的場合。
(2)間接發送
在發送端將漢字或字元轉換為機器內碼或區位碼數據數組,然後將詠轉換後的數據發送到串口,在接收端接收到數據後,按照
相反的順序得到的數據轉換為相應的漢字或字元,在轉換過程中.要用到位運算,如取得漢字的內碼後需要將高位元組和低位元組分開,
而VB5.0/6.0中並沒有提供此類函數,以下是求整數高、低位元組的函數。
Public Function HiByte(a As Integer )
Dim b
b= a And &HFF00
b = b / 256
If b<0 Then b = b + 256
HiByte = b
End Function
Public Function LowByte(a As Integ`er)
Dim b
b = a And &HFF
LowByte = b
End Function
5.如何用單機進行通信測試
通常在寫好了通信程序後需要兩台PC或一台Pc、一台單片機.將通信口連接後進行測試,但很多時侯因條件限制僅有單台PC機,
測試項目很簡單,那麼能否測試呢?當然可以,而且方法也很簡單。對於九針的串口,找一個廢棄的串口滑鼠,剝外滑鼠線,將連
接2、3針的線對接即可;對於25針的串口,找一枚曲別針(最好有塑料外套的)將它扯直,剝削去兩頭的塑料後在兩頭各彎一個圓
圈,中間對忻後直接套接在串口的2、3針上即可。如果但心不夠安全,則可以將5針按地。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
關於mscomm的用法,提高篇......[mgwmj]?
MSCOMM控制項是個好東西,如果您能夠充分了解他,他會為您衷心的效勞。
大致看了一下下午有關討論MSCOMM的話題,覺得有必要說說我的心得,我一般只做硬體,沒有系統的學過軟體,只是業余時間
學學用用,多少掌握了一點,也在此拿出來玩玩,不知有錯沒有,我可是以為我已經做的很好了^_^
這是一個VB通用串口事件驅動接收程序。一次性接收一個數據包,數據包可以為任意位元組,保證不會丟失一個數據!
Private Sub MSComm_OnComm()
Dim S() As Byte
Dim SS(1024) As Byte
Static N As Long
Static T As Variant
If (MSComm.CommEvent = comEvReceive) Then
S = MSComm.Input '只要有數據就收進來,哪怕只是一個
If (Timer - T > 0.01) Then '間隔10MS以上就認為是一個新的包
text1="" 'text1用於搜集和顯示接收(HEX格式)
N = 0
End If
T = Timer
For i = 0 To UBound(S) '一個數據包可能產生若干個oncomm事件
Text1.Text = Text1.Text & Right("0" & Hex(S(i)) & "H", 3) + " "
SS(N+i)=S(i) '接收數據包緩存於SS()
N=N+UBound(S)
Next i
End If
End Sub
⑥ 中央處理器的選擇方法及它們有什麼樣的區別
nit(中央微處理器)的縮寫,它是計算機中最重要的一個部分,由運算器和控制器組成。如果把計算機比作人,那麼CPU就是人的大腦。CPU的發展非常迅速,個人電腦從8088(XT)發展到現在的Pentium 4時代,只經過了不到二十年的時間。
從生產技術來說,最初的8088集成了29000個晶體管,而PentiumⅢ的集成度超過了2810萬個晶體管;CPU的運行速度,以MIPS(百萬個指令每秒)為單位,8088是0.75MIPS,到高能奔騰時已超過了1000MIPS。不管什麼樣的CPU,其內部結構歸納起來都可以分為控制單元、邏輯單元和存儲單元三大部分,這三個部分相互協調,對命令和數據進行分析、判斷、運算並控制計算機各部分協調工作。
CPU從最初發展至今已經有二十多年的歷史了,這期間,按照其處理信息的字長,CPU可以分為:4位微處理器、8位微處理器、16位微處理器、32位微處理器以及正在醞釀構建的64位微處理器,可以說個人電腦的發展是隨著CPU的發展而前進的。
Intel 4004
1971年,英特爾公司推出了世界上第一款微處理器4004,這是第一個可用於微型計算機的四位微處理器,它包含2300個晶體管。隨後英特爾又推出了8008,由於運算性能很差,其市場反應十分不理想。1974年,8008發展成8080,成為第二代微處理器。8080作為代替電子邏輯電路的器件被用於各種應用電路和設備中,如果沒有微處理器,這些應用就無法實現。
由於微處理器可用來完成很多以前需要用較大設備完成的計算任務,價格又便宜,於是各半導體公司開始競相生產微處理器晶元。Zilog公司生產了8080的增強型Z80,摩托羅拉公司生產了6800,英特爾公司於1976年又生產了增強型8085,但這些晶元基本沒有改變8080的基本特點,都屬於第二代微處理器。它們均採用NMOS工藝,集成度約9000隻晶體管,平均指令執行時間為1μS~2μS,採用匯編語言、BASIC、Fortran編程,使用單用戶操作系統。
Intel 8086
1978年英特爾公司生產的8086是第一個16位的微處理器。很快Zilog公司和摩托羅拉公司也宣布計劃生產Z8000和68000。這就是第三代微處理器的起點。
8086微處理器最高主頻速度為8MHz,具有16位數據通道,內存定址能力為1MB。同時英特爾還生產出與之相配合的數學協處理器i8087,這兩種晶元使用相互兼容的指令集,但i8087指令集中增加了一些專門用於對數、指數和三角函數等數學計算的指令。人們將這些指令集統一稱之為 x86指令集。雖然以後英特爾又陸續生產出第二代、第三代等更先進和更快的新型CPU,但都仍然兼容原來的x86指令,而且英特爾在後續CPU的命名上沿用了原先的x86序列,直到後來因商標注冊問題,才放棄了繼續用阿拉伯數字命名。
1979年,英特爾公司又開發出了8088。8086和8088在晶元內部均採用16位數據傳輸,所以都稱為16位微處理器,但8086每周期能傳送或接收16位數據,而8088每周期只採用8位。因為最初的大部分設備和晶元是8位的,而8088的外部8位數據傳送、接收能與這些設備相兼容。8088採用40針的DIP封裝,工作頻率為6.66MHz、7.16MHz或8MHz,微處理器集成了大約29000個晶體管。
8086和8088問世後不久,英特爾公司就開始對他們進行改進,他們將更多功能集成在晶元上,這樣就誕生了80186和80188。這兩款微處理器內部均以16位工作,在外部輸入輸出上80186採用16位,而80188和8088一樣是採用8位工作。
1981年,美國IBM公司將8088晶元用於其研製的PC機中,從而開創了全新的微機時代。也正是從8088開始,個人電腦(PC)的概念開始在全世界范圍內發展起來。從8088應用到IBM PC機上開始,個人電腦真正走進了人們的工作和生活之中,它也標志著一個新時代的開始。
Intel 80286
1982年,英特爾公司在8086的基礎上,研製出了80286微處理器,該微處理器的最大主頻為20MHz,內、外部數據傳輸均為16位,使用24位內存儲器的定址,內存定址能力為16MB。80286可工作於兩種方式,一種叫實模式,另一種叫保護方式。
在實模式下,微處理器可以訪問的內存總量限制在1兆位元組;而在保護方式之下,80286可直接訪問16兆位元組的內存。此外,80286工作在保護方式之下,可以保護操作系統,使之不像實模式或8086等不受保護的微處理器那樣,在遇到異常應用時會使系統停機。
IBM公司將80286微處理器用在先進技術微機即AT機中,引起了極大的轟動。80286在以下四個方面比它的前輩有顯著的改進:支持更大的內存;能夠模擬內存空間;能同時運行多個任務;提高了處理速度。最早PC機的速度是4MHz,第一台基於80286的AT機運行速度為6MHz至8MHz,一些製造商還自行提高速度,使80286達到了20MHz,這意味著性能上有了重大的進步。
80286的封裝是一種被稱為PGA的正方形包裝。PGA是源於PLCC的便宜封裝,它有一塊內部和外部固體插腳,在這個封裝中,80286集成了大約130000個晶體管。
IBM PC/AT微機的匯流排保持了XT的三層匯流排結構,並增加了高低位位元組匯流排驅動器轉換邏輯和高位位元組匯流排。與XT機一樣,CPU也是焊接在主板上的。
那時的原裝機僅指IBM PC機,而兼容機就是除了IBM PC以外的其它機器。在當時,生產CPU的公司除英特爾外,還有AMD及西門子公司等,而人們對自己電腦用的什麼CPU也不關心,因為AMD等公司生產的CPU幾乎同英特爾的一樣,直到486時代人們才關心起自己的CPU來。
8086~80286這個時代是個人電腦起步的時代,當時在國內使用甚至見到過PC機的人很少,它在人們心中是一個神秘的東西。到九十年代初,國內才開始普及計算機。
Intel 80386
1985年春天的時候,英特爾公司已經成為了第一流的晶元公司,它決心全力開發新一代的32位核心的CPU—80386。Intel給80386設計了三個技術要點:使用「類286」結構,開發80387微處理器增強浮點運算能力,開發高速緩存解決內存速度瓶頸。
1985年10月17日,英特爾劃時代的產品——80386DX正式發布了,其內部包含27.5萬個晶體管,時鍾頻率為12.5MHz,後逐步提高到20MHz、25MHz、33MHz,最後還有少量的40MHz產品。
80386DX的內部和外部數據匯流排是32位,地址匯流排也是32位,可以定址到4GB內存,並可以管理64TB的虛擬存儲空間。它的運算模式除了具有實模式和保護模式以外,還增加了一種「虛擬86」的工作方式,可以通過同時模擬多個8086微處理器來提供多任務能力。
80386DX有比80286更多的指令,頻率為12.5MHz的80386每秒鍾可執行6百萬條指令,比頻率為16MHz的80286快2.2倍。80386最經典的產品為80386DX-33MHz,一般我們說的80386就是指它。
由於32位微處理器的強大運算能力,PC的應用擴展到很多的領域,如商業辦公和計算、工程設計和計算、數據中心、個人娛樂。80386使32位CPU成為了PC工業的標准。
雖然當時80386沒有完善和強大的浮點運算單元,但配上80387協處理器,80386就可以順利完成許多需要大量浮點運算的任務,從而順利進入了主流的商用電腦市場。另外,30386還有其他豐富的外圍配件支持,如82258(DMA控制器)、8259A(中斷控制器)、8272(磁碟控制器)、82385(Cache控制器)、82062(硬碟控制器)等。針對內存的速度瓶頸,英特爾為80386設計了高速緩存(Cache),採取預讀內存的方法來緩解這個速度瓶頸,從此以後,Cache就和CPU成為了如影隨形的東西。
Intel 80387/80287
嚴格地說,80387並不是一塊真正意義上的CPU,而是配合80386DX的協處理晶元,也就是說,80387隻能協助80386完成浮點運算方面的功能,功能很單一。
Intel 80386SX
1989年英特爾公司又推出准32位微處理器晶元80386SX。這是Intel為了擴大市場份額而推出的一種較便宜的普及型CPU,它的內部數據匯流排為32位,外部數據匯流排為16位,它可以接受為80286開發的16位輸入/輸出介面晶元,降低整機成本。
80386SX推出後,受到市場的廣泛的歡迎,因為80386SX的性能大大優於80286,而價格只是80386的三分之一。
Intel 80386SL/80386DL
英特爾在1990年推出了專門用於筆記本電腦的80386SL和80386DL兩種型號的386晶元。這兩個類型的晶元可以說是80386DX/SX的節能型,其中,80386DL是基於80386DX內核,而80386SL是基於80386SX內核的。這兩種類型的晶元,不但耗電少,而且具有電源管理功能,在CPU不工作的時候,自動切斷電源供應。
Motorola 68000
摩托羅拉的68000是最早推出的32位微微處理器,當時是1984年,推出後,性能超群,並獲得如日中天的蘋果公司青睞,在自己的劃時代個人電腦「PC-MAC」中採用該晶元。但80386推出後,日漸沒落。
AMD Am386SX/DX
AMD的Am386SX/DX是兼容80386DX的第三方晶元,性能上和英特爾的80386DX相差無己,也成為當時的主流產品之一。
IBM 386SLC
這個是由IBM在研究80386的基礎上設計的,和80386完全兼容,由英特爾生產製造。386SLC基本上是一個在80386SX的基礎上配上內置Cache,同時包含80486SX的指令集,性能也不錯。
Intel 80486
1989年,我們大家耳熟能詳的80486晶元由英特爾推出。這款經過四年開發和3億美元資金投入的晶元的偉大之處在於它首次實破了100萬個晶體管的界限,集成了120萬個晶體管,使用1微米的製造工藝。80486的時鍾頻率從25MHz逐步提高到33MHz、40MHz、50MHz。
80486是將80386和數學協微處理器80387以及一個8KB的高速緩存集成在一個晶元內。80486中集成的80487的數字運算速度是以前80387的兩倍,內部緩存縮短了微處理器與慢速DRAM的等待時間。並且,在80x86系列中首次採用了RISC(精簡指令集)技術,可以在一個時鍾周期內執行一條指令。它還採用了突發匯流排方式,大大提高了與內存的數據交換速度。由於這些改進,80486的性能比帶有80387數學協微處理器的80386 DX性能提高了4倍。
隨著晶元技術的不斷發展,CPU的頻率越來越快,而PC機外部設備受工藝限制,能夠承受的工作頻率有限,這就阻礙了CPU主頻的進一步提高。在這種情況下,出現了CPU倍頻技術,該技術使CPU內部工作頻率為微處理器外頻的2~3倍,486 DX2、486 DX4的名字便是由此而來。
Intel 80486 DX
常見的80486 CPU有80486 DX-33、40、50。486 CPU與386 DX一樣內外都是32位的,但是最慢的486 CPU也比最快的386 CPU要快,這是因為486 SX/DX執行一條指令,只需要一個振盪周期,而386DX CPU卻需要兩個周期。
Intel 80486 SX
因為80486 DX CPU具有內置的浮點協微處理器,功能強大,當然價格也就比較昂貴。為了適應普通的用戶的需要,尤其是不需要進行大量浮點運算的用戶,英特爾公司推出了486 SX CPU。80486 SX主板上一般都有80487協微處理器插座,如果需要浮點協微處理器的功能,可以插上一個80487協微處理器晶元,這樣就等同於486 DX了。常見的80486 SX CPU有:80486 SX-25、33。
Intel 80486 DX2/DX4
其實這種CPU的名字與頻率是有關的,這種CPU的內部頻率是主板頻率的兩/四倍,如80486 DX2-66,CPU的頻率是66MHz,而主板的頻率只要是33MHz就可以了。
Intel 80486 SL CPU
80486 SL CPU最初是為筆記本電腦和其他便攜機設計的,與386SL一樣,這種晶元使用3.3V而不是5V電源,而且也有內部切斷電路,使微處理器和其他一些可選擇的部件在不工作時,處於休眠狀態,這樣就可以減少筆記本電腦和其他便攜機的能耗,延長使用時間。
Intel 486 OverDrive
升級486 SX可以在主板的協微處理器插槽上安裝一個80487SX晶元,使其等效於486 DX,但是這樣升級後,只是增加了浮點協微處理器的能力,並沒有提高系統的速度。為了提高系統的速度,還有另外一種升級的方法,就是在協微處理器插槽上插上一個486 OverDrive CPU,它的原理與486 DX2 CPU一樣,其內部操作速度可以是外部速度的兩倍。如一個20MHz的主板上安插了OverDrive CPU之後,CPU內部的操作速度可以達到40MHz。486 OverDrive CPU也有浮點協微處理器的功能,常見的有:OverDrive-50、66、80。
TI 486 DX
作為全球知名的半導體廠商之一,美國德州儀器(TI)也在486時代異軍突起,它自行生產了486 DX系列CPU,尤其在486DX2成為主流後,其DX2-80因較高的性價比成為當時主流產品之一,TI 486最高主頻為DX4-100,但其後再也沒有進入過CPU市場。
Cyrix 486DLC
這是Cyrix公司生產的486 CPU,說它是486 CPU,是指它的效率上逼近486 CPU,卻並不是嚴格意義上的486 CPU,這是由486 CPU的特點而定的。486DLC CPU只是將386DX CPU與1K Cache組合在一塊晶元里,沒有內含浮點協微處理器,執行一條指令需要兩個振盪周期。但是由於486DLC CPU設計精巧,486DLC-33 CPU的效率逼近英特爾公司的486 SX-25,而486DLC-40 CPU則超過了486 SX-25,並且486DLC-40 CPU的價格比486 SX-25便宜。486DLC CPU是為了升級386DM而設計的,如果原來有一台386電腦,想升級到486,但是又不想更換主板,就可以拔下原來的386 CPU,插上一塊486DLC CPU就可以了。
Cyrix 5x86
自從英特爾另闢蹊徑,開發了Pentium之後,Cyrix也很快推出了自己的新一代產品5x86。它仍然延用原來486系列的CPU插座,而將主頻從100MHz提高到120MHz。5x86比起486來說性能是有所增加,可是比起Pentium來說,不但浮點性能遠遠不足,就連Cyrix一向自豪的整數運算性能也不那麼高超,給人一種比上不足比下有餘的感覺。由於5x86可以使用486的主板,因此一般將它看成是過渡產品。
AMD 5x86
AMD 486DX是AMD公司在 486市場的利器,它內置16KB回寫緩存,並且開始了單周期多指令的時代,還具有分頁虛擬內存管理技術。由於後期TI推出了486DX2-80,價格非常低,英特爾又推出了Pentium系列,AMD為了搶占市場的空缺,推出了5x86系列CPU。它是486級最高主頻的產品,為5x86-120及133。它採用了一體的16K回寫緩存,0.35微米工藝,33×4的133頻率,性能直指Pentiun 75,並且功耗要小於Pentium。
Intel Pentium
1993年,全面超越486的新一代586 CPU問世,為了擺脫486時代微處理器名稱混亂的困擾,英特爾公司把自己的新一代產品命名為Pentium(奔騰)以區別AMD和Cyrix的產品。AMD和Cyrix也分別推出了K5和6x86微處理器來對付晶元巨人,但是由於奔騰微處理器的性能最佳,英特爾逐漸占據了大部分市場。
Pentium最初級的CPU是Pentium 60和Pentium 66,分別工作在與系統匯流排頻率相同的60MHz和66MHz兩種頻率下,沒有我們現在所說的倍頻設置。
早期的奔騰75MHz~120MHz使用0.5微米的製造工藝,後期120MHz頻率以上的奔騰則改用0.35微米工藝。經典奔騰的性能相當平均,整數運算和浮點運算都不錯。
Intel Pentium MMX
為了提高電腦在多媒體、3D圖形方面的應用能力,許多新指令集應運而生,其中最著名的三種便是英特爾的MMX、SSE和AMD的3D NOW!。 MMX(MultiMedia Extensions,多媒體擴展指令集)是英特爾於1996年發明的一項多媒體指令增強技術,包括57條多媒體指令,這些指令可以一次處理多個數據,MMX技術在軟體的配合下,就可以得到更好的性能。
多能奔騰(Pentium MMX)的正式名稱就是「帶有MMX技術的Pentium」,是在1996年底發布的。從多能奔騰開始,英特爾就對其生產的CPU開始鎖倍頻了,但是MMX的CPU超外頻能力特別強,而且還可以通過提高核心電壓來超倍頻,所以那個時候超頻是一個很時髦的行動。超頻這個詞語也是從那個時候開始流行的。
多能奔騰是繼Pentium後英特爾又一個成功的產品,其生命力也相當頑強。多能奔騰在原Pentium的基礎上進行了重大的改進,增加了片內16KB數據緩存和16KB指令緩存,4路寫緩存以及分支預測單元和返回堆棧技術。特別是新增加的57條MMX多媒體指令,使得多能奔騰即使在運行非MMX優化的程序時,也比同主頻的Pentium CPU要快得多。
這57條MMX指令專門用來處理音頻、視頻等數據。這些指令可以大大縮短CPU在處理多媒體數據時的等待時間,使CPU擁有更強大的數據處理能力。與經典奔騰不同,多能奔騰採用了雙電壓設計,其內核電壓為2.8V,系統I/O電壓仍為原來的3.3V。如果主板不支持雙電壓設計,那麼就無法升級到多能奔騰。
多能奔騰的代號為P55C,是第一個有MMX技術(整量型單元執行)的CPU,擁有16KB數據L1 Cache,16KB指令L1 Cache,兼容SMM,64位匯流排,528MB/s的頻寬,2時鍾等待時間,450萬個晶體管,功耗17瓦。支持的工作頻率有:133MHz、150MHz、166MHz、200MHz、233MHz。
Intel Pentium Pro
曾幾何時,Pentium Pro是高端CPU的代名詞,Pentium Pro所表現的性能在當時讓很多人大吃一驚,但是Pentium Pro是32位數據結構設計的CPU,所以Pentium Pro運行16位應用程序時性能一般,但仍然是32位的贏家,但是後來,MMX的出現使它黯然失色。
Pentium Pro(高能奔騰,686級的CPU)的核心架構代號為P6(也是未來PⅡ、PⅢ所使用的核心架構),這是第一代產品,二級Cache有256KB或512KB,最大有1MB的二級Cache。工作頻率有:133/66MHz(工程樣品),150/60MHz、166/66MHz、180/60MHz、200/66MHz。
AMD K5
K5是AMD公司第一個獨立生產的x86級CPU,發布時間在1996年。由於K5在開發上遇到了問題,其上市時間比英特爾的Pentium晚了許多,再加上性能不好,這個不成功的產品一度使得AMD的市場份額大量喪失。K5的性能非常一般,整數運算能力不如Cyrix的6x86,但是仍比Pentium略強,浮點運算能力遠遠比不上Pentium,但稍強於Cyrix。綜合來看,K5屬於實力比較平均的那一種產品。K5低廉的價格顯然比其性能更能吸引消費者,低價是這款CPU最大的賣點。
AMD K6
AMD 自然不甘心Pentium在CPU市場上呼風喚雨,因此它們在1997年又推出了K6。K6這款CPU的設計指標是相當高的,它擁有全新的MMX指令以及64KB L1 Cache(比奔騰MMX多了一倍),整體性能要優於奔騰MMX,接近同主頻PⅡ的水平。K6與K5相比,可以平行地處理更多的指令,並運行在更高的時鍾頻率上。AMD在整數運算方面做得非常成功,K6稍微落後的地方是在運行需要使用到MMX或浮點運算的應用程序方面,比起同樣頻率的Pentium 要差許多。
K6擁有32KB數據L1 Cache,32KB指令L1 Cache,集成了880萬個晶體管,採用0.35微米技術,五層CMOS,C4工藝反裝晶片,內核面積168平方毫米(新產品為68平方毫米),使用Socket7架構。
Cyrix 6x86/MX
Cyrix 也算是一家老資格的CPU開發商了,早在x86時代,它和英特爾,AMD就形成了三雄並立的局面。
自從Cyrix與美國國家半導體公司合並後,使它終於擁有了自己的晶元生產線,成品也日益完善和完備。Cyrix的6x86是投放到市場上與Pentium兼容的微處理器。
IDT WinChip
美國IDT公司(Integrated Device Technology)作為新加入此領域的CPU生產廠商,在1997年推出的第一個微微處理器產品是WinChip(即C6),在整個CPU市場上所佔的份額還不足1%。1998年5月,IDT宣布了它的第二代產品WinChip 2 。
WinChip 2在原有WinChip的基礎上作了一些改進,增加了一個雙指令的MMX單元,增強了浮點運算功能。改進後的WinChip 2比相同頻率的WinChip性能提高約10%,基本達到Intel Pentium微處理器的性能。
Intel PentiumⅡ
1997年~1998年是CPU市場競爭異常激烈的一年,這一時期的CPU晶元異彩紛呈,令人目不暇接。
PentiumⅡ的中文名稱叫「奔騰二代」,它有Klamath、Deschutes、Mendocino、Katmai等幾種不同核心結構的系列產品,其中第一代採用Klamath核心,0.35微米工藝製造,內部集成750萬個晶體管,核心工作電壓為2.8V。
PentiumⅡ微處理器採用了雙重獨立匯流排結構,即其中一條匯流排連通二級緩存,另一條負責主要內存。PentiumⅡ使用了一種脫離晶元的外部高速L2 Cache,容量為512KB,並以CPU主頻的一半速度運行。作為一種補償,英特爾將PentiumⅡ的L1 Cache從16KB增至32KB。另外,為了打敗競爭對手,英特爾第一次在PentiumⅡ中採用了具有專利權保護的Slot 1介面標准和SECC(單邊接觸盒)封裝技術。
1998年4月16日,英特爾第一個支持100MHz額定外頻的、代號為Deschutes的350、400MHz CPU正式推出。採用新核心的PentiumⅡ微處理器不但外頻提升至100MHz,而且它們採用0.25微米工藝製造,其核心工作電壓也由2.8V降至2.0V,L1 Cache和L2 Cache分別是32KB、512KB。支持晶元組主要是Intel的440BX。
在1998年至1999年間,英特爾公司推出了比PentiumⅡ功能更強大的CPU--Xeon(至強微處理器)。該款微處理器採用的核心和PentiumⅡ差不多,0.25微米製造工藝,支持100MHz外頻。Xeon最大可配備2MB Cache,並運行在CPU核心頻率下,它和PentiumⅡ採用的晶元不同,被稱為CSRAM(Custom StaticRAM,定製靜態存儲器)。除此之外,它支持八個CPU系統;使用36位內存地址和PSE模式(PSE36模式),最大800MB/s的內存帶寬。Xeon微處理器主要面向對性能要求更高的伺服器和工作站系統,另外,Xeon的介面形式也有所變化,採用了比Slot 1稍大一些的Slot 2架構(可支持四個微處理器)。
Intel Celeron(賽揚)
英特爾為進一步搶占低端市場,於1998年4月推出了一款廉價的CPU—Celeron(中文名叫賽揚)。最初推出的Celeron有266MHz、300MHz兩個版本,且都採用Covington核心,0.35微米工藝製造,內部集成1900萬個晶體管和32KB一級緩存,工作電壓為2.0V,外頻66MHz。Celeron與PentiumⅡ相比,去掉了片上的L2 Cache,此舉雖然大大降低了成本,但也正因為沒有二級緩存,該微處理器在性能上大打折扣,其整數性能甚至不如Pentium MMX。
為彌補缺乏二級緩存的Celeron微處理器性能上的不足,進一步在低端市場上打擊競爭對手,英特爾在Celeron266、300推出後不久,又發布了採用Mendocino核心的新Celeron微處理器—Celeron300A、333、366。與舊Celeron不同的是,新Celeron採用0.25微米工藝製造,同時它採用Slot 1架構及SEPP封裝形式,內建32KB L1 Cache、128KB L2 Cache,且以CPU相同的核心頻率工作,從而大大提高了L2 Cache的工作效率。
AMD K6-2
AMD於1998年4月正式推出了K6-2微處理器。它採用0.25微米工藝製造,晶元面積減小到了68平方毫米,晶體管數目也增加到930萬個。另外,K6-2具有64KB L1 Cache,二級緩存集成在主板上,容量從512KB到2MB之間,速度與系統匯流排頻率同步,工作電壓為2.2V,支持Socket 7架構。
K6-2是一個K6晶元加上100MHz匯流排頻率和支持3D Now!浮點指令的「結合物」。3D Now!技術是對x86體系的重大突破,它大大加強了處理3D圖形和多媒體所需要的密集浮點運算性能。此外,K6-2支持超標量MMX技術,支持100MHz匯流排頻率,這意味著系統與L2緩存和內存的傳輸率提高近50%,從而大大提高了整個系統的表現。
Cyrix MⅡ
作為Cyrix公司獨自研發的最後一款微處理器,Cyrix MⅡ是於1998年3月開始生產的。除了具有6x86本身的特性外,該微處理器還支持MMX指令,其核心電壓為2.9V,具有256位元組指令;3.5X倍頻;核心內集成650萬個晶體管,功耗20.6瓦;64KB一級緩存。
Rise mp6
Rise公司是一家成立於1993年11月的美國公司,主要生產x86兼容的CPU,在1998年推出了mP6 CPU。mp6不僅價格便宜,而且性能優異,有著很好的多媒體性能和強大的浮點運算。mp6使用Socket 7/Super 7兼容插座,只有16KB的一級緩存。
Intel PentiumⅢ
1999年春節剛過,英特爾公司就發布了採用Katmai核心的新一代微處理器—PentiumⅢ。該微處理器除採用0.25微米工藝製造,內部集成950萬個晶體管,Slot 1架構之外,它還具有以下新特點:系統匯流排頻率為100MHz;採用第六代CPU核心—P6微架構,針對32位應用程序進行優化,雙重獨立匯流排;一級緩存為32KB(16KB指令緩存加16KB數據緩存),二級緩存大小為512KB,以CPU核心速度的一半運行;採用SECC2封裝形式;新增加了能夠增強音頻、視頻和3D圖形效果的SSE(Streaming SIMD Extensions,數據流單指令多數據擴展)指令集,共70條新指令。PentiumⅢ的起始主頻速度為450MHz。
和PentiumⅡ Xeon一樣,英特爾同樣也推出了面向伺服器和工作站系統的高性能CPU—PentiumⅢ Xeon至強微處理器。除前期的PentiumⅡ Xeon500、550採用0.25微米技術外,該款微處理器是採用0.18微米工藝製造,Slot 2架構和SECC封裝形式,內置32KB一級緩存和512KB二級緩存,工作電壓為1.6V。
Intel CeleronⅡ
為進一步鞏固低端市場優勢,英特爾於2000年3月29日推出了採用Coppermine核心CeleronⅡ。該款微處理器同樣採用0.18微米工藝製造,核心集成1900萬個晶體管,採用FC-PGA封裝形式,它和賽揚Mendocino一樣內建128KB和CPU同步運行的L2 Cache,故其內核也稱為Coppermine 128。CeleronⅡ不支持多微處理器系統。但是,CeleronⅡ的外頻仍然只有66MHz,這在很大程度上限制了其性能的發揮。
AMD K6-Ⅲ
AMD於1999年2月推出了代號為「Sharptooth」(利齒)的K6-Ⅲ,它是該公司最後一款支持Super 7架構和CPGA封裝形式的CPU,採用0.25微米製造工藝、內核面積是135平方毫米,集成了2130萬個晶體管,工作電壓為2.2V/2.4V。