VC利用串口完成上下位机的通讯

 

这里我的流程是,下位机首先向上位机发送请求(比如发送字母‘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程序

 

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值