VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

这篇具有很好参考价值的文章主要介绍了VC++6.0上实现PC机与单片机串口通信的PC端上位机软件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.简介

我做这个的主要原因是选了一个PC和单片机的全双工串口通信作为课设题目,单片机端是用汇编语言编程且要预先下载到板子里,关于这个这里我就不多说,主要说说怎么实现PC端的上位机软件。早知道要写软件,鬼才选这个课题。但是自己选的路哭着也要走完。

做的时候我也感觉到,C++真难啊,,,但不可否认它确实是个好东西。

写这样的软件也是有几种方法思路的,因为我怕太难的学不会的话,到时候课设就凉凉了。所以我选择了较为亲民的ActiveX控件的方法。

Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。

MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,所以我们不必花时间去了解较为复杂的API函数,而且在VC、VB、什么什么等语言中都可以使用。具体来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,另一个是查询法。

1.通讯方式

MSComm控件提供下列两种处理通讯的方式:事件驱动方式查询方式

1.事件驱动方式

事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,事件发生时需要得到通知,就比如,在串口接收缓冲区中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用MSComm控件的OnComm事件捕获并处理这些通讯事件。OnComm事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅CommEvent 属性。在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。这种方法的优点是程序响应及时,可靠性高。每个MSComm控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。

2.查询方式

查询方式本质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。在程序的每个关键功能之后,可以通过检查CommEvent属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。比如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。 

2.MSComm控件常用属性

MSComm 控件有很多重要的属性,但首先必须熟悉几个属性。知道这几个几乎就能横着走了。

CommPort    设置并返回通讯端口号。 

Settings        以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 

PortOpen      设置并返回通讯端口的状态。也可以打开和关闭端口。 

Input             从接收缓冲区返回和删除字符。 

Output          向传输缓冲区写一个字符串。

1.CommPort属性

设置并返回通讯端口号

语法object.CommPort[value ] (value 一整型值,说明端口号。) 

说明在设计时,value可以设置成从 1 到 16 的任何数(缺省值为 1)。但是如果用PortOpen属性打开一个并不存在的端口时,MSComm 控件会产生错误 68(设备无效)。

注意:必须在打开端口之前设置 CommPort 属性。

2.PortOpen属性

设置并返回通讯端口的状态(开或关)。该属性在设计时无效。

MSComm.PortOpen=true; //打开端口

MSComm.PortOpen=false; //关闭端口并清除接收和传输缓冲区

说明

设置PortOpen属性为True打开端口。设置为False关闭端口并清除接收和传输缓冲区。当应用程序终止时,MSComm 控件自动关闭串行端口。

在打开端口之前,确定 CommPort 属性设置为一个合法的端口号。如果 CommPort 属性设置为一个非法的端口号,则当打开该端口时,MSComm 控件产生错误68(设备无效)。

另外,串行端口设备必须支持Settings 属性当前的设置值。如果 Settings 属性包含硬件不支持的通讯设置值,那么硬件可能不会正常工作。

如果在端口打开之前,DTREnable或RTSEnable属性设置为True,当关闭端口时,该属性设置为False。否则,DTR和RTS线保持其先前的状态。

数据类型:Boolean

3.RThreshold 属性

在MSComm控件设置CommEvent属性为comEvReceive并产生OnComm之前,设置并返回的要接收的字符数

语法object.Rthreshold [ = value ](value 整型表达式,说明在产生OnComm 事件之前要接收的字符数。)

说明当接收字符后,若Rthreshold属性设置为0(缺省值)则不产生 OnComm事件。例如,设置Rthreshold为1,接收缓冲区收到每一个字符都会使MSComm控件产生OnComm事件。

4.CTSHolding 属性

确定是否可通过查询Clear To Send (CTS)线的状态发送数据。Clear To Send 是调制解调器发送到相联计算机的信号,指示传输可以进行。该属性在设计时无效,在运行时为只读。

语法:object.CTSHolding(Boolean)

Mscomm 控件的 CTSHolding 属性设置值:True Clear To Send 线为高电平。 False Clear To Send 线为低电平。 

说明:如果Clear To Send线为低电平 (CTSHolding = False)并且超时时,MSComm控件设置CommEvent 属性为comEventCTSTO (Clear To Send Timeout) 并产生OnComm事件。

Clear To Send 线用于RTS/CTS (Request To Send/Clear To Send) 硬件握手。如果需要确定Clear To Send 线的状态,CTSHolding 属性给出一种手工查询的方法。更详细有关握手协议在 Handshaking 属性。

