Truyền dữ liệu kiểu text và nhị phân trong VB
Chào các bạn hôm nay tôi lại tiếp tục giới thiệu cho các bạn hiểu về cách truyền, nhận dữ liệu dạng text và binary trong VB.
Trước hết, các bạn cần biết biến kiểu Variant( tra trong từ điển có nghĩa là tương tự, gần giống nhau). Do vậy mà một biến Variant có thể gán = bất kì kiểu gì cũng được.Sau đây là chi tiết về 2 vấn đề chính:
VB cho phép bạn truyền dữ liệu dạng Text hay là dạng Binary. Thuộc tính InputMode quyết định điều khiển MSComm dùng dạng nào.
1.Kiểu văn bản( Text):
Với thuộc tính InputMode = comInputModeText thì MSComm sẽ gửi và nhận dữ liệu dạng xâu theo chuẩn ANSI ( không phải chuẩn ASCII). Để gửi một xâu ra port, bạn cần phải cho thuộc tính Output của MSComm = 1 xâu. Ví dụ:
Code: Dim SampleText as String
‘ví dụ bạn muốn truyền một xâu “ABC”
SampleText = “ABC”
‘ gửi kí tự này ra cổng
MSComm1.Output = SampleText
MSComm gửi một mã ANSI 8 bít cho mỗi kí tự trong xâu mà bạn gửi. Để đọc một xâu từ cổng, cần đặt một xâu = thuộc tính Input của MSComm. Ví dụ bạn muốn đọc dữ liệu từ cổng và ghi vào một biến SampleText có kiểu String:
Code:
Dim SampleText as String
SampleText = MSComm1.Input ‘ khi đó SampleText sẽ là dữ liệu đọc được
MSComm lưu trữ mỗi mã ANSI 8 bít như một kí tự văn bản.
Thực tế như các bạn đã biết thì giá trị truyền cho MSComm1.Output phải là kiểu Variant. Ở đây thuộc tính Output chấp nhận kiểu một biến Variant chứa một xâu kí tự và MSComm sẽ đọc xâu kí tự và gán tự động vào một biến Variant vì Variant chính là kiểu của Output. Nói cách khác ở đây có sự chuyển kiểu ngầm định giữa kiểu String sang kiểu Variant.
Ngay ở bên trong bản thân chương trình VB lại lưu trữ xâu dưới dạng mã Unicode 16 bít nhưng sự chuyển đổi giữa kiểu Unicode và kiểu xâu kí tự ANSI 8 bít của MSComm diễn ra một cách tự động.
Sự chuyển kiểu của số ASCII Hex:
Số ASCII Hex là số hexa bình thường mà ta vẫn dùng như 0xA5( trong C,C++) hoặc 0A5h( trong ASM,..) đại diện cho số 165 trong hệ Decimal( 165 = 16*10+ 5).
Với các ứng dụng dùng định dạng ASCII Hex, VB có một hàm chuyển đổi giữa kiểu xâu ASCII Hex và giá trị mà nó đại diện. Toán tử Hex$ chuyển đổi một số sang dạng kí tự ASCII Hex:
Ví dụ, để kiểm tra bạn có thể dùng hàm rất đơn giản xem nó in ra thế nào :
Code:
debug.print Hex$(165)
thì kết quả sẽ hiện trên một Dialog là : A5
Toán tử Val chuyển đổi từ kiểu ASCII Hex sang kiểu giá trị của xâu đó:
Ví dụ: ta thấy 0xA5 = 165 để thử xem có đúng không dùng lệnh;
Code:
debug.print Val(“&h” & “A5”)
Kết quả là 165.
Xâu đầu tiên “&h” được thêm vào để báo cho VB biết để đối xử với giá trị đưa ra sau đó như là một số hexadecimal.’
2. Kiểu nhị phân( Binary Mode):
Để truyền dữ liệu dưới dạng nhị phân, cần thiết lập thuộc tính InputMode của MSComm thành comInputModeBinary.
VB cung cấp một kiểu dữ liệu kiểu Byte để lưu trữ dữ liệu nhị phân. Các byte được ghi và đọc từ cổng nối tiếp được lưu trữ trong một biến Variant( nội dung của nó chứa một mảng mà các phần tử của mảng có kiểu Byte). Thậm chí nếu chí đọc, ghi duy nhất có 1 byte thì dữ liệu này cũng phải đặt trong một mảng byte, chứ không đuợc lưu trữ trong một biến kiểu byte thông thường. Để ghi một mảng kiểu byte ra cổng nối tiếp gồm 2 bước.
+ Bước đầu: lưu trữ mảng kiểu byte vào một biến variant
+ Bước 2: gửi dữ liệu đi bằng cách thiết lập thông số Output của MSComm bằng biến Variant đó.
Code:
Dim BytesToSend(0 to 1) as Byte ‘ khai báo một mảng 2 phần tủ
Dim Buffer as Variant
‘ lưu trữ dữ liệu vào mảng kiểu byte ở trên
BytesToSend(0) = &H4A
BytesToSend(1) = &H23
‘ cho vào một biến Variant
Buffer = BytesToSend()
‘ghi vào cổng nối tiếp
MSComm1.Output = Buffer
Để đọc các byte tại cổng nối tiếp, bạn cũng làm tương tự như trên, đọc vào một biến Variant sau đó cho một mảng = biến đó.
Code:
Dim BytesReceived() as Byte ‘ khai báo một mảng động
Dim Buffer as Variant ‘ khai báo biến variant
‘đọc dữ liệu từ cổng nối tiếp
Buffer = MSComm1.Input
‘ ghi dữ liệu đọc được vào mảng động
BytesReceived() = Buffer
Các ban lưu ý là phải khai báo một mảng byte động. Có 2 cách để chuyển đổi giữ mảng bytes và kiểu Variant. Bạn có thể cho một biến = một biến có số chiều đã được biết và VB làm công việc chuyển đổi này tự động:
Code:
Dim DimensionedArray(15) as Byte ‘ mảng đã khai báo số chiều =15
Dim DynamicBytesArray() as Byte
Dim Buffer As Variant
Dim Count As Integer
‘ lưu trữ một mảng mảng vào một biến variant. Mảng này đã được biết số phần tử
Buffer = DimensionedArray()
‘để sao chép nội dung của một biến variant vào một mảng thì mảng này phải khai báo là một mảng động( chưa biết số phần tử)
DynamicBytesArray() = Buffer
Đối với VB 6.0 bạn hoàn toàn có thể gán 2 mảng với nhau vì nó sẽ tự sao chép nội dung từ mảng nguồn sang mảng đích mà không cần phải làm bằng cách sao chép từng phần tử của 2 mảng cho nhau( như trong C thì bạn phải làm điều này rồi vì gán 2 tên mảng thực chất là bạn chỉ là cho con trỏ mảng đích trỏ vào địa chỉ của phần tử của mảng nguồn thôi, đây là sự sao chép bề mặt). Tuy nhiên bạn vẫn có thể làm điều này trong VB:
Code:
‘lưu trữ một mảng kiểu byte trong một biến variant
Buffer = CVar(DynamicByteArray())
‘ CVar -> Convert to Variant Chuyển thành kiểu variant
‘lưu nội dung của biến variant này trong một mảng kiểu byte
For Count = 0 to (LenB(Buffer)-1)
DimmensionedArray(Count) = CByte(Buffer(count))
Next Count
‘ CByte -> Convert to Byte chuyển kiểu thành kiểu Byte
Gửi nhận dữ liệu bằng phương pháp dò
Tiếp theo tôi xin giới thiệu cho các bạn phương pháp lấy dữ liệu bằng phương pháp thăm dò( polling).
Giao tiếp tại cổng bằng phương pháp dò tức là bạn chỉ đọc hoặc ghi ra cổng khi nào cần bằng cách dùng thuộc tính Input hoặc Output của MSComm.
1. Gửi dữ liệu:
Thuộc tính Output dùng để ghi dữ liệu ra cổng. Biến dùng ở bên phải cú pháp là một biến kiểu Variant. Đây là cú pháp để ghi dữ liệu:
Code:
Dim DataToWrite As Variant
MSComm1.Output = DataToWrite
Khi gửi một khối nhỏ dữ liệu, cần phải thiết lập thuộc tính OutBuferSize phải lớn hơn hoặc bằng số lượng lớn nhất các byte mà các bạn cần chuyển trong một lần.
Đối với việc truyền dữ liệu có tính lâu dài về thời gian dùng OutBufferCount để chắc chắn rằng bộ đệm không bị tràn. Khi bạn có nhiều dữ liệu cần gửi để tránh cho tràn bộ đệm , bạn nên đọc giá trị của OutBufferCount và so sánh với giá trị của OutBufferCount để kiểm tra xem bộ đệm còn bao nhiêu sau khi gửi dữ liệu đầu tiên. Sau đó làm đầy bộ đệm bằng cách ghi bằng đó các byte hoặc nhở hơn dữ liệu vào bộ đệm thì bộ đệm sẽ không bị tràn. Hoặc bạn có thể gửi dữ liệu đã đóng gói với kích thước xác định và chỉ gửi các gói này được OutBufferCount chỉ rằng có đủ chỗ trống trong bộ đệm cho gói dữ liệu này. Ví dụ, OutBufferSize = 1024 và kích thước 1 gói là 512, bạn chỉ có thể gửi được gói dữ liệu này khi mà OutBuferCount <= 512.
2. Nhận dữ liệu:
Để đọc dữ liệu được truyền đến, ứng dụng đọc dữ liệu từ InBuferCount theo từng chu kì. Khi bộ đếm chỉ rằng một số các kí tự mà ứng dụng cần đã đến( như muốn lấy 5 byte chẳng hạn) thì ứn dụng sẽ đọc dữ liệu với thuộc tính Input của MSComm:
Code:
Dim BytesToRead As Integer
Dim DataIn As Variant
‘thiết lập số byte cần đọc
NumberOfBytesToRead = 512
MSComm1.InputLen = NumberOfBytesToRead
‘ dò bộ đệm nhận đến khi bộ đệm có đầy đủ số byte cần đọc
Do
DoEvents
Loop Until MSComm1.InBufferCount> NumberOfBytesToRead
‘ khi tổng số byte đã tới thì đọc lưu vào DataIn
DataIn = MSComm1.Input
Thuộc tính InBuferSize phải đủ độ rộng để cho lượng lớn nhất dữ liệu có thể tới mà không bị mất trước khi MSComm có thể đọc chúng. Nếu dữ liệu đến bằng các block với kích thước cố định thì cần thiết lập thuộc tính InBufferSize bằng bội số của kích thước 1 block.
Nếu tổng dữ liệu đến không biết kích thước thế nào, ứng dụng nên đọc bộ đệm nhận ngay khi bộ đệm chỉ nhận được 1 byte để tránh việc không kiểm soát đượcbộ đệm gây ra tràn dữ liệu. Chờ đợi nhiều byte để đọc là một việc làm không có hiệu quả bởi vì không có cách nào biết được byte nào sẽ đến cuối cùng. Nếu chờ nhiều hơn 1 byte rồi mới đọc, chương trình nên bao gồm có một “time out” chính là tổng thời gian từ lúc chờ mà tổng số byte vẫn không đến( như bạn chờ 6 byte mà mãi không đến chẳng lẽ ứng dụng chờ mấy giờ à, thế thì bạn cần phải qui định là sao bao nhiêu lâu thì đọc thôi chẳng cần chờ nữa).
Bạn có thể kết hợp phương pháp lập trình theo thủ tục và theo sự kiện bằng cách sử dụng timer để biết khi nào thì đọc cổng. Ví dụ, dùng một sự kiện Timer gây ra ở cổng đeer đọc cổng một lần / một giây.
Trên đây là cách đọc, ghi dữ liệu bằng phương pháp dò. Ngày mai tôi xin giới thiệu cho các bạn cách dùng ngắt(Interrupt), tức là dùng sự kiện OnComm của MSComm.
12.2.1. Giao tiep COM_LCD
Ngoài ra, để dùng giao tiếp rs232 rất đơn giản:
#uses rs232
printf (xuất)
getc(nhập)
Trong CCs tiếng việt trên , tôi có trình bày cách set po rt , VD po rt B
1/ thiết lập cơ chế truy xuất nhanh po rtB :
khai báo #U SE FAST_IO(po rtB) khởi tạo 1 biến danh định chỉ tới địa chỉ PO rt B :Vd po rtB ở địa chỉ 0x3F thì set:
#LOCATE portB = 0x3F
portB chỉ là tên , có thể dùng tên khác tùy ý.
2/ sau đó trong chương trình , set chân vào ra :
VD : set_tris_B(0x11110000b) ; // B0->B3 : ngõ ra , B4->B7 : ngõ vào
VD : set_tris_B(255); // tất cà là ngõ vào
VD : set_tris_B( 0) ; // tất cả là ngõ ra
khi đó chỉ cần:
Vd : tất cả là ngõ vào thì có thể khiểm tra 1 cái gì đó :
if ( portB==0x0011b) { . . .} // nếu B0 và B1 có tín hiệu vào thì . . .
nếu set tất cả là ngõ ra thì :
Vd : portB = 127 ; // =0x01111111 : xuất tín hiệu ra trên B0->B6 ,B7 không có .
+
Chẳng lẽ để giao tiếp rs232 chỉ cần có 2 lệnh đó thôi sao? thế còn việc kiểm tra xem lúc nào bộ đệm tràn? như ở bên máy tính em làm cả khâu kiểm tra này, còn ở PIC thì sao? xử lý khi báo tràn như thế nào? EM có đọc datasheet của PIC 16F877 nhưng chưa thông lắm! Mong bác chỉ giáo. Ngoài ra em còn muốn xử lý data xuất/nhập này thì làm như thế nào? có phải ghi từ thanh ghi đệm vào bộ nhớ PIC rồi lấy data từ đó xử lý? Ví dụ như là em muốn cho nó xuất led chẳng hạn!
Mong bác thông cảm, có lẽ em hỏi hơi bị ngây ngô! Em mới chuyển từ 8051 sang PIC mấy tuần nay! CHưa biết gì cả!
|
Tôi thấy như vậy đã là đủ rồi, kho các hàm của CCS rất nhiệu Về RS232 cho pic thì bạn xem lại trong datasheet, PIC chi có 8 bit cho truyền và 8 bit cho nhân. Tài liệu đầy đủ nhất là help cua nó, kết hợp các hàm lại với nhau sẽ giúp bạn giải quyết nhiều bài toán.
Còn về lập trình giao tiếp RS232 tôi đã có một bài mẫu. Chương trình nhận ký tự từ bàn phím và hiên thị ra LCD, rồi xuất trả lại máy tính ký tự đó.
Code:
#include <16f877a.h>
#include
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
#include
//#include
int8 count=0;
char string_in[16];
#INT_RDA
Receive_isr() {
char c;
int8 i;
count++;
c = getc();
putc(c);
if (c=='c' | c=='C')
{
LCD_putcmd(0x01); //Clear Screen
c='c';
count=0;
}
if ((count<=16) && (c!='c')) LCD_putchar(c);
if (count > 16)
{
count=0;
LCD_putcmd(0xC0);
}
}
void main()
{
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
lcd_init();
lcd_putcmd(0x01);
lcd_putcmd(line_1);
printf("Enter a String.");
printf("Or anything you want!");
while (1) {}
}
12.2.2. USART-RS232
//PROGRAMM FOR rs232 communication
//
// PROCESSOR : PIC16F877A
// CLOCK : 20MHz, EXTERNAL
// SPEED : 9600 bps(1bit=104us)
#include
__CONFIG(WDTDIS & LVPDIS & BORDIS & HS & PWRTEN) ;
unsigned char ch;
void InitUsart(void) {
// TX Pin - output
TRISC6 = 0;
// RX Pin - input
TRISC7 = 1;
// RX Setting, 8bit, enable receive,
RCSTA = 0x90;
// TX Setting, 8bit, Asinchronius mode, High speed
TXSTA = 0x24;
// Set Baudrade - 9600 (from datasheet baudrade table)
SPBRG = 129;
}
void WriteByte(unsigned char byte) {
// wait until register is empty
while(!TXIF);
// transmite byte
TXREG = byte;
}
unsigned char ReadByte(void) {
// wait to receive character
while(!RCIF);
// return received character
return RCREG;
}
// main function
void main( void ) {
// Init Interface
InitUsart();
// loop forever - echo
while(1) {
ch = ReadByte();
WriteByte(ch);
WriteByte('*');
}
}
12.2.3. RS232TUT.H
// RS232TUT.h : main header file for the RS232TUT application
//
#if !defined(AFX_RS232TUT_H__B483DFBF_2BC7_4F5C_A17A_182A0133B7B9__INCLUDED_)
#define AFX_RS232TUT_H__B483DFBF_2BC7_4F5C_A17A_182A0133B7B9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTApp:
// See RS232TUT.cpp for the implementation of this class
//
class CRS232TUTApp : public CWinApp
{
public:
CRS232TUTApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRS232TUTApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CRS232TUTApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RS232TUT_H__B483DFBF_2BC7_4F5C_A17A_182A0133B7B9__INCLUDED_)
12.2.4. RS232TUT
// RS232TUT.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "RS232TUT.h"
#include "RS232TUTDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTApp
BEGIN_MESSAGE_MAP(CRS232TUTApp, CWinApp)
//{{AFX_MSG_MAP(CRS232TUTApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTApp construction
CRS232TUTApp::CRS232TUTApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CRS232TUTApp object
CRS232TUTApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTApp initialization
BOOL CRS232TUTApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CRS232TUTDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
12.2.5. RS232TUTDlg
// RS232TUTDlg.h : header file
//
//{{AFX_INCLUDES()
#include "mscomm.h"
//}}AFX_INCLUDES
#if !defined(AFX_RS232TUTDLG_H__4C1AE02B_9689_41FF_8F79_A9F74E508A84__INCLUDED_)
#define AFX_RS232TUTDLG_H__4C1AE02B_9689_41FF_8F79_A9F74E508A84__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTDlg dialog
class CRS232TUTDlg : public CDialog
{
// Construction
public:
CString getCurStrInCombobox(const CComboBox & a);
void InitComboBox();
void Settings();
CRS232TUTDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CRS232TUTDlg)
enum { IDD = IDD_RS232TUT_DIALOG };
CComboBox m_cboStopBit;
CComboBox m_cboParityBit;
CComboBox m_cboHandshaking;
CComboBox m_cboDataBit;
CComboBox m_cboComPort;
CComboBox m_cboBitRate;
CMSComm m_mscomm;
CString m_strReceive;
CString m_strTransfer;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRS232TUTDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CRS232TUTDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButtonExit();
afx_msg void OnEditchangeComboComport();
afx_msg void OnButtonSend();
afx_msg void OnOnCommMscomm1();
afx_msg void OnButtonClear();
afx_msg void OnButtonConnect();
DECLARE_EVENTSINK_MAP()
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RS232TUTDLG_H__4C1AE02B_9689_41FF_8F79_A9F74E508A84__INCLUDED_)
12.2.6. RS232TUTDlg.CPP
// RS232TUTDlg.cpp : implementation file
//
#include "stdafx.h"
#include "RS232TUT.h"
#include "RS232TUTDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTDlg dialog
CRS232TUTDlg::CRS232TUTDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRS232TUTDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CRS232TUTDlg)
m_strReceive = _T("");
m_strTransfer = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CRS232TUTDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRS232TUTDlg)
DDX_Control(pDX, IDC_COMBO_STOPBIT, m_cboStopBit);
DDX_Control(pDX, IDC_COMBO_PARITYBIT, m_cboParityBit);
DDX_Control(pDX, IDC_COMBO_HANDSHAKING, m_cboHandshaking);
DDX_Control(pDX, IDC_COMBO_DATABIT, m_cboDataBit);
DDX_Control(pDX, IDC_COMBO_COMPORT, m_cboComPort);
DDX_Control(pDX, IDC_COMBO_BITRATE, m_cboBitRate);
DDX_Control(pDX, IDC_MSCOMM1, m_mscomm);
DDX_Text(pDX, IDC_EDIT_RECEIVE, m_strReceive);
DDX_Text(pDX, IDC_EDIT_TRANSFER, m_strTransfer);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRS232TUTDlg, CDialog)
//{{AFX_MSG_MAP(CRS232TUTDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_EXIT, OnButtonExit)
ON_CBN_EDITCHANGE(IDC_COMBO_COMPORT, OnEditchangeComboComport)
ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRS232TUTDlg message handlers
BOOL CRS232TUTDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
InitComboBox();
return TRUE; // return TRUE unless you set the focus to a control
}
void CRS232TUTDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CRS232TUTDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CRS232TUTDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CRS232TUTDlg::Settings()
{
// if port is already opened then close port.
if( m_mscomm.GetPortOpen())
m_mscomm.SetPortOpen(false);
// Setting comport
m_mscomm.SetCommPort(m_cboComPort.GetCurSel()+ 1);
// Setting Handshaking
m_mscomm.SetHandshaking(m_cboHandshaking.GetCurSel());
//
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);//"9600,N,8,1");
m_mscomm.SetRThreshold(1); //
// set for input direction
m_mscomm.SetInputLen(1);
m_mscomm.SetInBufferSize(1024);
m_mscomm.SetInputMode(0);
m_mscomm.SetOutBufferSize(1024);
m_mscomm.SetPortOpen(true);
}
void CRS232TUTDlg::InitComboBox()
{
// ComboBox ComPort
m_cboComPort.ResetContent();
m_cboComPort.AddString("COM1");
m_cboComPort.AddString("COM2");
m_cboComPort.SetCurSel(0);
//m_cboComPort
// ComboBox BitRate
m_cboBitRate.ResetContent();
m_cboBitRate.InsertString(0,"600");
m_cboBitRate.InsertString(1,"1200");
m_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();
m_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);
// 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);
}
void CRS232TUTDlg::OnButtonExit()
{
// TODO: Add your control notification handler code here
if ( m_mscomm.GetPortOpen() )
m_mscomm.SetPortOpen(false);
OnOK();
}
void CRS232TUTDlg::OnEditchangeComboComport()
{
// TODO: Add your control notification handler code here
}
void CRS232TUTDlg::OnButtonSend()
{
// TODO: Add your control notification handler code here
UpdateData();
Settings();
// send data
m_mscomm.SetOutput((COleVariant)m_strTransfer);
UpdateData(false);
}
BEGIN_EVENTSINK_MAP(CRS232TUTDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CRS232TUTDlg)
ON_EVENT(CRS232TUTDlg, IDC_MSCOMM1, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CRS232TUTDlg::OnOnCommMscomm1()
{
// TODO: Add your control notification handler code here
UpdateData();
switch( m_mscomm.GetCommEvent()){
case 1: // comEvSend
break;
case 2:// comEvReceive
VARIANT data = m_mscomm.GetInput();
m_strReceive += (CString)data.bstrVal;
break;
case 3:// comEvCTS
break;
case 4://comEvDSR
break;
case 5: //comEvCD
break;
case 6://comEvRing
break;
case 7: //comEvEOF
break;
};
UpdateData(false);
}
void CRS232TUTDlg::OnButtonClear()
{
// TODO: Add your control notification handler code here
UpdateData();
m_strReceive = "";
UpdateData(false);
}
CString CRS232TUTDlg::getCurStrInCombobox(const CComboBox &a)
{
CString str;
a.GetLBText(a.GetCurSel(),str);
return str;
}
Chia sẻ với bạn bè của bạn: |