这里我的流程是,下位机首先向上位机发送请求(比如发送字母‘A’),上位机接收到请求,读取电脑里某个路径里面的文件(如txt),然后利用串口将文件发送到下位机,下位机接收文件,当接收完毕再次向上位机发送请求,像这样一直循环往复
上位机用的是vc++6.0,关于串口控件添加的问题,这里我简要讲一下,网上很多人反映像一些教程里面说的添加控件的方法:Project------Add To Project-----Component and Controls这样发现里面的文件夹是空的,或者是用了右键insert ActiveX Control 之后不知道怎么做了。
首先第一种问题,我不知道原因,所以我是用的是第二种方法,也就是右键insert ActiveX Control,在这之后,打开class wizard,然后双击刚才添加的控件的ID,来为他在某个类(如果是单文档的话就是对话框的类)添加一个成员变量就可以了,如下图
好了关于串口的问题就讲到这里,然后是代码,首先是读文件代码:
void CComHandle::loadfile (const string path,char* buf)
{
CCparameter parameter;
//char s[30]={ 0x00 };
static long pfile=0;
FILE* fp=fopen(path.c_str(),"r+b");
fseek(fp,pfile,0);//保存上次的文件指针,利用static变量
//读文件可以利用fget读1行
/* fgets(s,30,fp);
//也可以利用fscanf来格式化的读取
/* fscanf(fp,"%s",&s);
if((s[1]=='8')&&(s[2]=='0'))
;
else if()
else if
{
s[0]='0';
parameter.motor=atoi(s);
fscanf(fp,"%d",¶meter.direction);
fscanf(fp,"%d",¶meter.speed );
fscanf(fp,"%d",¶meter.step );
fscanf(fp,"%s",&s);
}*/
fgets(parameter.sendstring,30,fp);
strcpy(buf,parameter.sendstring);
pfile=ftell(fp);//保存文件指针
fclose(fp);
}
parameter是我自己创建的类,里面的sendstring是char型数组的成员变量,这里利用了静态变量来保存指针,每次读取数据的时候都从上次的位置继续读取数据。
接下来是串口的初始化函数:
//串口初始化
if(m_mscomm.GetPortOpen()) //如果打开了串口
m_mscomm.SetPortOpen(FALSE); //不需要打开串口
m_mscomm.SetCommPort(5); //选择com ,设置串行端口号
if( !m_mscomm.GetPortOpen()) //如果没有打开串口
{
m_mscomm.SetPortOpen(TRUE);//打开串口
AfxMessageBox(" open serial port successfully");
}
else
AfxMessageBox("cannot open serial port");
m_mscomm.SetSettings("115200,n,8,1"); //波特率115200,无校验,8个数据位,1个停止位
m_mscomm.SetInputMode(1); //1:表示以二进制方式检取数据
m_mscomm.SetRThreshold(2); //参数1表示每当串口接收缓冲区中有多于或等于2个字符时将引发一个接收数据的OnComm事件
m_mscomm.SetInputLen(0); //设置当前接收区数据长度为0,为了清除数据?
m_mscomm.GetInput();//先预读缓冲区以清除残留数据
然后就是串口接收和发送部分:
CComHandle ccomhandle;//创建对象
VARIANT variant_inp;
COleSafeArray safearray_inp;
CByteArray arr_output;
COleVariant var_output;
CString m_send = "ok";
arr_output.SetSize(30);//设置大小
LONG len,k;
m_mscomm.SetInputLen(2);
BYTE rxdata[2048];
CString strtemp;
if(m_mscomm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp=m_mscomm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组 ,因为上面我设置了一次读取2个字节,所以每次k最大为2
m_strRXData = "";
for(k=1;k<len;k++) //将数组转换为Cstring型变量 ,
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_strRXData+=strtemp;//加入接收编辑框对应字符串
}
if(rxdata[0]=='A')//收到下位机发送请求
{
//下面的函数里面填写你需要读取的文件的绝对路径
ccomhandle.loadfile("C:/Users/Moe/Desktop/CtrlFile_3_1.txt",(char *)buf);//将读取到的字符串送入buf
int count=strlen(buf);
count++;
//在读取得最后加上/r/n
for(int i=0;i<count;i++)
{
if(buf[i]=='\n')
arr_output.SetAt(i,'\r');
arr_output.SetAt(i,buf[i]);
}
m_mscomm.SetOutput(COleVariant(arr_output));//通过串口发送
}
}
当上位机接收到下位机发送的A的时候,就立即读取txt文件,然后利用串口将文件发送出去,这里需要注意的是SetOutPut的参数有要求只能是Variant类型的,这里利用了
COleVariant经行了数据转换。
最后贴上源码的下载地址:vc程序