5.SThreshold 属性

MSComm控件设置CommEvent属性为comEvSend并产生OnComm事件之前,设置并返回传输缓冲区中允许的最小字符数

语法object.SThreshold [ = value ],value整形表达式,代表在OnComm事件产生之前在传输缓冲区中的最小字符数。 

说明:若设置Sthreshold属性为0(缺省值),数据传输事件不会产生OnComm 事件。若设置Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm控件产生OnComm事件。如果在传输缓冲区中的字符数小于value,CommEvent 属性设置为comEvSend,并产生OnComm事件。comEvSend 事件仅当字符数与 Sthreshold 交叉时被激活一次。例如,如果 Sthreshold 等于5,仅当在输出队列中字符数从 5 降到 4 时,comEvSend 才发生。如果在输出队列中从没有比 Sthreshold 多的字符,comEvSend事件将绝不会发生。

6.Handshake 常数

常数 值    描述 
comNone       0    无握手
comXonXoff    1    XOn/Xoff 握手
comRTS         2         Request-to-send/clear-to-send 握手
comRTSXOnXOff     3      Request-to-send 和 clear-to-send 握手皆可

              

7.OnComm 常数

常数  值  描述 
comEvSend        1      发送事件
comEvReceive    2    接收事件
comEvCTS     3    clear-to-send线变化
comEvDSR    4 data-set ready线变化
comEvCD      5    carrier detect 线变化
comEvRing        6         振铃检测
comEvEOF     7      文件结束

8. Error 常数

常数 描述
comEventBreak  1001 接收到中断信号 
comEventCTSTO 1002   Clear-to-send 超时 
comEventDSRTO 1003    Data-set ready 超时
comEventFrame    1004     帧错误 
comEventOverrun 1006       端口超速 
comEventCDTO 1007   Carrier detect 超时 
comEventRxOver   1008    接收缓冲区溢出 
comEventRxParity 1009  Parity 错误 
comEventTxFull    1010 传输缓冲区满
comEventDCB  1011 检索端口设备控制块 (DCB) 时的意外错误 

9.InputMode 常数

常数 描述 
    comInputModeText   0     (缺省)通过 Input 属性以文本方式取回数据
 comInputModeBinary    1     通过 Input 属性以二进制方式检取回数据

10.CDHolding属性

通过查询Carrier Detect (CD)线的状态确定当前是否有传输。Carrier Detect 是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为只读。

语法object.CDHolding

设置值CDHolding属性的设置值为: 

设置      描述 
True Carrier Detect    线为高电平 
False Carrier Detect 线为低电平

说明:注意当Carrier Detect线为高电平(CDHolding = True)且超时时,MSComm控件设置CommEvent属性为comEventCDTO(Carrier Detect 超时错误),并产生OnComm事件。

注意在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。

Carrier Detect也被称为 Receive Line Signal Detect (RLSD)

数据类型 Boolean

11.DSRHolding 属性

确定Data Set Ready (DSR)线的状态。Data Set Ready 信号由调制解调器发送到相连计算机,指示作好操作准备。该属性在设计时无效,在运行时为只读。

语法:object.DSRHolding

object 所在处表示对象表达式,其值是“应用于”列表中的对象。

DSRHolding属性返回以下值:

值           描述 
True Data Set Ready   线高 
False Data Set Ready   线低 

说明:当Data Set Ready线为高电平(DSRHolding = True)且超时时,MSComm 控件设置CommEvent属性为comEventDSRTO(数据准备超时)并产生OnComm 事件。

当为Data Terminal Equipment (DTE)机器写Data Set Ready/Data Terminal Ready握手例程时该属性是十分有用的。

数据类型:Boolean

12.Settings 属性

设置并返回波特率、奇偶校验、数据位、停止位参数。

语法object.Settings[ = value]

说明:当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。

Value 由四个设置值组成,有如下的格式:"BBBB,P,D,S"。BBBB为波特率,P为奇偶校验,D为数据位数,S为停止位数。value 的缺省值是:"9600,N,8,1"。

(1)下表列出合法的波特率:

设置值:110、300、600、1200、2400、9600(缺省)、14400、19200、28800、38400、56000、128000、256000

(2)下表说明合法的奇偶校验值:

设置值      描述

E          偶数 (Even)

M          标记 (Mark)

