Tài liệu tham khảo công nghệ thông tin Lập trình giao tiếp máy tính qua cổng RS232
Trang 1Tutorial no 01.02
1 Điều khiển MSComm 1.1 Chuẩn giao tiếp RS232
RS232 là một chuẩn giao tiếp nối tiếp dùng định dạng không đồng bộ, kết nối nhiều nhất là với 2 thiết bị, chiều dài kết nối lớn nhất cho phép để đảm bảo dữ liệu là 50 – 100 feet ( 12.7 đến 25.4 m), tốc độ 20kBít/s đôi khi là tốc độ 115 k Bít/s với một số thiết bị đặc biệt.
Trang 2Hình 1.2: Chọn Device Manager
Trang 3Trang 4
1.2 Các thuộc tính của MSComm
1.2.1 Điều khiển MSComm trong Visual Basic
.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 5+ SThreshold: thiết lập và và trả lại số kí tự nhỏ nhất được cho phép trong bộ đệm gửi để xảy ra sự kiện OnComm = comEvSend . Theo mặc định giá trị này = 0 tức là khi truyền sẽ không gây ra sự kiện OnComm. Nếu thiết lập thông số này =1 thì sự kiện OnComm xảy ra khi bộ đệm truyền rỗng. Sự kiện OnComm = comEvSend chỉ xảy ra khi mà số kí tự trong bộ đệm truyền nhỏ hơn hoặc = Sthreshold. Nếu số kí tự trong bộ đệm này luôn lớn hơn Sthreshold thì sự kiện này không thể xảy ra.
Trang 6comEventRxOver 1008 Xảy ra khi bộ đệm nhận bị tràn. Không có đủ chỗ cho dữ liệu trong bộ đệm nhận.
comEventRxParity 1009 Lỗi Parity. Phần cứng phát hiện ra một lỗi Parity.
comEventTxFull 1010 xảy ra khi bộ đệm truyền bị đầy. Bộ đệm truyền bị đầy trong khi ghi dữ liệu lớn vào bộ đệm
comEventDCB 1011 Một lỗi không mong muốn khi đang khôi phục lại khỗi điều khiển thiết bị( DCB – Device Control Block) cho cổng
comEvSend 1 Xảy ra khi số kí tự trong bộ đệm truyền nhỏ hơn giá trị SthresHold.
comEvCD 5 Xảy ra khi có thay đổi trong đường CD( Carrier Detect)
comEvRing 6 Phát hiện chuông (Ring).Một số UART không hỗ trợ sự kiện này.
comEvEOF 7 Xảy ra khi nhận được kí tự kết thúc file ( kí tự 26 trong bảng mã ASCII)
kiện comEvEOF trong OnCommEvent. Nếu value= false thì sẽ không gây lên sự kiện này.
Trang 7(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 8comNone 0 (Mặc định) Không bắt tay
comRTS 2 Bắt tay RTS/CTS (Request To Send/Clear To Send)
comRTSXOnXOff 3 Dùng cả bắt tay Request To Send and XON/XOFF
Handshaking chỉ là giao thức truyền thông nội tại quyết định bởi dữ liệu nào được
1.1.2 Điều khiển MSComm trong Visual C++
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 9virtual BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL)
{ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID); }
BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE, BSTR bstrLicKey = NULL)
{ return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID, pPersist, bStorage, bstrLicKey); }
void SetCDHolding(BOOL bNewValue); BOOL GetCDHolding();
void SetCommID(long nNewValue); long GetCommID();
Trang 10void SetCommPort(short nNewValue); short GetCommPort();
void SetCTSHolding(BOOL bNewValue); BOOL GetCTSHolding();
void SetDSRHolding(BOOL bNewValue); BOOL GetDSRHolding();
void SetDTREnable(BOOL bNewValue); 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);
Trang 11VARIANT GetInput();
void SetCommEvent(short nNewValue); short GetCommEvent();
void SetEOFEnable(BOOL bNewValue); BOOL GetEOFEnable();
void SetInputMode(long nNewValue); long GetInputMode();
VARTYPE vt;
unsigned short wReserved1; unsigned short wReserved2; unsigned short wReserved3; union {
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 12char 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;
Trang 13
1.3 Cách thiết lập tối ưu cho ứng dụng
2 Lập trình
2.1 Mục đích yêu cầu
Chương trình có chức năng sau:
Chú ý:
Trang 142.2 Thiết kế giao diện cho chương trình 2.2.1 Tạo dự án “RS232TUT”
Khởi động Visual C++, chọn New từ menu File
Trang 15Hình 2.4: Chọn MFC Application(exe), tên dự án, nơi chứa dự án
Trang 18Hình 2.10: Chọn Components Controls
Trang 19Hộp thoại Components and Control Gallery xuất hiện bạn chọn Regestered ActiveX Controls(đây là thư mục chứa các điều khiển ActiveX):
Trang 20Nhấn Close để đóng hộp thoại
Trang 222.2.3 Thêm các điều khiển khác 2.2.3.1 Thêm các Group Box
Hình 2.18: Thêm GroupBox2
Trang 23Hình 2.20: Thêm GroupBox4
Trang 24Hình 2.22: Thêm GroupBox6
Trang 25Hình 2.24: Thêm GroupBox8
Trang 27Hình 2.28: Thiết lập thuộc tính cho GroupBox2
Trang 28Hình 2.31: Thiết lập thuộc tính cho GroupBox4
Trang 29Hình 2.33: Thiết lập thuộc tính cho GroupBox6
Trang 30Hình 2.34: Thiết lập thuộc tính cho GroupBox8
Trang 32Hình 2.38: Làm cho các GroupBox này thẳng hàng với nhau
Trang 34Hình 2.42: Thiết lập ID cho EditBox1
Trang 35Hình 2.44: Thêm EditBox2
Trang 36Hình 2.46: Thuộc tính của EditBox
Trang 38Hình 2.50: Tạo 3 Button có cùng kích thước
Trang 39Hình 2.52: Thuộc tính của Button1
Trang 40Hình 2.54: Thuộc tính của Button3
Trang 42Hình 2.58: Thêm ComboBox4
Trang 43Hình 2.60: Thêm ComboBox6
Trang 44Di 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 46Hình 2.65: Thuộc tính ID của Combo3
Trang 47Hình 2.67: Thuộc tính ID của Combo2
Trang 48Hình 2.69: Thuộc tính ID của ComboBox6
Trang 492 ComboBox ID Style
IDC_COMBO_COMPORT Droplist
Trang 50Hình 2.71: Chọn MFCClassWizard tab Member Variables, chọn AddVariable
Trang 51Các bạn thêm các biến cho các điều khiển tương tự như trên. Sau đây là hình minh hoạ việc thêm các biến này:
Trang 52Hình 2.74: Thêm biến điều khiển cho ComboBox Data Bit
Trang 53Hình 2.76: Thêm biến điều khiển cho Combo Parity Bit
Trang 54Hình 2.78: Thêm biến giá trị cho Edit Box Receive
Trang 55Hình 2.80: Thêm biến điều khiển cho MSComm
Trang 56vào lớp CRS232TUTDlg chọn Add Member Function:
Trang 57Trang 58
Hình 2.84: Thêm hàm getCurStrInCombobox , chọn OK
Trang 59Các bạn kích vào cửa sổ bên trái chọn tab Class, kích đúp chuột vào tên hàm, bên phải sẽ hiện ra nơi định nghĩa hàm, các bạn thêm mã vào.
Trang 60CString str;
a.GetLBText(a.GetCurSel(),str); return str;
2.3.2.2 Hàm InitComboBox: dùng khởi tạo các giá trị cho ComboBox Kích đúp chuột vào hàm InitComboBox( hàm này dùng khởi tạo các giá trị cho
ComboBox) trong của sổ bên trái tương tự như với hàm trên.
Trang 61// ComboBox ComPort
m_cboComPort.ResetContent(); m_cboComPort.AddString(ʺCOM1ʺ); m_cboComPort.AddString(ʺCOM2ʺ); m_cboComPort.SetCurSel(0);
// ComboBox BitRate
m_cboBitRate.ResetContent(); m_cboBitRate.InsertString(0,ʺ600ʺ); m_cboBitRate.InsertString(1,ʺ1200ʺ);
Trang 62m_cboBitRate.InsertString(2,ʺ2400ʺ); m_cboBitRate.InsertString(3,ʺ4800ʺ); m_cboBitRate.InsertString(4,ʺ9600ʺ); m_cboBitRate.InsertString(5,ʺ14400ʺ); m_cboBitRate.InsertString(6,ʺ19200ʺ); m_cboBitRate.InsertString(7,ʺ28800ʺ); m_cboBitRate.InsertString(8,ʺ38400ʺ); m_cboBitRate.InsertString(9,ʺ56000ʺ); m_cboBitRate.InsertString(10,ʺ57600ʺ); m_cboBitRate.InsertString(11,ʺ115200ʺ); m_cboBitRate.InsertString(12,ʺ128000ʺ); m_cboBitRate.InsertString(13,ʺ256000ʺ); m_cboBitRate.SetCurSel(4);
// ComboBox Data Bit
m_cboDataBit.ResetContent(); m_cboDataBit.AddString(ʺ5ʺ); m_cboDataBit.AddString(ʺ6ʺ); m_cboDataBit.AddString(ʺ7ʺ); m_cboDataBit.AddString(ʺ8ʺ); m_cboDataBit.SetCurSel(3); // ComboBox Stop Bit
m_cboStopBit.ResetContent(); m_cboStopBit.AddString(ʺ1ʺ); m_cboStopBit.AddString(ʺ1.5ʺ); m_cboStopBit.AddString(ʺ2ʺ); m_cboStopBit.SetCurSel(0); // ComboBox Parity Bit
m_cboParityBit.ResetContent();
Trang 63m_cboParityBit.InsertString(0,ʺNoneʺ); m_cboParityBit.InsertString(1,ʺOldʺ); m_cboParityBit.InsertString(2,ʺEvenʺ); m_cboParityBit.InsertString(3,ʺMarkʺ); m_cboParityBit.InsertString(4,ʺSpaceʺ);
m_cboParityBit.SetCurSel(0); // mặc định chọn None // ComboBox Handshaking
m_cboHandshaking.ResetContent();
m_cboHandshaking.InsertString(0,ʺNoneʺ);
m_cboHandshaking.InsertString(1,ʺXON/XOFFʺ); m_cboHandshaking.InsertString(2,ʺRTSʺ);
m_cboHandshaking.InsertString(3,ʺRTS/CTS + XON/XOFFʺ); m_cboHandshaking.SetCurSel(0);
Hình 2.89: Thêm dữ liệu bằng tay
Trang 642.3.2.3 Hàm Settings: dùng thiết lập các tham số cho MSComm Bạn kích đúp vào hàm Settings ( hàm này dùng thiết lập các tham số cho
m_mscomm.SetPortOpen(false); // Thiết lập tên cổng
m_mscomm.SetCommPort(m_cboComPort.GetCurSel()+ 1); // Thiết lập bắt tay
m_mscomm.SetHandshaking(m_cboHandshaking.GetCurSel());
Trang 65// Thiết lập tần số, bit dữ liệu, bít stop
CString strBitRate = getCurStrInCombobox(m_cboBitRate); CString strParity = getCurStrInCombobox(m_cboParityBit); CString strDataBit = getCurStrInCombobox(m_cboDataBit); CString strStopBit = getCurStrInCombobox(m_cboStopBit); CString strSetting;
strSetting.Format(ʺ%s,%c,%s,%sʺ,strBitRate,strParity[1],strDataBit,strStopBit); m_mscomm.SetSettings(strSetting);
m_mscomm.SetRThreshold(1);
m_mscomm.SetInputLen(1); // mỗi lần đọc một kí tự m_mscomm.SetInBufferSize(1024);
m_mscomm.SetInputMode(0); // 0 – Text Mode , 1‐ Binary Mode m_mscomm.SetOutBufferSize(1024);
m_mscomm.SetPortOpen(true); // mở cổng }
2.3.2.4 Hàm khởi tạo cho hộp thoại
Đầ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 66Hình 2.92: Chọn EditCode để viết thêm vào hàm
Trang 67// TODO: Add extra initialization here InitComboBox();
return TRUE; // return TRUE unless you set the focus to a control }
2.3.2.5 Các hàm cho các nút Button đáp ứng sự kiện Click:
Hàm OnButtonExit()
Hình 2.93: Thêm hàm cho nút Exit
Trang 68Hình 2.95: Nhấn EditCode để viết mã cho hàm
Trang 69// TODO: Add your control notification handler code here // Nếu cổng còn mở thì đóng lại
if ( m_mscomm.GetPortOpen() )
m_mscomm.SetPortOpen(false); OnOK();
}
Trang 71Hình 2.100: Cửa sổ thêm code
Trang 72// TODO: Add your control notification handler code here UpdateData();
Settings(); // send data
m_mscomm.SetOutput((COleVariant)m_strTransfer); UpdateData(false);
Trang 73// TODO: Add your control notification handler code here UpdateData();
m_strReceive = ʺʺ; UpdateData(false); }
Trang 74Do 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 75// TODO: Add your control notification handler code here UpdateData();
switch( m_mscomm.GetCommEvent()){ case 1: // comEvSend
case 2:// comEvReceive
VARIANT data = m_mscomm.GetInput(); m_strReceive += (CString)data.bstrVal;
case 3:// comEvCTS
Trang 76Hình 2.107: Dịch chương trình
Trang 77Hình 2.109: Chạy chương trình
Trang 783 Tài liệu tham khảo
‐ Phạm Công Ngô ‐ Phạm Ngọc Nam ‐ Phạm Tuấn Lương ‐ Tự học lập trình Visual C++ 6.0 từ cơ bản đến nâng cao