VC6.0MFC串口通信编写全过程(DOC)
- 格式:doc
- 大小:242.50 KB
- 文档页数:17
VC上位机MFC利用串口控件发送接收数据程序代码打开vc++6.0,建立一个基于对话框的mfc应用程序。
添加控件后会弹出一个确认框
点击“确定”
单击\,控件将被成功添加
然后在控件的属性里进行一些必要的配置:
Inputmode设置为1-binary,这意味着以二进制模式检查数据
其它的用默认值。
您还可以使用oninitdialog()函数中的代码进行设置,如下所示:
设置好以后,要在程序的开始打开串口,不然是没发使用的。
在oninitdialog中加入以下代码:
睡眠(100);方差数据;intdata_len;charcdata[1024];
cdata[data_len]=0;
//CDATA是指向所接收字符串的指针
m_list.addstring(cdata);//在listbox控件中显示接收到的数据}。
串口调试助手源程序及编程详细过程作者:龚建伟 2001.6.20可以任意转载,但必须注明作者和说明来自,不得作为商用目次:1.建立项目2.在项目中插入MSComm控件3.利用ClassWizard定义CMSComm类控制变量4.在对话框中添加控件5.添加串口事件消息处理函数OnComm()6.打开和设置串口参数7.发送数据在众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短一个月,在全国各地累计下载量近5000人次,在近200多个电子邮件中,20多人提供了使用测试意见,更有50多位朋友提出要串口调试助手的源代码,为了答谢谢朋友们的支持,公开推出我最初用VC控件MSComm编写串口通信程序的源代码,并写出详细的编程过程,姑且叫串口调试助手源程序V1.0或VC串口通讯源程序吧,我相信,如果你用VC编程,那么有了这个代码,就可以轻而易举地完成串口编程任务了。
(也许本文过于详细,高手就不用看)开始吧:1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点);2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX 控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
用MFC实现串口编程龚建伟评论:本文既写了在Windows中怎样用VC控件MSComm,又说明了API技术编程方法,在写用MSComm控件时,数据类型的转换说得不是太明白,初次涉猎串口编程的朋友恐怕看了还是编不出来;直接从底层编写的部分值得一读,说得较为详细,但你得先从VC教本上看一看什么是线程。
一.串行通信的基本原理二.串口信号线的接法三.16位串口应用程序的简单回顾四.在MFC下的32位串口应用程序㈠使用ActiveX控件?㈡使用32位的API 通信函数本文详细介绍了串行通信的基本原理,以及在Windows NT、Win98环境下用MFC实现串口(COM)通信的方法:使用ActiveX控件或Win API.并给出用Visual C++6.0编写的相应MFC32位应用程序。
关键词:串行通信、VC++6.0、ActiveX控件、Win API、MFC32位应用程序、事件驱动、非阻塞通信、多线程.在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助。
一.串行通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
mfc串口类使用方法MFC串口类使用方法一、引言MFC(Microsoft Foundation Classes)是微软公司为Windows操作系统开发的一套C++类库,提供了一系列的类和函数,简化了Windows程序的开发。
MFC串口类是其中的一个重要组成部分,用于实现在Windows平台下对串口进行读写操作。
本文将介绍MFC串口类的使用方法,帮助读者快速上手并实现串口通信功能。
二、MFC串口类的基本介绍MFC提供了一个名为CSerialPort的串口类,通过该类可以方便地进行串口的打开、关闭、读写等操作。
在使用MFC串口类之前,需要在代码中包含相应的头文件:#include "afxwin.h"三、打开串口在使用串口之前,首先需要打开串口。
打开串口的函数原型如下:BOOL CSerialPort::Open(int nPort, int nBaud, char nParity, int nDatabits, int nStopbits, DWORD dwCommEvents, UINT nBufferSize = 512);参数说明:nPort:串口号,例如1代表COM1;nBaud:波特率,例如9600;nParity:奇偶校验位,可以选择'N'(无校验)、'E'(偶校验)或'O'(奇校验);nDatabits:数据位,可以选择5、6、7或8;nStopbits:停止位,可以选择1或2;dwCommEvents:串口事件,可以选择EV_RXCHAR(接收到字符时触发)或EV_RXFLAG(接收到指定标志位时触发);nBufferSize:缓冲区大小,默认为512。
示例代码如下:CSerialPort serial;if (serial.Open(1, 9600, 'N', 8, 1, EV_RXCHAR)){// 串口打开成功}else{// 串口打开失败}四、关闭串口在使用完串口后,需要关闭串口。
本文详细介绍了串行通信的基本原理,以及在Windows NT、Win98环境下用MFC实现串口(COM)通信的方法:使用ActiveX控件或Win API.并给出用Visual C++6.0编写的相应MFC32位应用程序。
关键词:串行通信、VC++6.0、ActiveX控件、Win API、MFC32位应用程序、事件驱动、非阻塞通信、多线程.在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助。
一.串行通信的基本原理回到页顶串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
二.串口信号线的接法回到页顶一个完整的RS-232C接口有22根线,采用标准的25芯插头座(或者9芯插头座)。
25芯和9芯的主要信号线相同。
以下的介绍是以25芯的RS-232C为例。
①主要信号线定义:2脚:发送数据TXD;3脚:接收数据RXD;4脚:请求发送RTS;5脚:清除发送CTS;6脚:数据设备就绪DSR;20脚:数据终端就绪DTR;8脚:数据载波检测DCD;1脚:保护地;7脚:信号地。
Vc++串口通信(加密解密以及反馈协议)一.主要功能:实现两台计算机通过串口进行数据通信。
二.软件特色:与本软件传输协议不同的串口信息接收到之后不做显示,发送过程中经过数据包加首部尾部来确定数据是否为同一个协议,之后再经过加密发送,接受时先解密,然后经过除去首部跟尾部来得到本来的数据。
三.加密原理:发送时先加首部跟尾部,然后再将所有字符串转换成字符数组,进而对数组中的每个字符进行处理,具体方法是首先获得本次发送的数据总长度,单个字符减去本次字符串总长度的数字,再将数组转换成字符串发送出去,解码时先将受到的字符串转换成字符数组,再将每个字符加上本次接收到的字符串总长度,然后除去首部跟尾部,得到实际有用的数据。
四.协议原理:在每次收到数据之后进行判断,是否为预先设定的反馈数据,如果是,则不做处理,如果不是,则进行发送反馈数据操作。
每次发送完数据对话框有提示“数据已发送“,当收到反馈数据时,提示”数据已成功接收“。
五.主要问题:单次发送的数据不能大于33个字符,否则会接收不正常。
波特率已加到程序里面固定为“115200“,如果太小了可能会出现接收不到信息或者接收速度慢等情况。
六.界面图示:1.发送完数据,但是对方未收到。
2.发送完数据,对方已经成功接收。
七.部分代码界面设计类向导中的函数设计“serilDlg.cpp”文件内部代码#include "stdafx.h"#include "seril.h"#include "serilDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifint comseril;///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass 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// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CSerilDlg dialogCSerilDlg::CSerilDlg(CWnd* pParent /*=NULL*/): CDialog(CSerilDlg::IDD, pParent){//{{AFX_DATA_INIT(CSerilDlg)m_strRXData = _T("");m_strTXData = _T("");m_TestFlag = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CSerilDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CSerilDlg)DDX_Control(pDX, IDC_OPENSERIL, m_Opensril);DDX_Control(pDX, IDC_COM, m_serilcom);DDX_Text(pDX, IDC_EDIT_RXDATA, m_strRXData);DDX_Text(pDX, IDC_EDIT_TXDATA, m_strTXData);DDX_Control(pDX, IDC_MSCOMM1, m_ctrlComm);DDX_Text(pDX, IDC_TESTFLAG, m_TestFlag);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CSerilDlg, CDialog)//{{AFX_MSG_MAP(CSerilDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_CLEAR, OnClear)ON_BN_CLICKED(IDC_CLEARSEND, OnClearsend)ON_CBN_CLOSEUP(IDC_COM, OnCloseupCom)ON_BN_CLICKED(IDC_FASONG, OnFasong)ON_BN_CLICKED(IDC_OPENSERIL, OnOpenseril)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CSerilDlg message handlersBOOL CSerilDlg::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 dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control}void CSerilDlg::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 CSerilDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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 icondc.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 CSerilDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}BEGIN_EVENTSINK_MAP(CSerilDlg, CDialog)//{{AFX_EVENTSINK_MAP(CSerilDlg)ON_EVENT(CSerilDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)//}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()void CSerilDlg::OnComm(){// TODO: Add your control notification handler code hereVARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[20480],rxtemp[20480]={0},top[20480],down[20480],jm[20480],jm1[20480]; //设置BYTE数组An 8-bit integerthat is not signed.CString strtemp,test,test1;if (m_ctrlComm.GetCommEvent() == 2) //事件值为2表示接收缓冲区内有字符{ // CString rw="rw";////////以下你可以根据自己的通信协议加入处理代码variant_inp = m_ctrlComm.GetInput(); //读缓冲区safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len = safearray_inp.GetOneDimSize(); //得到有效数据长度for(k = 0;k < len;k++){safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组}if(rxdata[0] == 'r'&&rxdata[1] == 'e'&&rxdata[2] == 'c'&&rxdata[3] == 'i'&&rxdata[4] == 'v'&&rxdata[5] == 'e'){m_TestFlag = "已被成功接收";}else{m_ctrlComm.SetOutput(COleVariant("recive"));}for (k=0;k<5;k++){top[k]=rxdata[k];}for(k=0;k<4;k++){down[k]=rxdata[len-4+k];}if(top[0] == 'b' && top[1] == 'e' && top[2] == 'g' && top[3] == 'i' && top[4] == 'n' && down[0] == 'o' && down[1] == 'v' && down[2] == 'e' && down[3] == 'r'){for(k=0;k<len-9;k++){rxtemp[k] = rxdata[k+5];}for(k=0;k<len-9;k++){jm1[k] = (rxtemp[k] -len+9);}for(k = 0;k < len-9;k++) //将数组转换为Cstring型变量{BYTE bt = *(char*)(jm1+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放m_strRXData += strtemp;}}}UpdateData(FALSE); //更新编辑框内容(主要是接收编辑框中的)}void CSerilDlg::OnFasong(){long siz,k;CString SendAll,sendal;UpdateData(TRUE); //读取编辑框内容siz = strlen( m_strTXData) ;char cha[20480] ;char cha1[20480];char cha2[20480];strcpy(cha, m_strTXData);for (k=0;k<siz;k++){cha1[k] = cha[k] +siz ;}CString str(cha1,siz);SendAll = "begin" + str + "over";m_ctrlComm.SetOutput(COleVariant(SendAll)); //发送数据m_TestFlag = "数据已发送";UpdateData(FALSE); //读取编辑框内容}void CSerilDlg::OnOpenseril(){// TODO: Add your control notification handler code herem_ctrlComm.SetCommPort(comseril); //选择com口if ( m_ctrlComm.GetPortOpen() ){m_ctrlComm.SetPortOpen(FALSE);// 关闭串口// AfxMessageBox("cannot open serial port");AfxMessageBox("串口已关闭");}else{m_ctrlComm.SetPortOpen(TRUE);//打开串口AfxMessageBox("串口打开成功");SetDlgItemText(IDC_OPENSERIL,"关闭串口"); //显示串口已经关闭m_ctrlComm.SetSettings("115200,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据// m_TestFlag = "未测试";UpdateData(FALSE);}}void CSerilDlg::OnCloseupCom(){comseril = m_serilcom.GetCurSel();}void CSerilDlg::OnClear(){m_strRXData = "";UpdateData(FALSE); //更新编辑框内容// TODO: Add your control notification handler code here}void CSerilDlg::OnClearsend(){// TODO: Add your control notification handler code herem_strTXData = "";UpdateData(FALSE);}、Seril.h内代码// serilDlg.h : header file////{{AFX_INCLUDES()#include "mscomm.h"//}}AFX_INCLUDES#if !defined(AFX_SERILDLG_H__1B7176B4_DDC7_45B3_B636_2597E461F275__INCLUDED_) #define AFX_SERILDLG_H__1B7176B4_DDC7_45B3_B636_2597E461F275__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////// CSerilDlg dialogclass CSerilDlg : public CDialog{// Constructionpublic:CSerilDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CSerilDlg)enum { IDD = IDD_SERIL_DIALOG };CButton m_Opensril;CComboBox m_serilcom;CString m_strRXData;CString m_strTXData;CMSComm m_ctrlComm;CString m_TestFlag;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CSerilDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CSerilDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnClear();afx_msg void OnClearsend();afx_msg void OnCloseupCom();afx_msg void OnFasong();afx_msg void OnComm();afx_msg void OnOpenseril();DECLARE_EVENTSINK_MAP()//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_SERILDLG_H__1B7176B4_DDC7_45B3_B636_2597E461F275__INCLUDED_)日期:2013-4-10。
VC(MFC)编写串口调试助手1.序确定基本功能:1.自动寻找串口,并自动添加到下拉框中共选择;2.有波特率、数据位、停止位、校验位的选择设置;3.串口打开控制按钮;4.发送、清除按钮;5.接收是自动实现的;6.有定时自动发送功能;7.有传送文件功能;8.有状态栏显示,指示串口状态,设置参数和发送接收显示。
下面就一步步实现,本人纯业余,只是记录下来这个学习过程,请勿拍砖。
开发平台Visual C++6.0英文版,电脑是i7-2670Q四核8G内存1G独显的笔记本,装的win7 64位旗舰版,因此VC6兼容不是太好,有些小毛病,不过不影响编写。
2.创建MFC项目File -> New -> Projects选择MFC AppWizard(exe),项目名称commassist选择OK选中Dialog based,点击Next> 。
默认选项,点击Next> ,继续默认选项,点击Next> ,如果选中As a statically linked library,生产的EXE可直接在没装VC的机器上运行。
可以在项目中进行更改。
选择第二个CCommassistDlg,点击Finish点击OK。
项目创建完毕,进入项目。
删除界面上确定和取消按钮以及静态文字。
3.创建界面保存后便可以开始创建界面了。
参考界面仿照设计的界面,具体添加按钮或编辑框等的布局步骤就不用细说了。
4.图标修改在资源视图中选择Icon右键InsertIcon加入打开和关闭的Icon图标或自行绘制,如下图IDR_MAINFRAME原为MFC提供的图标,这里我直接改成自己的,生成EXE后将会显示这个图标。
下面将帮助页面图标也改为自绘图标。
在打开按钮旁边加入自绘的打开和关闭图标:先加入工具条中的Picture,然后选中右键看属性,并如图将Image选为默认的IDI_ICON_CLOSE。
如下图5.基本设置下面对各个按钮及编辑框设置进行描述右键串口对应的Combo Box,ID设置为IDC_COMLIST,Type设置为Drop List,Sort不选择(我系统是WIN7 64位,不选中反而自动排序,至于XP得试试看了,以下的选择相同)。
MFC串⼝通信本⽂详细介绍了串⾏通信的基本原理,以及在Windows NT、Win98环境下⽤MFC实现串⼝(COM)通信的⽅法:使⽤ActiveX 控件或Win API.并给出⽤Visual C++6.0编写的相应MFC32位应⽤程序。
关键词:串⾏通信、VC++6.0、ActiveX控件、Win API、MFC32位应⽤程序、事件驱动、⾮阻塞通信、多线程.在Windows应⽤程序的开发中,我们常常需要⾯临与外围数据源设备通信的问题。
计算机和单⽚机(如MCS-51)都具有串⾏通信⼝,可以设计相应的串⼝通信程序,完成⼆者之间的数据通信任务。
实际⼯作中利⽤串⼝完成通信任务的时候⾮常之多。
已有⼀些⽂章介绍串⼝编程的⽂章在计算机杂志上发表。
但总的感觉说来不太全⾯,特别是介绍32位下编程的更少,且很不详细。
笔者在实际⼯作中积累了较多经验,结合硬件、软件,重点提及⽐较新的技术,及需要注意的要点作⼀番探讨。
希望对各位需要编写串⼝通信程序的朋友有⼀些帮助。
⼀.串⾏通信的基本原理回到页顶串⾏端⼝的本质功能是作为CPU和串⾏设备间的编码转换器。
当数据从CPU经过串⾏端⼝发送出去时,字节数据转换为串⾏的位。
在接收数据时,串⾏的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串⼝是系统资源的⼀部分。
应⽤程序要使⽤串⼝进⾏通信,必须在使⽤之前向操作系统提出资源申请要求(打开串⼝),通信完成后必须释放资源(关闭串⼝)。
⼆.串⼝信号线的接法回到页顶⼀个完整的RS-232C接⼝有22根线,采⽤标准的25芯插头座(或者9芯插头座)。
25芯和9芯的主要信号线相同。
以下的介绍是以25芯的RS-232C为例。
①主要信号线定义:2脚:发送数据TXD;3脚:接收数据RXD;4脚:请求发送RTS;5脚:清除发送CTS;6脚:数据设备就绪DSR;20脚:数据终端就绪DTR;8脚:数据载波检测DCD;1脚:保护地;7脚:信号地。
在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助一.串行通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
串口通信程序的流程如下图:二.串口信号线的接法一个完整的RS-232C接口有22根线,采用标准的25芯插头座(或者9芯插头座)。
25芯和9芯的主要信号线相同。
以下的介绍是以25芯的RS-232C为例。
①主要信号线定义:2脚:发送数据TXD; 3脚:接收数据RXD; 4脚:请求发送RTS; 5脚:清除发送CTS;6脚:数据设备就绪DSR;20脚:数据终端就绪DTR;8脚:数据载波检测DCD;1脚:保护地; 7脚:信号地。
②电气特性:数据传输速率最大可到20K bps,最大距离仅15m.注:看了微软的MSDN 6.0,其Windows API中关于串行通讯设备(不一定都是串口RS-232C或RS-422或RS-449)速率的设置,最大可支持到RS_256000,即256K bps! 也不知道到底是什么串行通讯设备?但不管怎样,一般主机和单片机的串口通讯大多都在9600 bps,可以满足通讯需求。
网络与通信实验报告题目:串口通行实验班级:0309103学号:*********姓名:***指导老师:付大丰日期:2012-10-21一、实验要求把两台计算机的串口通过串口线连在一起,通过串口实现两台计算机通讯。
可以利用高级语言、C语言编程实现,要求程序界面友好,有发送和接收功能,其接收和发送内容可在屏幕上显示。
二、实验原理串口通讯把数据的字节分解成单个的二进制比特流依次传输,其结构简单,连接线少,应用非常广泛。
实现串口通信的方法很多。
如:利用标准通信函数实现串口通信、利用API实现串口通信和利用ActiveX控件实现。
本文主要采用ActiveX控件Microsoft CommunicationsControl(MSComm)编程,Windows平台先进的ActiveX技术使得对串口编程不再需要处理烦琐的细节。
利用已有的AxtiveX控件,只需要编写少量的代码,就可以轻松高效地完成任务。
以下对ActiveX控件属性进行简单介绍,在ClassWizard中为新创建的通信控件定义成员对象(CMSComm m_comm),通过该对象便可以对串口属性进行设置,MSComm控件共有27个属性,这里只介绍其中几个常用属性:CommPort:设置并回通讯端口号,缺省为COMl。
Settings:以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
PortOpen:设置并返回通讯端口的状态,也可以打开和关闭端口。
Input:从接收缓冲区返回和删除字符。
Output:向发送缓冲区写一个字符串。
InputLen:设置每次Input读入的字符个数,缺省值为0,表明读取接收缓冲区中的全部内容。
InBufferCount:返回接收缓冲区中已接收到的字符数,将其置0可以清除接收缓冲区。
InputMode:定义Input属性获取数据的方式(为0:文本方式;为1:二进制方式)。
RThreshold和SThreshold:表示在OnComm事件发生之前,接收缓冲区或发送缓冲区中可以接收的字符数。
摘要:本文介绍了在Windows平台下串行通信的实现机制,讨论了根据不同的条件用Visual C++ 设计串行通信程序的三种方法,并结合实际,实现对温度数据的接收监控。
在实验室和工业应用中,串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。
依据不同的条件实现对串口的灵活编程控制是我们所需要的。
在光学镜片镀膜工艺中,用单片机进行多路温度数据采集控制,采集结果以串行方式进入主机,每隔10S向主机发送一次采样数据,主机向单片机发送相关的控制命令,实现串行数据接收,处理,记录,显示,实时绘制曲线。
串行通信程序开发环境为 VC++ 6.0。
Windows下串行通信与以往DOS下串行通信程序不同的是,Windows不提倡应用程序直接控制硬件,而是通过Windows操作系统提供的设备驱动程序来进行数据传递。
串行口在Win 32中是作为文件来进行处理的,而不是直接对端口进行操作,对于串行通信,Win 32 提供了相应的文件I/O函数与通信函数,通过了解这些函数的使用,可以编制出符合不同需要的通信程序。
与通信设备相关的结构有COMMCONFIG ,COMMPROP,COMMTIMEOUTS,COMSTAT,DCB,MODEMDEVCAPS,MODEMSETTINGS共7个,与通信有关的Windows API函数共有26个,详细说明可参考MSDN帮助文件。
以下将结合实例,给出实现串行通信的三种方法。
实现串行通信的三种方法方法一:使用VC++提供的串行通信控件MSComm 首先,在对话框中创建通信控件,若Control工具栏中缺少该控件,可通过菜单Project --> Add to Project --> Components and Control插入即可,再将该控件从工具箱中拉到对话框中。
此时,你只需要关心控件提供的对 Windows 通讯驱动程序的 API 函数的接口。
用MFC实现串口编程龚建伟评论:本文既写了在Windows中怎样用VC控件MSComm,又说明了API技术编程方法,在写用MSComm控件时,数据类型的转换说得不是太明白,初次涉猎串口编程的朋友恐怕看了还是编不出来;直接从底层编写的部分值得一读,说得较为详细,但你得先从VC教本上看一看什么是线程。
一.串行通信的基本原理二.串口信号线的接法三.16位串口应用程序的简单回顾四.在MFC下的32位串口应用程序㈠使用ActiveX控件㈡使用32位的API 通信函数本文详细介绍了串行通信的基本原理,以及在Windows NT、Win98环境下用MFC实现串口(COM)通信的方法:使用ActiveX控件或Win API.并给出用Visual C++6.0编写的相应MFC32位应用程序。
关键词:串行通信、VC++6.0、ActiveX控件、Win API、MFC32位应用程序、事件驱动、非阻塞通信、多线程.在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助。
一.串行通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
c语言怎么写串口通信编程串口通信是一种广泛应用于嵌入式系统和电子设备之间的通信方式。
无论是嵌入式开发还是电子设备控制,串口通信都是常见的需求。
在C语言中,实现串口通信需要通过操作串口的硬件寄存器和使用相应的通信协议来实现数据的发送和接收。
本文将一步一步介绍如何使用C语言编写串口通信程序。
第一步:打开串口要开始串口通信,首先需要打开串口。
在C语言中,可以使用文件操作函数来打开串口设备。
通常,串口设备被命名为/dev/ttyS0,/dev/ttyS1等,具体名称取决于系统。
下面是一个打开串口设备的示例代码:cinclude <stdio.h>include <fcntl.h>include <termios.h>int open_serial_port(const char *port) {int fd = open(port, O_RDWR O_NOCTTYO_NDELAY);if (fd == -1) {perror("open_serial_port");return -1;}设置串口属性struct termios options;tcgetattr(fd, &options);cfmakeraw(&options);cfsetspeed(&options, B9600);tcsetattr(fd, TCSANOW, &options);return fd;}int main() {const char *port = "/dev/ttyS0";int fd = open_serial_port(port);if (fd == -1) {打开串口失败,处理错误return -1;}串口已打开,可以进行数据的读写操作return 0;}在上面的代码中,open_serial_port函数用于打开指定的串口设备并进行一些必要的设置。
用MFC实现串口编程龚建伟评论:本文既写了在Windows中怎样用VC控件MSComm,又说明了API技术编程方法,在写用MSComm控件时,数据类型的转换说得不是太明白,初次涉猎串口编程的朋友恐怕看了还是编不出来;直接从底层编写的部分值得一读,说得较为详细,但你得先从VC教本上看一看什么是线程。
一.串行通信的基本原理二.串口信号线的接法三.16位串口应用程序的简单回顾四.在MFC下的32位串口应用程序㈠使用ActiveX控件㈡使用32位的API 通信函数本文详细介绍了串行通信的基本原理,以及在Windows NT、Win98环境下用MFC实现串口(COM)通信的方法:使用ActiveX控件或Win API.并给出用Visual C++6.0编写的相应MFC32位应用程序。
关键词:串行通信、VC++6.0、ActiveX控件、Win API、MFC32位应用程序、事件驱动、非阻塞通信、多线程.在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助。
一.串行通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
用MFC实现串口编程龚建伟评论:本文既写了在Windows中怎样用VC控件MSComm,又说明了API技术编程方法,在写用MSComm控件时,数据类型的转换说得不是太明白,初次涉猎串口编程的朋友恐怕看了还是编不出来;直接从底层编写的部分值得一读,说得较为详细,但你得先从VC教本上看一看什么是线程。
一.串行通信的基本原理二.串口信号线的接法三.16位串口应用程序的简单回顾四.在MFC下的32位串口应用程序㈠使用ActiveX控件?㈡使用32位的API 通信函数本文详细介绍了串行通信的基本原理,以及在Windows NT、Win98环境下用MFC实现串口(COM)通信的方法:使用ActiveX控件或Win API.并给出用Visual C++6.0编写的相应MFC32位应用程序。
关键词:串行通信、VC++6.0、ActiveX控件、Win API、MFC32位应用程序、事件驱动、非阻塞通信、多线程.在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
计算机和单片机(如MCS-51)都具有串行通信口,可以设计相应的串口通信程序,完成二者之间的数据通信任务。
实际工作中利用串口完成通信任务的时候非常之多。
已有一些文章介绍串口编程的文章在计算机杂志上发表。
但总的感觉说来不太全面,特别是介绍32位下编程的更少,且很不详细。
笔者在实际工作中积累了较多经验,结合硬件、软件,重点提及比较新的技术,及需要注意的要点作一番探讨。
希望对各位需要编写串口通信程序的朋友有一些帮助。
一.串行通信的基本原理串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
最详细的VC++串口上位机编程VC++串口上位机编程串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。
(见文章末尾图)3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。
程序的编写:1、打开VC++6.0建立基于对话框的MFC应用程序Test,2、在项目中插入MSComm控件:工程->增加到工程->Components and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。
其于MFC的串口调试助手编辑过程 一、新建 打开VC6.0 文件 新建 工程 MFC AppWiard(exe) 位置(选择保存工程位置) 工程名称(输入工程名XXXX) 确定 选择基本对话框 下一步 下一步 下一步 选择(CXXXXDlg) 完成 确定 在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消” 及提示框)删除或修改使用,至此基本框架完成如下图:
二、往生成的基本框架中添加控件 1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再将控件添加到基本框内使用,步骤如下: 菜单栏 工程 添加到工程 Components and controls… Registered ActiveX Controls 选择“Microsoft Communications Control, version 6.0” Insert 确定 OK 关闭此子窗口完成添加操作标志如上图所示。 2、将刚才添加添加到控件列表框内的串口控件添加到基本框架内 点击控件列表框内的串口控件,此时光标变为“十”形,在基本框架内随意划取一矩形区域,即可以添加串口控件,不需要修改此控件的大小及位置,因为程编译运行后此控件是看不到的,步骤结果如下图:
此控件(标志)是下面步骤添加进来的串口控件
基本框架 3、继续往基本框架内添加用于编辑发送数据的输入编辑框及输出编辑框,同理选择控件列表框内的“编辑框控件”,以相同的操作即可添加两个编辑窗口及一个按纽控件如下图所示:
这两个窗口需要修改大小及位置,因为程序运行后将会显示而串口通信控件则不显示,上图是运行后的效果。 4、对以上四个控件编程步骤如下: a、右击串口通信控件 建立类向导 Member variables Control IDS中选择IDC_MSCOMM1 add variable… Member variable name中输入控件变量名m_ctrlComm(变量名可以随意选取,但程序中应与所取变量名一致) OK 确
定
选择其中任意一个作为输入编辑框及输出编辑框 b、右击编辑框、属性、常规、ID:中输入ID号,此编辑框用于接收显示数据的其ID号为IDC_EDIT_RXDATA(可以随意选取,但程序中应与所取ID号一致),再在此窗口的样式中勾选”多行”,同时将“自动水平滚动(T)”勾选去掉,再勾选“垂直滚动(V)”,此勾选操作是用于垂直多行显示的,按回车后即可输入;同理右击另一编辑框输入ID号为IDC_EDIT_TXDATA此编辑框用于编辑发送数据的,同样也选上用于垂直多行显示,发送框可以不用垂直多行显示;再为按钮控件添加ID号,为IDC_BUTTON_MANUALSEND,并将标题中的“Button1”改为“发送”,功能是按一
次就把发送编辑框中的内容发送一次。 C、为以上两个编辑框添加变量,与串口通信控件一样添加,为IDC_EDIT_RXDATA添加CString型变量m_strRXData ;为IDC_EDIT_TXDATA添加CString型变量m_strTXData。说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符
数据。 D、添加串口事件消息处理函数OnComm() 打开ClassWizard->Message Maps,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。 这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。在函数中加入如下代码: 代码段1: void CScommTestDlg::OnComm() { // TODO: Add your control notification handler code here
VARIANT variant_inp;//定义一个VARIANT类对象 COleSafeArray safearray_inp;//定义一个COleSafeArray对象 LONG len,k; BYTE rxdata[2048];//设置BYTE数组 AN 8—intterthat is not signed. CString strtemp; if (m_ctrlComm.GetCommEvent()==2)//事件值为2表示接收缓冲区内有数据 { ////以下你可以根据自己的通信协议加入处理代码 variant_inp=m_ctrlComm.GetInput();//读缓冲区 safearray_inp=variant_inp;//VARIANT型变量转换为ColeSafeArray型变量 len=safearray_inp.GetOneDimSize(); for(k=0;k{ safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组 } for(k=0;k{ BYTE bt=*(char*)(rxdata+k); //if(m_ctrlHexSend.GetCheck())//如果是HEX显示则转为16进制 // strtemp.Format("%02x ",bt); //将16进制数送入临时变量strtemp存放 // else
提示2:此三句是下面用于是否是十六进制发送的,暂时可以不用理会
提示1:此句以下才是我们要添加的语句 strtemp.Format("%c",bt);//将字符送入临时变量strtemp存放 m_strRXData+=strtemp;//加入接收编辑框对应字符串 } } UpdateData(FALSE);//更新编辑框内容(主要是接收编辑框中的) } 到目前为止还不能在接收编辑框中看到数据,因为我们还没有打开串口,但运行程序不应该有任何错误,不然,你肯定哪儿没看仔细,因为我是打开VC6对照着做一步写一行的,运行试试。没错吧?那么做下一步: E、打开串口和设置串口参数 你可以在你需要的时候打开串口,例如在程序中做一个开始按钮,在该按钮的处理函数中打开串口。现在我们在主对话框的CSCommTestDlg::OnInitDialog()打开串口,加入如下代码: 代码段2: BOOL CSCommTestDlg::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 // m_ComboBox.SetCurSel(0);//打开软件时串口选择框默认显示COM1
// m_BaudRate_M.SetCurSel(0);//打开软件时波特率选择框默认显示9600 // m_Date_Select_M.SetCurSel(0);//打开软件时数据位选择框默认显示8 // m_StopBit_M.SetCurSel(0);//打开软件时停止位选择框默认显示1 // m_ParityCheck_M.SetCurSel(0);//打开软件时奇偶校验选择框默认显示无校验N
提示3:此句以下才是我们要添加的语句 提示4:此5
句是我们下面要用到的暂时可以不用理会 //下面if语句用于打开默认串口 /************************************************************/ if(m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(FALSE);//关闭串口 } m_ctrlComm.SetCommPort(1);//打开软件时默认使用COM1串口 if(!m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(TRUE);//打开串口 } else { AfxMessageBox("cannot open serial port"); } /*************************************************************/
m_ctrlComm.SetSettings("9600,n,8,1");//打开软件时端口设置默认为波特率9600,无校验位,8位数据,1位停止位 m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据 m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0 m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据 return TRUE; // return TRUE unless you set the focus to a control } F、发送数据,先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->Message Maps,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加OnButtonManualsend()函数,并在函数中添加如下代码: 代码段3: void CSCommTestDlg::OnButtonManualsend() { // TODO: Add your control notification handler code here UpdateData(TRUE); //读取编辑框内容 m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据 } 此时运行程序,在发送编辑框中随意输入数,单击发送按钮,若出错则修改后再测试,直到成功再进行以下操作。 5、添加两个“组框”或“静态文本”控件,调整位置及大小,在标师处输入提示文字,