N          缺省 (Default) None

O          奇数 (Odd)

S           空格 (Space)

(3)下表列出合法的数据位值。

设置值:4、5、6、7、8 (缺省)

(4)下表列出合法的停止位值。

设置值:1(缺省)、1.5、2

13.InputLen 属性

设置并返回 Input 属性从接收缓冲区读取的字符数。该属性在设计时无效,在运行时为只读。

语法object.InputLen [ = value]

InputLen 属性语法包括下列部分:

value 整型表达式,说明 Input 属性从接收缓冲区中读取的字符数。 

说明:InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。

InputLen属性确定被Input属性读取的字符数。设置 InputLen 为 0,则 Input 属性读取缓冲区中全部的内容。

InputMode 属性确定用 Input 属性读取的数据类型。如果设置 InputMode 为comInputModeText,Input属性通过一个Variant返回文本数据。如果设置 InputMode为comInputModeBinary,Input 属性通过一个Variant。返回一二进制数据的数组。

若接收缓冲区中 InputLen字符无效,Input属性返回一个零长度字符串 ("")。在使用 Input 前,用户可以选择检查 InBufferCount 属性来确定缓冲区中是否已有需要数目的字符。该属性在从输出格式为定长数据的机器读取数据时非常有用。

数据类型:Variant

14.Output 属性

往传输缓冲区写数据流。该属性在设计时无效,在运行时为只读。

语法

object.Output [ = value]

Output属性语法包括下列部分:

部分    描述
object   对象表达式,其值是“应用于”列表中的对象
value

要写到传输缓冲区中的一个字符串

   

说明

Output 属性可以传输文本数据或二进制数据。用 Output 属性传输文本数据,必须定义一个包含一个字符串的 Variant。发送二进制数据,必须传递一个包含字节数组的 Variant 到 Output 属性。

正常情况下,如果发送一个 ANSI 字符串到应用程序,可以以文本数据的形式发送。如果发送包含嵌入控制字符、Null 字符等等的数据,要以二进制形式发送。

数据类型:Variant

15. EOFEnable 属性

确定在输入过程中 MSComm 控件是否寻找文件结尾 (EOF) 字符。如果找到EOF字符,将停止输入并激活OnComm事件,此时 CommEvent 属性设置为 comEvEOF。

语法:object.EOFEnable [= value]

EOFEnable属性语法包括下列部分:

value 布尔表达式,确定当找到 EOF 字符时,OnComm 事件是否被激活,如“设置值”中所描述。 

value 的设置值:

True    当 EOF 字符找到时 OnComm 事件被激活。 

False(缺省)当EOF 字符找到时OnComm 事件不被激活。 

说明:当 EOFEnable 属性设置为 False,OnComm 控件将不在输入流中寻找 EOF 字符。

16. 错误消息(MS Comm 控件)

下表列出 MSComm 控件可以捕获的错误,我们可以通过错误代码知道具体出错点

描述
380   无效属性值 comInvalidPropertyValue
383  属性为只读 comSetNotSupported
394 属性为只读 comGetNotSupported 
8000 端口打开时操作不合法 comPortOpen
8001 超时值必须大于 0 
8002  无效端口号 comPortInvalid
8003 属性只在运行时有效 
8004 属性在运行时为只读 
8005 端口已经打开 comPortAlreadyOpen
8006  设备标识符无效或不支持该标识符 
8007 不支持设备的波特率 
8008 指定的字节大小无效 
8009 缺省参数错误 
8010 硬件不可用(被其它设备锁定) 
8011 函数不能分配队列 
8012   设备没有打开 comNoOpen 
8013 设备已经打开 
8014 不能使用 comm 通知 
8015 不能设置 comm 状态 comSetCommStateFailed
8016 不能设置 comm 事件屏蔽 
8018 仅当端口打开时操作才有效 comPortNotOpen 
8019  设备忙 
8020  读 comm 设备错误 comReadError
8021   为该端口检索设备控制块时的内部错误 comDCBError 

2.具体实现(附部分代码)

MSComm控件进行串行通信的一般步骤主要就以下几点

(1)设置通信对象、通信端口号及其它属性;

(2)设定通信协议;

(3)打开通信端口,进行数据的传送;

(4)关闭通信端口。

怎么引入控件的具体步骤在这里我就不详细介绍,自己下Visual C++6.0熟悉以下就知道了。下面是我设计的一个程序界面,包含串口数据发送和接收显示以及前期数码管显示的测试程序。

VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

大家可能对这个控件没有具体的概念,简单就上面开始测试的按键来说,打开它的属性如下

VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

 它有一个ID号,这在代码里表现为一个函数的实现

VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

 我们可以发现代码中含有由choosenum为判断条件的判断语句,到这相信大家可以猜到这个是使数码管显示指定数字的实现代码,这些控件都是包含在CDpjDlg类里的。

VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

 这每个值又对应着相应的控件,就说C++这个语言是一个面向对象的编程,这也是它的一个优越性,也是最值得学习的一点。再看那个小按钮的属性界面就应该明白程序界面是怎么和代码相关联的了。但是使用控件之前要在对象里初始化才能用。

VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

 上面就是是简单介绍了一下基本的操作方式,增进以下了解。接下来是比较重要的几段代码,源码我会在课设答辩完成后再放到平台上。

首先是头文件里类的定义

/
// CDpjDlg dialog

class CDpjDlg : public CDialog
{
// Construction
public:
	int Str2Hex(CString str, CByteArray &senddata);
	char HexChar(char c);
	CDpjDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CDpjDlg)
	enum { IDD = IDD_DPJ_DIALOG };
	CEdit	m_ctrlsend;
	CMSComm	m_ctrlComm;
	CString	m_send;
	CString	m_receive;
	CString	m_state;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CDpjDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CDpjDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	virtual void OnOK();
	afx_msg void OnTest();

	afx_msg void OnRadio1();
	afx_msg void OnRadio2();
	afx_msg void OnRadio3();
	afx_msg void OnRadio4();
	afx_msg void OnRadio5();

	afx_msg void OnButton1();
    afx_msg void OnButton2();
	
	afx_msg void OnOnCommMscomm();
	virtual void OnCancel();
	afx_msg void OnSetfocusEdit1();
	afx_msg void OnChangeEdit2();
	DECLARE_EVENTSINK_MAP()
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

实现向串口发送由text控件得到的数据的代码,上面的是从控件得到数据的函数

void CDpjDlg::OnSetfocusEdit1() //Edit1文本框得到焦点
{
	// TODO: Add your control notification handler code here

	m_ctrlsend.SetSel(0,-1);//Edit1文本框中字符全选中
	m_ctrlsend.Clear();     //清除Edit1文本框中的所有字符
}

void CDpjDlg::OnOK() 
{
	// TODO: Add extra validation here
    CByteArray hexdata; 
	UpdateData(TRUE);  //读编辑框内容	
	int len=Str2Hex(m_send,hexdata);
 	UpdateData(FALSE);  //更新编辑框内容
	m_ctrlComm.SetOutput(COleVariant(hexdata));

}

实现接收到的消息的处理程序

/
// 消息处理程序

BOOL CDpjDlg::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_ctrlComm.SetCommPort(1);   //选择的COM口
	m_ctrlComm.SetInputMode(1); //输入方式为二进制方式
	m_ctrlComm.SetInBufferSize(1024); //设置输入缓冲区大小
	m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
    m_ctrlComm.SetSThreshold(1);//参数1表示当传输缓冲区完全空时将引发一个接收数据的OnComm事件
	m_ctrlComm.SetSettings("9600,n,8,1"); //波特率/数据位/停止位
	m_ctrlComm.SetPortOpen(TRUE);//打开串口
    m_send="00";
	UpdateData(FALSE);  //更新编辑框内容

	return TRUE;  // return TRUE  unless you set the focus to a control
}

 主要实现各种状态判断的函数

void CDpjDlg::OnOnCommMscomm() 
{
	// TODO: Add your control notification handler code here
	VARIANT variant_inp;
	COleSafeArray safearray_inp;
	LONG len,k;
	BYTE rxdata[512]; //设置BYTE数组
	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<len;k++)
			safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
		for(k=0;k<len;k++)             //将数组转换为Cstring型变量
		{
			BYTE bt=*(char*)(rxdata+k);    //字符型
			strtemp.Format("%02X",bt);    //将字符送入临时变量strtemp存放
	        m_receive=strtemp;//加入对应字符串m_receive中
		}
  	}
    else
	   m_receive="数据未收到 "; 
	
   if(strtemp=="00")
    {      
		m_state="开始通信!";
	}
	else if(strtemp==m_send)
    {  
      m_state="通信正常!";
    }
	else
	{  
      m_state="通信不正常!";
    }
    if(strtemp=="FF")
    {      
		m_state="通信结束,输入00重新开始!";
	}
   	UpdateData(FALSE);  //更新编辑框内容
}

