Các thuộc tính của MSComm MSComm là một điều khiển ActiveX dùng trong truyền thông nối tiếp.. Các tính chất của điều khiển này được dùng để thiết lập giao tiếp với các thiết bị ngoại vi
Trang 1Báo cáo tốt nghiệp
Lập trình giao tiếp máy tính qua cổng
RS232
Trang 2Tutorial n o 01.02
Gửi đến: Đoàn Hiệp, Doãn Minh Đăng, Huỳnh Châu Thuận
Trang 4Trang 5
1.2 Các thuộc tính của MSComm
MSComm là một điều khiển ActiveX dùng trong truyền thông nối tiếp. Các tính chất
của điều khiển này được dùng để thiết lập giao tiếp với các thiết bị ngoại vi qua cổng RS232. Do đó tôi xin giới thiệu với các bạn điều khiển này trong Visual Basic vì cách gọi thuộc tính đơn giản của VB. Từ đó sẽ lấy làm cơ sở để lập trình trên Visual C++.
1.2.1 Điều khiển MSComm trong Visual Basic
Tất cả các tính chất này bạn có thể tìm tại thư viện MSDN July 2001 theo đường dẫn như sau ở tab contents:
MSDN Library ‐ July 2001 / Visual Tools and Languages/ Visual Studio 6.0
Documentation / Visual Basic Documentation / Reference/ Control Reference / ActiveX Control/ MSComm Control
Các tính chất của MSComm được sắp xếp theo chức năng:
Thiết lập tham số cho cổng:
+ CommID: trả lại handles đồng nhất tới thiết bị truyền thông, có kiểu Long. Tính chất này không có lúc thiết kế mà chỉ có khi thi hành, thuộc tính này là ReadOnly.
không = InputLen thì thuộc tính Input sẽ trả lại kí tự rỗng “”. Ví thế bạn cần phải chọn cách kiểm tra InBufferCount để chắc chắn số kí tự yêu cầu đã có đủ trước khi dùng lệnh
.Input. Tính chất này rất là có ích khi đọc dữ liệu một máy mà dữ liệu ra được định dạng bằng các khối có kích thước cố định.
Trang 6truyền. value = false kí tự trống sẽ được truyền. Kí tự trống được định nghía theo chuẩn ASCII là kí tự 0 – chr$(0).
Trang 7tìm thấy kí tự kết thúc file. Nếu value=true khi tìm thấy kí tự kết thúc file thì sẽ gây lên sự
kiện comEvEOF trong OnCommEvent. Nếu value= false thì sẽ không gây lên sự kiện này.
Trang 8+ InBufferCout: trả lại số kí tự đang có trong bộ đệm nhận Bạn có thể xoá bộ đệm nhận bằng cách đặt thuộc tính này =0 . Không nhầm với thuộc tính InBufferSize là tổng kích
thước của bộ đệm nhận.
+ Input: nhận và xoá dữ liệu trong bộ đệm nhận.
Nếu InputMode là comInputModeText thì giá trị trả về sẽ là một xâu tức có kiểu String , dữ liệu dạng text trong một biến kiểu Variant. Nếu InputMode =
Bắt tay( handshaking):
+ Break : thiết lập hoặc xoá tín hiệu. object.Break [ = value] value = true hoặc false. Khi
set value= true thì thông số Break này sẽ gửi một tín hiệu break. Tín hiệu break trì hoàn việc truyền dữ liệu và đưa đường truyền vào trạng thái break tới khi mà value = false.
+ CDHolding: quết định xem sự truyền này đến đâu bằng cách truy vấn đường CD(
Carrier Detect). Carrier Detect là tín hiệu gửi từ modem tới máy tính kết nối với nó thống báo rằng nó đang online. Nếu giá trị = true thì nó đường CD đang ở mức cao, nếu = false thì đường dây này đang ở mức thấp. Tính chất này không có trong lúc thiết kế chỉ có trong khi chạy chương trình.Carrier Detect được biết như là Receive Line Signal Detect (RLSD).
+ CTSHolding: quết định khi nào bạn gửi dữ liệu bằng cách truy vấn trạng thái đường
Clear To Send (CTS). Thông thường tín hiệu CTS được gửi từ modem tới máy tính kết nối với nó để báo rằng đang quá trình truyền dữ liệu. Thuộc tính Readonly chỉ xuất hiện khi chạy chương trình. Đường Clear To Send dùng trong RTS/CTS (Request To Send/Clear To
Send) bắt tay phần cứng. CTSHolding cho bạn một cách để tự tay dò đường Clear To Send
nếu bạn cần biết trạng thái của nó.
+ DSRHolding: biết trạng thái của đường Data Set Ready (DSR). Tín hiệu Data Set
Ready truyền từ modem tới máy tính nối với nó để thông báo rằng modem đã sẵn sàng hoạt động. Tính chất này dùng khi viết Data Set Ready/Data Terminal Ready handshaking routine cho máy Data Terminal Equipment (DTE)‐ máy trang bị đầu cuối dữ liệu.
+ DTREnable: tính chất này quyết định khi nào cho phép đường Data Terminal Ready
(DTR) trong truyền thông. Tín hiệu DTR gửi từ máy tính tới modem đẻ báo rằng máy tính sẵn sàng là nơi nhận dữ liệu. Khi DTREnable = true thì đường Data Terminal Ready set lên cao khi cổng mở, và thấp khi cổng đóng. Nếu DTREnable = false thì đường đó luôn mức thấp. Trong phần lớn trường hợp set đường Data Terminal Ready thành thấp để hang up telephone.
Trang 9truyền thông sẽ chuyển dữ liệu vào trong bộ đệm nhận.
+ RTSEnable: quết định khi nào cho phép đường Request To Send (RTS), Tín hiệu RTS
từ máy tính tới modem để yêu cầu được tryền dữ liệu. Khi RTSEnable = true thì đường RTS mức cao khi cổng mở, tích mức thấp khi cổng đóng. Và hiển nhiên khi RTSEnable thì đường RTS luôn mức thấp.RTS dùng trong RTS/CTS hardware handshaking. RTSEnable cho phép bạn dò đường RTS khi cần biết tình trạng của đường này.
Các tính chất trên không có lúc thiết kế giao diện mà chỉ có lúc chạy chương trình ( dùng trong viết code).
Ví dụ, bạn muốn thiết lập dùng cổng COM1 chẳng hạn thì dùng thuộc tính CommPort
ở trên và chỉ thêm tiền tố Set_ nếu muốn thiết lập và Get_ nếu muốn lấy giá trị này.
Sau đây là lớp MSComm là một lớp kế thừa từ lớp cở sở CWnd, các bạn có thể tham khảo. Các bạn chú ý về các kiều dữ liệu cửa các tham số và giá trị trả về của các hàm. Việc
Trang 12VARIANT GetInput();
void SetCommEvent(short nNewValue);
short GetCommEvent();
void SetEOFEnable(BOOL bNewValue);
void SetInputMode(long nNewValue);
long GetInputMode();
};
Các bạn xem kĩ các hàm, các phép toán trên có thể thấy là kiểu dữ liệu dùng làm tham
số cho hàm hay giá trị trả về của các hàm hầu hết là các kiểu dữ liệu cơ bản như BOOL,
short, Chỉ đặc biết là có kiểu dữ liệu VARIANT.
VARIANT là một cấu trúc mà dữ liệu nó chứa là một kiểu union được định nghĩa như
sau:
typedef struct FARSTRUCT tagVARIANT VARIANT;
typedef struct FARSTRUCT tagVARIANT VARIANTARG;
typedef struct tagVARIANT {
VARTYPE vt;
unsigned short wReserved1;
unsigned short wReserved2;
unsigned short wReserved3;
union {
Byte bVal;
Short iVal;
long lVal;
float fltVal;
double dblVal;
VARIANT_BOOL boolVal;
SCODE scode;
CY cyVal;
DATE date;
BSTR bstrVal;
DECIMAL FAR* pdecVal
IUnknown FAR* punkVal;
IDispatch FAR* pdispVal;
SAFEARRAY FAR* parray;
Byte FAR* pbVal;
short FAR* piVal;
long FAR* plVal;
float FAR* pfltVal;
double FAR* pdblVal;
VARIANT_BOOL FAR* pboolVal;
SCODE FAR* pscode;
CY FAR* pcyVal;
DATE FAR* pdate;
BSTR FAR* pbstrVal;
IUnknown FAR* FAR* ppunkVal;
IDispatch FAR* FAR* ppdispVal; SAFEARRAY FAR* FAR* pparray;
VARIANT FAR* pvarVal;
void FAR* byref;
Trang 13char cVal;
unsigned short uiVal;
unsigned long ulVal;
int intVal;
unsigned int uintVal;
char FAR * pcVal;
unsigned short FAR * puiVal;
unsigned long FAR * pulVal; // VT_BYREF|VT_UI4 int FAR * pintVal;
unsigned int FAR * puintVal;
}; }; Các bạn để ý thấy rằng kiểu VARIANT dùng làm tham số cho hàm SetInput và là kiểu trả về của hàm GetOutput. Mà với kiểu truyền kiểu dạng Text chúng ta truyền dữ liệu ra cổng là dạng xâu kí tự thì chúng ta chuyển đối giữ kiểu VARIANT sang kiểu kí tự CString như thế nào? ‐ Chuyển từ kiểu CString ‐> VARIANT: tôi dùng lớp ColeVariant ( các bạn có thể tra trong MSDN dùng tab Index) là dạng đóng gói của kiểu cấu trúc VARIANT, lớp này có hàm khởi tạo COleVariant( CString& strSrc ); và do đó nó có thể làm tham số cho hàm SetInput của MSComm. Vì vậy chúng ta chỉ cần khai báo một biến ColeVariant là xong. CString data_tosend = “Example”; CodeVariant temp(data_tosend); m_mscomm1.SetInput(temp); ‐ Chuyển từ kiểu VARIANT sang kiểu CString. Các bạn xem lại định nghĩa cấu trúc VARIANT ở trên xem có biến nào có kiểu trả về kiểu tương thích với kiểu CString( tức có thể ép kiểu để trở thành kiểu CString). Tôi thấy có thành phần BSTR bstrVal;
Do đó ta chỉ việc ép kiểu là xong.
VARIANT data;
CString m_strData = (CString) data.bstrVal;
Trang 14
1.3 Cách thiết lập tối ưu cho ứng dụng
Để cho ứng dụng có thể đọc ngay dữ liệu khi bắt đầu có trong bộ đệm nhận thì các bạn nên đặt thuộc tính RthresHold = 1.
Ngoài ra các bạn cần quan tâm đến các tham số: CommPort, Settings, Rthreshold,
SthresHold,PortOpen, InputLen, InputBuffer, OutputBuffer, InBufferSize, InputMode, OutBufferSize.
2 Lập trình
2.1 Mục đích yêu cầu
Chương trình này rất là đơn giản. Chúng ta sẽ tạo ra một chương trình có giao diện như sau:
Hình 2.1: Giao diện chương trình
Chương trình có chức năng sau:
‐ Nhập kí tự hoặc xâu kí tự vào EditBox Transfer, điều chỉnh tham số giao tiếp trên các ComboBox. Nhấn nút Send để gửi dữ liệu ra cổng COM.
‐ Đồng thời với nó nếu có dữ liệu truyền vê cổng Com thì dữ liệu sẽ được hiển thị lên EditBox Receive. Khi bạn nhấn vào Clear thì sẽ xoá dữ liệu hiển thị trên EditBox này.
Chú ý:
Trang 15Để có thể test luôn chương trình các bạn nối tắt chân 2 và chân 3 của RS232 lại với nhau chính là nối chân RxD và TxD để chúng ta truyền dữ liệu ra RS232 sau đó nhận dữ liệu luôn. Đây là ví dụ test đơn giản không có bắt tay phần cứng.
Trang 16Hình 2.3: Chọn New từ menu file
Hình 2.4: Chọn MFC Application(exe), tên dự án, nơi chứa dự án
Trang 24Hình 2.19: Thêm GroupBox3
Hình 2.20: Thêm GroupBox4
Trang 25Hình 2.21: Thêm GroupBox5
Hình 2.22: Thêm GroupBox6
Trang 26Hình 2.23: Thêm GroupBox7
Hình 2.24: Thêm GroupBox8
Trang 27Hình 2.25: Thêm GroupBox9
Thay đổi thuộc tính cho GroupBox1:
Trang 28
Hình 2.27: Thiết lập thuộc tính Caption: Settings Các bạn làm tương tự với các GroupBox khác, theo hình vẽ dưới đây:
Hình 2.28: Thiết lập thuộc tính cho GroupBox2
Trang 29Hình 2.30: Thiết lập thuộc tính cho GroupBox3
Hình 2.31: Thiết lập thuộc tính cho GroupBox4
Trang 30Hình 2.32: Thiết lập thuộc tính cho GroupBox5
Hình 2.33: Thiết lập thuộc tính cho GroupBox6
Trang 31Hình 2.34: Thiết lập thuộc tính cho GroupBox7
Hình 2.34: Thiết lập thuộc tính cho GroupBox8
Trang 32Hình 2.35: Thiết lập thuộc tính cho GroupBox9
Tiếp theo các bạn làm cho các GroupBox 4‐>9 có kích thước bằng nhau và căn lề đẹp hơn
Hình 2.36: Làm cho các GroupBox có cùng kích thước
Trang 33Hình 2.37 Làm cho các GroupBox 7‐>9 có khoảng cách bằng nhau
Hình 2.38: Làm cho các GroupBox này thẳng hàng với nhau
Trang 34Hình 2.39: Kết quả sau khi làm cho cùng kích thước
2.2.3.2 Thêm các EditBox
Hình 2.40: Thêm EditBox1
Trang 35Hình 2.41: kích chuột phải, chọn Properties
Hình 2.42: Thiết lập ID cho EditBox1
Trang 36Hình 2.43: Thiết lập thuộc tính ReadOnly và MultiLine
Hình 2.44: Thêm EditBox2
Trang 37Hình 2.45: Chọn Properties
Hình 2.46: Thuộc tính của EditBox
Trang 39Hình 2.49: Thêm Button3
Hình 2.50: Tạo 3 Button có cùng kích thước
Trang 40Hình 2.51: Chọn Properties
Hình 2.52: Thuộc tính của Button1
Trang 41Hình 2.53: Thuộc tính của Button2
Hình 2.54: Thuộc tính của Button3
Trang 43Hình 2.57: Thêm ComboBox3
Hình 2.58: Thêm ComboBox4
Trang 44Hình 2.59: Thêm ComboBox5
Hình 2.60: Thêm ComboBox6
Trang 45Hình 2.61: Tạo cho các comboBox có cùng chiều rộng
Chú ý: Riêng với ComboBox thì các bạn phải kéo sao cho chiều cao của điều
khiển phải đủ lớn để chứa các dữ liệu nằm trong nó sau này nếu không thì bạn sẽ chẳng thấy nó hiển thị gì hoặc là sẽ thấy có thanh cuộn. Tốt nhất là kéo dài thoải mái
đi.
Để điều chỉnh chiều cao của các ComboBox như sau:
Di chuột đến ComboBox để con trỏ chuột nằm trên nút xổ xuống của điều khiển sau đó kích chuột trái 1 lần. Khi đó bạn sẽ có thể co dãn chiều cao của ComboBox thoải mái
Trang 47Hình 2.64: Thuộc tính ID của Combo1
Hình 2.65: Thuộc tính ID của Combo3
Trang 48Hình 2.66: Thuộc tính ID của Combo5
Hình 2.67: Thuộc tính ID của Combo2
Trang 49Hình 2.68: Thuộc tính ID của ComboBox 4
Hình 2.69: Thuộc tính ID của ComboBox6
Trang 50Hình 2.70: Thuộc tính Type: DropList của các ComboBox chung
Các bạn sau kiểm tra các thuộc tính của các điều khiển bằng bảng sau:
STT Đối tượng Thuộc tính Thiết lập
1 MSComm ID IDC_MSCOMM1
2 ComboBox ID
Style
IDC_COMBO_COMPORT Droplist
Trang 53Hình 2.73: Thêm biến điều khiển cho ComboBox ComPort
Hình 2.74: Thêm biến điều khiển cho ComboBox Data Bit
Trang 54Hình 2.75: Thêm biến điều khiển cho Combo Handshaking
Hình 2.76: Thêm biến điều khiển cho Combo Parity Bit
Trang 55Hình 2.77: Thêm biến điều khiển cho Combo Stop Bit
Hình 2.78: Thêm biến giá trị cho Edit Box Receive
Trang 56Hình 2.79: Thêm biến giá trị cho EditBox Transfer
Hình 2.80: Thêm biến điều khiển cho MSComm
Trang 58Hình 2.82: Chọn tab Class trong cửa sổ Workspace
Trang 59
Hình 2.83: Kích chuột phải chọn Add Member Function
Hình 2.84: Thêm hàm getCurStrInCombobox , chọn OK
Trang 61Hình 2.87: Kích đúp vào tên hàm getCurStrInCombobox bên trái để định nghĩa hàm
Thêm mã chương trình:
CString CRS232TUTDlg::getCurStrInCombobox(const CComboBox &a)
Trang 64
Hình 2.89: Thêm dữ liệu bằng tay
Trang 65m_mscomm.SetHandshaking(m_cboHandshaking.GetCurSel());
Trang 66Đầu tiên bạn phải thêm hàm này vào bằng cách mở MFC ClassWizard(ấn tổ hợp phím Ctr + W), chọn tab Message Maps:
Trang 67Hình 2.91: Thêm hàm InitDialog
Tiếp theo, bạn kích vào Edit Code , khung bên phải của VC++ sẽ hiện ra hàm OnInitDialog()để bạn thêm code vào:
Hình 2.92: Chọn EditCode để viết thêm vào hàm
Trang 68Hàm OnButtonExit()
Hình 2.93: Thêm hàm cho nút Exit
Trang 69Hình 2.94: Đồng ý với tên hàm là OnButtonExit
Hình 2.95: Nhấn EditCode để viết mã cho hàm
Trang 72Hình 2.99: Nhấn EditCode để viết hàm
Hình 2.100: Cửa sổ thêm code
Trang 75có thể dùng các ngắt khác tuỳ ý của mình.
Do tôi thiết lập InputLen = 1, nên mỗi lần chỉ nhận một kí tự, các bạn có thể dùng điều này để kiểm tra thông tin nhận từ vi điều khiển, ví dụ một kí tự báo hiệu chẳng hạn
Trang 77Hình 2.107: Dịch chương trình
Trang 78Hình 2.108: Kiểm tra sửa lỗi chương trình đến khi không có lỗi
Hình 2.109: Chạy chương trình
Trang 79Hình 2.110: Ứng dụng khi chạy
Bạn đánh một vài kí tự vào trong ô Transfer thiết lập tham số và truyền thử để kiểm tra chương trình.