Lập trình giao tiếp nối tiếp

Ngôn ngữ Visual Basic có module phần mềm MSCOMM.OCX

phục vụ cho truyền thông, với Visual Basic 4.0 là MSCOMM16.OCX

còn với Visual Basic 6.0 là MSCOMM32.OCX

Muốn cài trình đơn truyền thông vào thanh công cụ ta vào

Project- Components – Controls chọn Microsoft Comm Control

6.0/ OK (Hình 8.1), biểu tượng hình điện thoại sẽ hiện trên thanh

công cụ. Có thể nhắp chuột kép để đưa vào form của chương

trình. Các bước trên có thể làmtắt bằng phím Ctrl T. Thành

phần Comm khi mới đưa vào form thường được gán tên MSComm1

cho cổng Com1 và ta có thể sửa tên hay thay đổi cổng com tùy ý.

pdf25 trang | Chia sẻ: luyenbuizn | Lượt xem: 990 | Lượt tải: 0download
Bạn đang xem trước 20 trang nội dung tài liệu Lập trình giao tiếp nối tiếp, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 8 LẬP TRÌNH GIAO TIẾP NỐI TIẾP 8.1 LẬP TRÌNH TRONG DOS: Ngôn ngữ QBASIC Lệnh khởi động cổng COM n: OPEN “COM n, [Baud], [Parity], [Data], [Stop]” for RANDOM as #m trong đó n = 1, 2, 3, 4; m = 1 ÷ 255 Ví dụ: OPEN “COM 2, 9600, E, 7, 2” FOR RANDOM AS #1 Lệnh xuất ra một chuỗi S $ PRINT #1 , S $ Lệnh đọc vào một chuỗi R $ INPUT # 1, R $ Ngoài ra còn các lệnh truy xuất thanh ghi của vi mạch UART Ngôn ngữ Pascal và C Dùng các lệnh truy xuất thanh ghi như ở chương 7 Trong MS DOS ở dòng lệnh đánh MODE COM n : 96, E, 7, 1 sẽ mở COM n 8.2 LẬP TRÌNH NGÔN NGỮ VISUAL BASIC 6.0 Ngôn ngữ Visual Basic có module phần mềm MSCOMM.OCX phục vụ cho truyền thông, với Visual Basic 4.0 là MSCOMM16.OCX còn với Visual Basic 6.0 là MSCOMM32.OCX Muốn cài trình đơn truyền thông vào thanh công cụ ta vào Project- Components – Controls chọn Microsoft Comm Control 6.0/ OK (Hình 8.1), biểu tượng hình điện thoại sẽ hiện trên thanh công cụ. Có thể nhắp chuột kép để đưa vào form của chương trình. Các bước trên có thể làm tắt bằng phím Ctrl T. Thành phần Comm khi mới đưa vào form thường được gán tên MSComm1 cho cổng Com1 và ta có thể sửa tên hay thay đổi cổng com tùy ý. Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 211 Thành phố Hồ Chí Minh, tháng 4 năm 2006 Các tính chất chính của trình đơn là Commport, DTREnable, EOFEnable, Handshaking, InBuffersize, InputLen, InputMode, NullDiscard, OutBuffersize, ParityReplace, Rthreshold, RTSEnable, Settmgs, Sthreshold… được đặt khi viết chương trình, có thể thay đổi khi chạy chương trình bằng các lệnh điều khiển. Tính chất CommPort Đặt cổng com được sử dụng Object.CommPort [= Value] Value = 1 đến 16, mặc định là 1 khi khởi động Visual Basic. Tính chất này phải đặt trước khi mở cổng, nếu biểu thức trong ngoặc không có thì trả về số cổng com đang hoạt động. Tác giả: TS Nguyễn Đức Thành Trang 212 Đặt cấu hình cổng Object.Settings [= Value] Value = “BBBB, P, D, S” Gía trị mặc định là “9600, N, 8, 1”. Trong trường hợp đặt sai giá trị sẽ báo sự cố. Sau đây là các giá trị cho phép: • Baud rate: 110, 300, 600, 1200, 2400, 9600 (Default), 14400, 19200, 28800, 38400, 56000, 128000, 256000 • Parity bit: E (even), M (Mark), N (Default), O (odd), S (Space) • Data bit: 4, 5, 6, 7, 8 (Default) • Stop bit: 1, 1.5, 2 Ví dụ: MSComm2. Settings = “9600, N, 8, 1” Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 213 Thành phố Hồ Chí Minh, tháng 4 năm 2006 Mở cổng Object.PortOpen [= True/ False] Value = True : mở cổng Value = False : đóng cổng và xóa bộ đệm truyền thu, Cổng tự động đóng khi kết thúc chương trình áp dụng. Nhập dữ liệu String$= Object.Input Dữ liệu chuỗi ở bộ đệm thu được đọc vào biến String$ . Liên quan đến đọc dữ liệu có các lệnh sau: Object.InputLen [= numByte%] InputLen: qui định số ký tự đọc bởi Input. Chọn InputLen = 0 sẽ cho đọc toàn bộ vùng bộ đệm. Object.InbufferSize = [numbyte%] InBufferSize đặt và trả về kích thước theo byte của đệm thu, mặc định là 1024. Object.InbufferCount [= Count%] InbufferCount: cho biết số ký hiệu có trong bộ đệm nhận. Xóa bộ đệm bằng cách cho InbufferCount = 0 Object.InputMode [= value] InputMode: cho biết loại dữ liệu là văn bản hay nhị phân Value = 0 : ComInputModeText Value = 1 : ComInputModeBinary Ví dụ: Dim Buffer as Variant Dim Arr() as Byte MSComm1.CommPort = 1 MSComm1.PortOpen = True ‘Set InputMode to read binary data MSComm1.InputMode = comInputModeBinary Do Until MSComm1.InBufferCount > 10 DoEvents Loop Buffer = MSComm1.Input ' Assign to byte array for processing Tác giả: TS Nguyễn Đức Thành Trang 214 Arr = Buffer Xuất dữ liệu Object.Output [= value] Xuất chuỗi ký tự hay chuỗi nhị phân ra cổng COM. Giống như nhập dữ liệu ta có các lệnh hỗ trợ. OutBufferSize: đặt và trả lại kích thước bộ đệm truyền OutBufferCount: trả lại số ký tự trong bộ đệm truyền. Ví dụ: gởi ký tự nhấn phím Private Sub Form_KeyPress (KeyAscii As Integer) Dim Buffer as Variant MSComm1.CommPort = 1 MSComm1.PortOpen = True Buffer = Chr$(KeyAscii) MSComm1.Output = Buffer End Sub Ví dụ: ‘ gởi chuỗi ký tự MsComm1.Output = "This is a text string” ‘ gởi số nhị phân Dim Out( ) As Byte MsComm1.Output = Out Gởi tín hiệu Break object.Break [= True/False] Đọc chân DCD inCD= object. CDHolding nếu inCD True thì DCD ở mức cao, nếu False DCD ở mức thấp. Đặt thời gian chờ sóng mang object. CDTimeout [= milliseconds] Chờ khoảng thời gian cho DCD ở mức cao, nếu hết thời gian mà CDHolding = false thì tạo sự kiện onComm CDTO (carrier detect Timeout Error). Đọc CTS Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 215 Thành phố Hồ Chí Minh, tháng 4 năm 2006 object. CTS Holding True: mức 1, False: mức 0 Đặt thời gian chờ CTS Khi DTE gởi RTS thì modem phải gởi trả lại CTS, tính chất object. CTSTimeout định thời gian chờ, nếu quá thời gian đó mà không có CTS thì tạo sự kiện CTSTO. Đọc DSR object. DSRHolding Đặt thời gian chờ DSR object. DSRTimeout Điều khiển DTR object. DTREnable [=True/False] nếu True thì DTR mức 1 khi mở cổng và mức 0 khi đóng cổng, nếu False thì DTR ở mức 0 Điều khiển RTS object. RTSEnable [ =True/False] Khi True RTS sẽ ở mức 1 khi mở cổng và mức 0 khi đóng cổng Sthreshold: đặt số byte có trong bộ đệm truyền để báo sự kiện. Nếu Sthreshold = 1 thì sẽ gọi onComm khi bộ đệm truyền rỗng. Nếu Sthreshold = 0 thì không gọi. Đặt số byte của bộ đệm thu tối thiểu để báo sự kiện object. Rthreshold [= value] Nếu đặt bằng 1 thì sẽ gọi onComm khi nhận được 1 ký tự. Nếu đặt bằng 0 thì không gọi. Giao thức bắt tay object.Handshaking [= value] Value = 0 không bắt tay Value = 1 bắt tay theo RTS/CTS = 2 XON/XOFF = 3 RTS/XON/XOFF Ví dụ: Private Sub Form_Load ( ) Dim Buffer$ as string Tác giả: TS Nguyễn Đức Thành Trang 216 ‘ Dùng COM 1, 9600 baud, không parity, 8 bit data, 1 bit stop MSComm1. Comport = 1 MSComm1. Settings = “9600, N, 8, 1” ‘ Đọc toàn bộ bộ đệm MSComm1. Inputlen = 0 ‘ Mở cổng và gởi lệnh đến modem chế độ trả lời bằng chữ MSComm1. PortOpen = True MSComm1. Output = “ATV1Q0” & Chr$(13) ‘ Chờ trả lời “OK”, nếu có OK thì đóng cổng Do DoEvents Buffer$ = Buffer$ & MSComm1. Input Loop Until InStr (Buffer$, “OK” & vbCrLf) MSComm1. PortOpen = False End Sub Chương trình trên dùng kỹ thuật hỏi vòng. Ta có thể dùng kỹ thuật sự kiện object.CommEvent. Khi có sự kiện xảy ra chương trình cho cổng object_OnComm () sẽ được gọi để xử lý các sự kiện hay các lỗi. Ví dụ: Private Sub MSComm1_OnComm ( ) Select Case MSComm1. CommEvent ‘ Xử lý sự kiện hay lỗi bằng cách đặt lệnh dưới mỗi phát biểu Case ‘ Lỗi Case ComEventBreak ‘Nhận Break Case ComEventFrame ‘Sai frame Case ComEventOverrun ‘Mất dữ liệu Case ComEventRXOver ‘Đệm thu tràn Case ComEventRXParity ‘Sai Parity Case ComEventTXFull ‘Đệm phát đầy Case ComEventDCB ‘Sai khi đọc DCB ‘ Sự kiện Case ComEvCD ‘Đường CD thay đổi Case ComEvCTS ‘CTS thay đổi Case ComEvDSR ‘DSR thay đổi từ 1 xuống 0 Case ComEvRing ‘RI thay đổi Case ComEvReceive ‘Số byte đệm thu đạt mức Rthreshold Case ComEvSend ‘Số byte đệm phát ít hơn Sthreshold Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 217 Thành phố Hồ Chí Minh, tháng 4 năm 2006 Case ComEvEOF ‘Nhận ký tự EOF kết thúc file (mã ASCII 26) trong chuỗi nhập End Select End Sub. Các lỗi khi sử dụng MSComm trình bày trong bảng sau Lỗi Gía trị Miêu tả comInvalidPropertyValue 380 Sai thuộc tính comSetNotSupported 383 Thuộc tính chỉ đọc comGetNotSupported 394 Thuộc tính chỉ đọc comPortOpen 8000 Không thực hiện khi cổng đã mở 8001 Gía trị Timeout phải lớn hơn 0 comPortInvalid 8002 Số cổng không giá trị 8003 Thuộc tính chỉ có khi chương trình chạy 8004 Thuộc tính chỉ đọc khi chương trình chạy comPortAlreadyOpen 8005 Cổng đã mở rồi 8006 Số nhận dạng thiết bị không phù hợp 8007 Vận tốc truyền không phù hợp 8008 Số byte đã đặt không giá tri 8009 Thông số mặc định sai 8010 Thiết bị không có sẵn 8011 The function cannot allocate the queues comNoOpen 8012 Thiết bị không mở 8013 Thiết bị đã mở 8014 Could not enable comm notification comSetCommStateFailed 8015 Không thể đặt trạng thái truyền thông 8016 Không thể đạt mặt nạ che comPortNotOpen 8018 Hoạt động chỉ thực hiện khi cổng mở 8019 Thiết bị bận comReadError 8020 Error reading comm device comDCBError 8021 Internal error retrieving device control block for the port Ví dụ: chương trình quay số điện thoại qua modem Option Explicit ' Variable names beginning with A through Z default to Integer. DefInt A-Z Tác giả: TS Nguyễn Đức Thành Trang 218 Dim CancelFlag, Default$ Private Sub CancelButton_Click() ' CancelFlag tells the Dial procedure to exit. CancelFlag = True CancelButton.Enabled = False End Sub Private Sub Dial(Number$) Dim DialString$, FromModem$, dummy, i As Double i = 0 DialString$ = "ATDT" + Number$ + vbCr ' Dial the number. MSComm1.Output = DialString$ ' Wait for "OK" to come back from the modem. Do i = i + 1 dummy = DoEvents() ' If there is data in the buffer, then read it. If MSComm1.InBufferCount Then FromModem$ = FromModem$ + MSComm1.Input ' Check for "OK". If InStr(FromModem$, "OK") Then ' Notify the user to pick up the phone. Beep MsgBox "Please pick up the phone and either press Enter or click OK" Exit Do End If End If ' Did the user choose Cancel? If i > 100000 Then Beep MsgBox "TimeOut, Please check cable and modem" Exit Do End If If CancelFlag Then CancelFlag = False Exit Do End If Loop ' Disconnect the modem. Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 219 Thành phố Hồ Chí Minh, tháng 4 năm 2006 MSComm1.Output = "ATH" + vbCr End Sub Private Sub DialButton_Click() Dim Number$, Temp$ DialButton.Enabled = False QuitButton.Enabled = False CancelButton.Enabled = True ' Get the number to dial. Number$ = InputBox$("Enter phone number:", , Default$) If Number$ = "" Then DialButton.Enabled = True QuitButton.Enabled = True CancelButton.Enabled = False Exit Sub End If Temp$ = Status Default$ = Number$ Status = "Dialing - " + Number$ ' Dial the selected phone number. Dial Number$ DialButton.Enabled = True QuitButton.Enabled = True CancelButton.Enabled = False Status = Temp$ End Sub Private Sub Form_Load() Default$ = "8654357" MSComm1.CommPort = 1 MSComm1.Settings = "9600,N,8,1" On Error Resume Next MSComm1.PortOpen = True If Err Then MsgBox "COM1: not available. Change the CommPort property to another port." Exit Sub End If MSComm1.InBufferCount = 0 MSComm1.InputLen = 0 End Sub Private Sub QuitButton_Click() Tác giả: TS Nguyễn Đức Thành Trang 220 ' Close the port. MSComm1.PortOpen = False End End Sub Ví dụ: ghép nối vi điều khiển 8951 điều khiển port 0 ORG 0000H MOV IE,#00000000B MOV TMOD,#00100000 MOV TL1#,0FDH MOV TH1,#0FDH MOV SCON,#01010000B SETB TR1 MOV P0,#00000000B INDEX: ACALL SUB_RXD ACALL LEDOFF ACALL LED1 ACALL LED2 ACALL LED3 ACALL LED4 ACALL LED5 ACALL LED6 ACALL LED7 SJMP INDEX RXD : JNB RI,$ CLR RI MOV A,SBUF RET LEDOFF: CJNE A,#30H,NEXT MOV P0,#00000000B ACALL SUB_TXD SJMP INDEX LED1: CJNE A,#31H,NEXT CPL P0.0 ACALL SUB_TXD SJMP INDEX LED2: CJNE A,#32H,NEXT CPL P0.1 ACALL SUB_TXD SJMP INDEX Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 221 Thành phố Hồ Chí Minh, tháng 4 năm 2006 LED3: CJNE A,#33H,NEXT CPL P0.2 ACALL SUB_TXD SJMP INDEX LED4: CJNE A,#34H,NEXT CPL P0.3 ACALL SUB_TXD SJMP INDEX LED5: CJNE A,#35H,NEXT CPL P0.4 ACALL SUB_TXD SJMP INDEX LED6: CJNE A,#36H,NEXT CPL P0.5 ACALL SUB_TXD SJMP INDEX LED7: CJNE A,#37H,NEXT CPL P0.6 ACALL SUB_TXD SJMP INDEX NEXT: RET TXD : MOV SBUF,#43 JNB TI,$ CLR TI RET END Chương trình máy tính Tác giả: TS Nguyễn Đức Thành Trang 222 Private Sub Command8_Click() ‘ Communication Setting On Error GoTo Errlabel MSComm1.Settings = Text1.Text MSComm1.CommPort = Combo1.ListIndex + 1 MSComm1.RThreshold = 1 MSComm1.PortOpen = True MSComm1.InputLen = 0 Exit Sub Errlabel: If Err.Number = 8002 Then MsgBox "Select com Port", vbInformation, "8051 Control I/O" End Sub Private Sub Command1_Click() MSComm1.Output = "1" valLED1 = Not valLED1 End Sub Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 223 Thành phố Hồ Chí Minh, tháng 4 năm 2006 Private Sub Command2_Click() MSComm1.Output = "2" valLED2 = Not valLED2 End Sub Private Sub Command3_Click() MSComm1.Output = "3" valLED3 = Not valLED3 End Sub Private Sub Command4_Click() MSComm1.Output = "4" valLED4 = Not valLED4 End Sub Private Sub Command5_Click() MSComm1.Output = "5" valLED5 = Not valLED5 End Sub Private Sub Command6_Click() MSComm1.Output = "6" valLED6 = Not valLED6 End Sub Private Sub Command7_Click() MSComm1.Output = "7" valLED7 = Not valLED7 End Sub Private Sub Command9_Click() MSComm1.Output = "0" valLED = Not valLED End Sub Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive Dim Buffer As Variant Buffer = MSComm1.Input Label2.Caption = "Return = " & Buffer If Buffer = "C" Then If valLED = True Then For x = 0 To 7 Step 1 Shape1(x).FillColor = &HFFFFFF Next Shape1(0).FillColor = &HFF& valLED1 = False valLED2 = False valLED3 = False valLED4 = False valLED5 = False valLED6 = False valLED7 = False Tác giả: TS Nguyễn Đức Thành Trang 224 Command9.Caption = "ON ALL" Exit Sub Else Shape1(0).FillColor = &HFFFFFF Command9.Caption = "OFF ALL" End If If valLED1 = True Then Shape1(1).FillColor = &HFF& Else Shape1(1).FillColor = &HFFFFFF End If If valLED2 = True Then Shape1(2).FillColor = &HFF& Else Shape1(2).FillColor = &HFFFFFF End If If valLED3 = True Then Shape1(3).FillColor = &HFF& Else Shape1(3).FillColor = &HFFFFFF End If If valLED4 = True Then Shape1(4).FillColor = &HFF& Else Shape1(4).FillColor = &HFFFFFF End If If valLED5 = True Then Shape1(5).FillColor = &HFF& Else Shape1(5).FillColor = &HFFFFFF End If If valLED6 = True Then Shape1(6).FillColor = &HFF& Else Shape1(6).FillColor = &HFFFFFF End If If valLED7 = True Then Shape1(7).FillColor = &HFF& Else Shape1(7).FillColor = &HFFFFFF End If End If End Select Errlabel: Exit Sub End Sub Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 225 Thành phố Hồ Chí Minh, tháng 4 năm 2006 8.3 LẬP TRÌNH DÙNG DELPHI 5.0 VÀ VISUAL C++6.0 MSComm có thể cài trong Delphi theo các bước sau: Vào menu Component – Import ActiveX Control -- Microft Comm Control 6.0 – Install để cài MSComm vào ActiveX. Sau đó vào toolbar ActiveX. tìm icon điện thoại để kéo vào Form. Các lệnh MSComm trong Delphi tương tự trong Visual Basic Đối với Visual C thì lập trình MSComm phức tạp hơn, sau đây là ví dụ cài đặt MSComm trong Visual C Tác giả: TS Nguyễn Đức Thành Trang 226 Cài đặt MSCOMM trong Visual C Nếu muốn thêm component truyền thông nối tiếp vào project bạn vào menu Project- Add to Project- Components and Controls Gallery Chọn mục Registered ActiveX Controls – Microsoft Communication Controls, version 6.0- Insert. Hình biểu tượng điện thoại xuất hiện trên thanh Control. Lập trình MSCOMM trong Visual C++ phức tạp hơn lập trình trong Visual Basic và Delphi, các hàm của lớp CMScomm được định nghĩa trong mscomm.h, sau đây là một đoạn trong file này cần tham khảo để gọi hàm cho đúng void SetCDHolding(BOOL bNewValue); BOOL GetCDHolding(); void SetCommID(long nNewValue); long GetCommID(); void SetCommPort(short nNewValue); short GetCommPort(); void SetCTSHolding(BOOL bNewValue); BOOL GetCTSHolding(); void SetDSRHolding(BOOL bNewValue); BOOL GetDSRHolding(); void SetDTREnable(BOOL bNewValue); Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 227 Thành phố Hồ Chí Minh, tháng 4 năm 2006 BOOL GetDTREnable(); void SetHandshaking(long nNewValue); long GetHandshaking(); void SetInBufferSize(short nNewValue); short GetInBufferSize(); void SetInBufferCount(short nNewValue); short GetInBufferCount(); void SetBreak(BOOL bNewValue); BOOL GetBreak(); void SetInputLen(short nNewValue); short GetInputLen(); void SetNullDiscard(BOOL bNewValue); BOOL GetNullDiscard(); void SetOutBufferSize(short nNewValue); short GetOutBufferSize(); void SetOutBufferCount(short nNewValue); short GetOutBufferCount(); void SetParityReplace(LPCTSTR lpszNewValue); CString GetParityReplace(); void SetPortOpen(BOOL bNewValue); BOOL GetPortOpen(); void SetRThreshold(short nNewValue); short GetRThreshold(); void SetRTSEnable(BOOL bNewValue); BOOL GetRTSEnable(); void SetSettings(LPCTSTR lpszNewValue); CString GetSettings(); void SetSThreshold(short nNewValue); short GetSThreshold(); void SetOutput(const VARIANT& newValue); VARIANT GetOutput(); void SetInput(const VARIANT& newValue); VARIANT GetInput(); void SetCommEvent(short nNewValue); short GetCommEvent(); void SetEOFEnable(BOOL bNewValue); BOOL GetEOFEnable(); void SetInputMode(long nNewValue); long GetInputMode(); Tác giả: TS Nguyễn Đức Thành Trang 228 Ví dụ muốn truyền chuỗi what ta dùng đoạn lệnh sau CString strOutput = "What"; UCHAR myData = 0x00; strOutput += myData; m_Comm.SetPortOpen(true); // mở cổng m_Comm.SetOutput(COleVariant(strOutput)); Sau đây trình bày phần chính của chương trình serialDlg.cpp giao tiếp qua cổng Com, mời các bạn phân tích ý nghĩa các dòng lệnh, đề nghị tham khảo thêm hướng dẫn của VC++ // serialDlg.cpp : implementation file BOOL CSerialDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon if(m_ctlMSCOMM1.GetPortOpen()) m_ctlMSCOMM1.SetPortOpen(FALSE); m_ctlMSCOMM1.SetCommPort(1); //đặt cấu hình port m_ctlMSCOMM1.SetSettings("9600,n,8,1"); m_ctlMSCOMM1.SetInputMode(0); m_ctlMSCOMM1.SetRThreshold(1); m_ctlMSCOMM1.SetSThreshold(0); m_ctlMSCOMM1.SetInputLen(0); m_ctlMSCOMM1.SetPortOpen(TRUE); return TRUE; } Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 229 Thành phố Hồ Chí Minh, tháng 4 năm 2006 void CSerialDlg::OnExit() { m_ctlMSCOMM1.SetPortOpen(FALSE); OnOK(); } void CSerialDlg::OnSend() { UpdateData(TRUE); m_receive.Empty(); Send_str(m_send); UpdateData(FALSE); } void CSerialDlg::Send_str(CString str) { LPCSTR pstr=str; //đặt con trỏ cho chuỗi int i = str.GetLength(); BSTR bstr = SysAllocStringLen(0,i); //dành chỗ cho chuỗi Unicode bstr MultiByteToWideChar(CP_ACP,0,pstr,i+1,bstr,i+1); //đổi sang mã Unicode VARIANT dataout; dataout.vt=VT_BSTR; dataout.bstrVal=bstr; m_ctlMSCOMM1.SetOutput(dataout); //xuất chuỗi ra } void CSerialDlg::OnMscomm1() { if(m_ctlMSCOMM1.GetCommEvent()==2) { m_receive +=Get_str(); UpdateData(FALSE); } . } CString CSerialDlg::Get_str() { CHAR str[256]; VARIANT datain; Tác giả: TS Nguyễn Đức Thành Trang 230 datain.vt=VT_BSTR; datain=m_ctlMSCOMM1.GetInput(); WideCharToMultiByte(CP_ACP,0,datain.bstrVal,-1,str,256,NULL,NULL); return str; } Ngoài cách sử dụng công cụ MSComm còn có thể dùng các hàm của WinAPI 32. Do tính chất phức tạp của các hàm và giới hạn của giáo trình, xin trình bày vắn tắt để áp dụng vào chương trình trong Delphi và VC. Chi tiết có thể đọc trong Win 32 Program Reference. Sau đây là các hàm - Createfile, mở cổng COM hàm này trả về một biến (handle). Nếu không mở cổng được, biến trả về là –1, đóng cổng dùng lệnh closehandle, biến trả về là khác zero, nếu trả về zero là có lỗi. - Get Commstate: lấy cấu hình hiện tại của cổng cất vào khối DCB (device control block) - Set Commstate: đặt cấu hình cổng theo nội dung của DCB - Purge Comm: xóa bộ đệm vào ra, chấm dứt đọc, viết. - Writefile: viết data (xuất ra cổng Com) - Readfile: đọc cổng - EscapeCommFunction đặt: và xóa RTS hay DTR Unit modem: // chương trình minh họa các lệnh điều khiển modem dùng winapi và delphi 6.0 interface uses Windows, SysUtils; Var parity, stopbit, databit, cong:byte; tdo: dword; v, d, ta, td: real; hPort : longint; Send: array [1..50] of char; Receive: array [1..100] of char; i, sobyte: integer; kq: byte; Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 231 Thành phố Hồ Chí Minh, tháng 4 năm 2006 stri: string; Procedure Close_Com; Procedure Open_Com (nCom: byte); Procedure Set_Com (baud:Dword; Prt:byte; Stpbits:byte; dtbits: byte); Procedure Gan_chuoi (Str: string); Procedure Dial (phone: string); Procedure Hang_up; Procedure Flush_Com; Function Send_Com (send_str: string; dWByte: Dword): Boolean; Function Get_Com_Buffer: longint; Function Receive_Com (dwByte: Dword): Boolean; Procedure doi_chuoi (ch: byte); Implementation { $R *.DFM} Procedure Close_Com; begin if hPort –1 then CloseHandle (hPort); hPort := –1; end; Procedure Open_Com (nCom : byte); var sCom: string; begin sCom := ‘COM’ + IntToStr (nCom); if hPort –1 then Close Com; hPort := CreateFile (Pchar (sCom), GENERIC_READ OR GENERIC_WRITE, 0, NIL, OPEN_EXISTING; FILE_ATTRIBUTE_NORMAL, longint (0)); end; Procedure Set_Com(baud: Dword, Prt: byte; Stpbits:byte;dtbits: byte); var dcbPort:TDCB; // khai bao kieu DCB begin if hPort –1 then begin if GetCommState (hPort, dcbPort) then begin dcbPort. BaudRate:= baud; dcbPort. Bytesize: = dtBits; dcbPort. Parity : = prt; dcbPort.StopBits : = DtpBits; dcbPort. Elags : = dcbport.flags or (RTS_CONTROL_ENABLE) OR (DTR_CONTROL_ENABLE): Tác giả: TS Nguyễn Đức Thành Trang 232 SetCommState (hPort, dcbPort); end; end; end; Procedure Gan_chuoi (Str : string); var i : byte; s: string; begin s:= Str; for i:= 1 to length (s) do send [i] := s [i]; end; Function Send_Com (send_str: string; dwByte: Dword): Boolean; var dwWritten: Dword; begin result:= strue; Gan_chuoi (send_str); if (hPort –1) then begin WriteFile (hPort, send, dwByte, dwWritten, nil); if dwWritten dwByte then begin result := false; exit; end; end else result := false; end; Procedure Flush_Com; begin if hPort –1 then // Loai bo cac ky tu trong in/out buffer PurgeComm (hPort, PURGE_RXABORT OR PURGE_TXABORT OR PURGE_RXCLEAR OR PURGE_TXCLEAR); end; Procedure Dial (phone : string); var s : string; begin Open_Com (cong); Set_Com (tdo, parity, stopbit, databit); Chương 8: LẬP TRÌNH GIAO TIẾP NỐI TIẾP Trang 233 Thành phố Hồ Chí Minh, tháng 4 năm 2006 s := ‘ATDT’ + Phone+#13; Flush_Com; Send_Com (s, length (s)); end; Function Get_Com_Buffer : longint; var statPort : TCOMSTAT; dwErrorCode : dWord; begin Result := 0; if hPort –1 then begin ClearCommError (hPort, dwErrorCode, @statPort); // Khoi phuc co bao loi Result := statPort. CbInQue; // lay so byte trong in buffer end; end; Function Receive_Com (dwByte : Dword) : Boolean; Var dwRead : Dword; begin begin ReadFile (hPort, Receive, dwByte, dwRead, nil); if dwRead dwByte then begin result := false; exit; end else result := true; end; end; Procedure Hang_Up: var s : string; begin s := ‘ATH0’ +#13; Open_Com (cong); Set_Com (tdo, parity, stopbit, databit); Flush_Com; Send_Com (s, length (s)); Close_C

Các file đính kèm theo tài liệu này:

  • pdfchapter8_.pdf
Tài liệu liên quan