一个测试单片机的程序,用数码管

void CDpjDlg::OnTest() 
{
    m_receive="";
    //05 57 01 00 00 00 04 57  数码管显示00
    //05 57 01 00 00 01 04 56  数码管显示01
    //05 57 01 00 00 02 04 55  数码管显示02
    //05 57 01 00 00 03 04 54  数码管显示03
    //05 57 01 00 00 04 04 53  数码管显示04
    //05 57 01 00 00 05 04 52  数码管显示05
    //05 57 01 00 00 06 04 51  数码管显示06
    //05 57 01 00 00 07 04 50  数码管显示07
    //05 57 01 00 00 08 04 5F  数码管显示08
    //05 57 01 00 00 09 04 5E  数码管显示09
    //05 57 01 00 00 0A 04 5D  数码管显示10

    //使数码管显示从0-4  
	CByteArray hexdata; 
    //05 57 01 00 00 00 04 57  数码管显示00 
    m_send="05 57 01 00 00 00 04 57";
	int len=Str2Hex(m_send,hexdata);
 	m_ctrlComm.SetOutput(COleVariant(hexdata));
    Sleep(100);//等待100毫秒
	//05 57 01 00 00 01 04 56  数码管显示01
	m_send="05 57 01 00 00 01 04 56";
    len=Str2Hex(m_send,hexdata);
	m_ctrlComm.SetOutput(COleVariant(hexdata));//发送数据
	Sleep(100);//等待100毫秒
	//05 57 01 00 00 02 04 55  数码管显示02
	m_send="05 57 01 00 00 02 04 55";
    len=Str2Hex(m_send,hexdata);
	m_ctrlComm.SetOutput(COleVariant(hexdata));//发送数据
	Sleep(100);//等待100毫秒
    //05 57 01 00 00 03 04 54  数码管显示03
    m_send="05 57 01 00 00 03 04 54";
    len=Str2Hex(m_send,hexdata);
	m_ctrlComm.SetOutput(COleVariant(hexdata));//发送数据
	Sleep(100);//等待100毫秒
	//05 57 01 00 00 04 04 53  数码管显示04
	m_send="05 57 01 00 00 04 04 53";
    len=Str2Hex(m_send,hexdata);
	m_ctrlComm.SetOutput(COleVariant(hexdata));//发送数据
    Sleep(100);//等待100毫秒
    //05 52 01 03 00 01 04 50    读取地址03H中的值
	m_send="05 52 01 03 00 01 04 50 ";
    len=Str2Hex(m_send,hexdata);
	m_ctrlComm.SetOutput(COleVariant(hexdata));//发送数据
}

这个程序发的只是数字1,2,3,4,,但要想单片机端汇编编程简单一点,我实际用的是直接发送使数码管显示相应数字的两位16进制数。其中关于串口数据传输协议我觉得有必要提一下,从上面的代码也可以看到传的数据是一组由八个两位16进制数组成的东西。

这个我也不太懂,简单来说就比如

m_send="05 57 01 00 00 C0 04 97";

//05-协议引导字节,可以说是默认的,基本不用改
//57-表示写,若是52的话表示读
//01-也是固定的东西
//00-数据的位置
//00-固定的
//C0-要传输的数据
//04-固定的
//97-进行一个异或校验,57和数据的位置和要传的数据的二进制异或结果

应该大概率会需要一个转16进制的代码,这个改一下对象应该就能拿去用

//将字符转换十六进制
char CDpjDlg::HexChar(char c)
{
    if((c>='0')&&(c<='9'))
		return c-0x30;
	else if((c>='A')&&(c<='F'))
		return c-'A'+10;
	else if((c>='a')&&(c<='f'))
		return c-'a'+10;
	else 
		return -1;
}

//将字符串转换成十六进制
int CDpjDlg::Str2Hex(CString str, CByteArray &senddata)
{
    int hexdata,lowhexdata;
	int hexdatalen=0;
	int len=str.GetLength();
	senddata.SetSize(len/2);
	for(int i=0;i<len;)
	{
		char lstr,hstr=str[i];
		if(hstr==' ')
		{
			i++;
			continue;
		}
		i++;
		if(i>=len)
			break;
		lstr=str[i];
		hexdata=HexChar(hstr);    //高位转换
		lowhexdata=HexChar(lstr); //低位转换
		if((hexdata==16)||(lowhexdata==16))
			break;
		else 
			hexdata=hexdata*16+lowhexdata;
		i++;
		senddata[hexdatalen]=(char)hexdata;
		hexdatalen++;
	}
	return hexdatalen;
}

