用VC++6.0实现PC机与单片机之间的数据交换


程序示例

串口初始化

if (!m_comm.GetPortOpen())m_comm.SetPortOpen(TURE); /*打开串口*/

m_comm.SetSettings("4800,n,8,1"); /*串口参数设置*/
m_comm.SetInputMode(0); /*设置TEXT缓冲区输入方式*/
m_comm.SetRthresHold(1); /*每接收一个字符则激发OnComm()事件*/

接收数据

m_comm.SetInputLen(1); /*每次读取一个字符
VARINAT V1=m_comm.GetInput();

/*读入字符*/

m_V1=V1.bstrval;

发送字符
m_comm.SetOutput(Colevariant ("Hello"); /*发送 “Hello” */

3.3 注意

  SetOutput方法可以传输文本数据或二进制数据。用SetOutput方法传输文本数据,必须定义一个包含一个字符串的Variant。
发送二进制数据,必须传递一个包含字节数组的Variant 到 Output 属性。正常情况下,如果发送一个 ANSI 字符串到应用程序,
可以以文本数据的形式发送。如果发送包含嵌入控制字符、Null 字符等的数据,要以二进制形式发送。此处望引起读者注意,笔
者曾经在此犯错。

4 VC++类CSerial

4.1 串行通信类CSerial简介

Cserial 是由MuMega Technologies公司提供的一个免费的VC++类,可方便地实现串行通信。以下为该类定义的说明部分。

class CSerial
{
public:
CSerial();
~CSerial();
BOOL Open( int nPort = 2, int nBaud = 9600 );
BOOL Close( void );
int ReadData( void *, int );
int SendData( const char *, int );
int ReadDataWaiting( void );
BOOL IsOpened( void ){ return( m_bOpened ); }
protected:
BOOL WriteCommByte( unsigned char );
HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
BOOL m_bOpened;

}


4.2 串行通信类Cserial 成员函数简介

1. CSerial::Cserial是类构造函数,不带参数,负责初始化所有类成员变量。

2. CSerial:: Open这个成员函数打开通信端口。带两个参数,第一个是埠号,有效值是1到4,第二个参数是波特率,返回一个布
尔量。

3. CSerial:: Close函数关闭通信端口。类析构函数调用这个函数,所以可不用显式调用这个函数。

4. CSerial:: SendData函数把数据从一个缓冲区写到串行端口。它所带的第一个参数是缓冲区指针,其中包含要被发送的资料;
这个函数返回已写到端口的实际字节数。

5. CSerial:: ReadDataWaiting函数返回等待在通信端口缓冲区中的数据,不带参数。 6. CSerial:: ReadData函数从端口接收缓冲区读入数据。第一个参数是void*缓冲区指针,资料将被放入该缓冲区;第二个参
数是个整数值,给出缓冲区的大小。

4.3 应用VC类的一个实例

1. 固定式EBM气溶胶灭火系统简介

  固定式EBM气溶胶灭火装置分区启动器是专为EBM灭火装置设计的自动控制设备。可与两线制感温、感烟探测器配套使用,当监
测部位发生火情时,探测器发出电信号给分区启动器,经逻辑判断后发出声、光报警,延时后自动启动EBM灭火装置。为了便于火灾
事故的事后分析,需对重要的火警事件和关键性操作进行记录,记录应能从PC机读出来;PC机能控制、协调整个系统的工作,这些
都涉及通信。本例中启动器采用RS-485通信接口,系统为主从式网络,PC机为上位机。具体的通信协议为:
(1)下位机定时向上传送记录的事件;
(2)应答发送,即PC机要得到最新事件记录,而传送时间未到时,PC机发送命令,下位机接收命令后,把最新记录传给上位机;
(3)上位机发送其它命令如校时、启动、停止、手/自动等。

2. 通信程序设计

部分上位机程序

(1)发送命令字程序,代码如下

void CCommDlg::OnSend()
{

CSerial Serial;

//构造串口类,初始化串行口

if (Serial.Open(2,9600)) //if-1

//打开串行口2,波特率为9600bps
{
static char szMessage[]="0";

//命令码(可定义各种命令码)
int nBytesSent;
int count=0;
resend:

nBytesSent=Serial.SendData(szMessage,strlen(szMessage));

//发送命令码
char rdMessage [20];
if (Serial.ReadDataWaiting()) //if-2
{
Serial.ReadData(rdMessage,88);
//rdMessage 定义接收字节存储区,为全局变量//

if ((rdMessage[0]!=0x7f)&&(count<3))
{
count++;
goto resend
}

if(count>=3)
MessageBox(“发送命令字失败”);
}

else //if-2
MessageBox("接收数据错误");

}
else //if-1
MessageBox("串行口打开失败");
}

下位机通信程序:

#include<reg51.h>
#include<stdlib.h>
#include<stdio.h>

#define count 9
#define com_code 0x00
#define com_code1 0xff

unsigned char buffer[count];
int po,year,month,date,hour;
int minute,second,recordID ;
int sum;

main()
{

/*初始化串口和定时器*/

TMOD=0×20;
TH1=0×fd;
TR1=0×01;
ET1=0×00;
ES=1;
EA=1;

/*待发送数据送缓冲区*/

buffer[0] = 0×ff; //数据特征码
buffer[1] = count+1; //数据长度
buffer[2] = year; //年
buffer[3] = month; //月
buffer[4] = date; //日
buffer[5] = hour; //时
buffer[6] = minute; //分
buffer[7] = second; //秒
buffer[8] = recordID; //事件号

for(po=0;po<count;po++)
sum+=buffer[po];

buffer[9]=sum; //校验和

}

/*发送中断服务程序*/

void send(void) interrupt 4 using 1
{
int i;

RI=0;
EA=0;
do
{
for(i=0;i<=count;i++)
{
SBUF=buffer[i]; //发送数据和校验和//
while(TI==0);
TI=0;
}
while(RI==0);
RI=0;
} while(SBUF!=0); //主机接收不正确,重新发送//

EA=1;

Return;
}

5 应用总结

  根据不同需要,选择合适的方法。我们选用的用VC++类实现的上位机和下位机的串行通信方法具有使用简单、编写程序方便的
特点。经过半年多应用于EBM灭火系统的情况来看,该方法实现的系统运行稳定可靠,是一种值得推广的简单易行的通信方法。

COPYRIGHT(C) 2011 厦门永宏亚得机电科技有限公司版权所有(闽ICP备05025945号) ALL RIGHTS RESERVED?

电话: 0592-5190891 传真: 0592-5190720 E-Mail: E-mail:yade8895@163.com
地址: 厦门市海沧区兴港六里17号2607室 邮编:361009 联系人:翟先生