最后是关闭串口的函数,是“关闭”按钮控件的实现

void CDpjDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	m_ctrlComm.SetPortOpen(FALSE);//关闭串口
	CDialog::OnCancel();
}

最后,温馨提示,上面的代码只是主要实现框架的代码,实际实现远不止于此。文章来源地址https://www.toymoban.com/news/detail-453006.html

到了这里,关于VC++6.0上实现PC机与单片机串口通信的PC端上位机软件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机-串口通信

    目录 1.什么是通信 1.1.通信的概念 1.2.传送方式 1.3.同步方式 1.4.传送方向 1.5.校验方式 2.单片机串口介绍 2.1.硬件电路 2.2.电平标准 2.3.常见接口 2.4.内部结构 2.5.相关寄存器 2.6.工作模式(模式1) 2.7.如何配置串口中断 3.实际应用 3.1.单片机向电脑发送数据 3.2.电脑向单片机发送

    2024年02月01日
    浏览(50)
  • 单片机串口通信程序

    本文总结了两种比较简单的关于串口发送接收的程序,以下是步骤: 定义数据: 首先要串口初始化:(以9600波特率为例) 串口中断:  在定时器0扫描里加入,或者主函数while(1)里加入: (其中++URX_tt=(1000/波特率),数要接近,否则会有小小干扰。) 接下来关于串口通信

    2024年02月10日
    浏览(49)
  • 单片机的串口通信

            今天,完整地总结一下普中科技的单片机的串口通信的硬件与编程,记录一下以后如果需要也比较方便捡起来。         单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。         对这

    2024年02月11日
    浏览(45)
  • 51单片机串口通信

    串口通信(serial communication)是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式,属于串行通信方式。 接口标准:常用RS-232和RS-485 RS-232C有一种9针的非标准连接器口,简称DB9。串口通信使用的大多都是DB9接口。在串口通信中,通常我们只使用2、

    2024年02月05日
    浏览(49)
  • 【51单片机系列】proteus仿真单片机的串口通信

    本文参考:https://zhuanlan.zhihu.com/p/425809292。 在proteus之外使用串口软件和单片机通信。通过在proteus设计一个单片机接收PC发送的数据,并将接收的数据发送出去,利用软件【Configure Virtual Serial Port Driver】创建一对虚拟串口,利用软件【串口助手】向单片机发送数据。 proteus仿真

    2024年01月17日
    浏览(53)
  • 【51单片机】串口通信&&使用串口通信控制LED灯

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Promise】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔串口通信 😎代码   🍔串口初始化 ⭐分析  🏳️‍🌈确定T1的工作方式 🎈TMOD=0X20;  🏳️‍🌈确定T1的初值 🎈

    2024年02月17日
    浏览(49)
  • c51单片机串口通信(中断方式接收数据)(单片机--单片机通信)示例代码 附proteus图

         单片机一般采用中断方式接受数据,这样便于及时处理 其中发送数据段采用的是查询方式,接收端采用了中断方式, 要注意的地方有: 在中断处理函数int_0()内,处理数据前要先关闭中断,否则中断可能会不断传过来, EA=0; 然后退出中断处理函数前恢复中断处理能力:

    2024年02月13日
    浏览(65)
  • 51单片机学习--串口通信

    首先需要配置寄存器: 下面这里SCON配0x40和0x50都可以,因为暂时还不需要接受信息,所以REN置1置0都可 在main中调用SendByte函数,每按下一次复位键,接收缓冲区就会收到一个11 这就是单向发送的一个简单实例,接下来实现每隔一秒发送一个递增的数据,只需要添加一个全局变

    2024年02月14日
    浏览(50)
  • 51单片机 | 串口通信实验

      这一节我们就来学习 51 单片机的串口通信。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。本节要实现的功能是: 51 单片机通过串口( UART )实现与 PC 机对话, 51 单片机的串口收到 PC 机发来的数据后原封不动的返回给

    2024年02月04日
    浏览(64)
  • 51单片机(八)串口通信

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月05日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包