基于MFC的USB上位机开发(3)数据传输模块

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/snaking616/article/details/84930182

延伸阅读:

基于MFC的USB上位机开发(1)概述

基于MFC的USB上位机开发(2)速度测试模块

基于MFC的USB上位机开发(3)数据传输模块

基于MFC的USB上位机开发(4)环路模块

基于MFC的USB上位机开发(5)下环路模块

目录

1. 设计思路

1.1 发送数据

1.2 接收数据

1.3 清空管道

2. MFC控件相关操作

2.1 Edit Control控件数值操作

2.2 使用时间命名

2.3 数据保存

2.4 长数组进行分行显示

2.5 打开文件夹

3. 功能测试

3.1 传输512字节固定数值数据

3.2 传输512字节递增数据

3.3 传输混合固定数值数据

3.4 清空管道

3.5 打开数据记录

4. 参考


    本模块用于FPGA环路程序的调试,在上位机窗口上包括两个区域:数据控制区域和数据显示区域。当FPGA需要读取USB的数据时,上位机可向USB端发送指定数目和数值或者512字节递增的数据,当FPGA往USB写好数据时,上位机也可以手动接收来至USB的512字节数据。上位机接收的数据不仅可以显示在窗口上,还可以保存至电脑本地文件中。在FPGA环路调试中,如果USB的FIFO管道内出现了非512字节整数倍的无效数据,可使用清空管道命令来完成USB管道的清空,本模块的界面效果如下:

1. 设计思路

1.1 发送数据

        由于FPGA与USB之间的数据线位数为16bit,为单字节(8bit)的偶数倍,所以发送数据的数量必须为偶数,其大小范围是0~512。

        待发送的数据可以按指定数目和数值的方式进行发生,只要累积发送512字节,上位机端就可以收到512字节数据。待发送的数据也可以是512字节递增数据,数据包含2个从0x 00递增至0x FF的256字节数据。

        发送模块的程序流程图如下,在上位机的Public区定义了变量Increment_req,用于判断是否发送递增数据的请求。当按下“发送指定数据”按钮时,上位机会向USB发送指定数目和大小的数据。如果按下“发送512字节递增数据”按钮,公共变量Increment_req会赋值true,上位机会向USB发送512字节递增数据,在该次线程结束时Increment_req会赋值false。

1.2 接收数据

    接收模块的程序流程图如下,当接收按钮按下上位机立马创建接收512字节数据的线程,如果接收成功就将数据进行显示和保存,如果接收失败就提醒先向FPGA发送数据,与此同时将该按钮禁用。512字节数据的显示是本环节的设计难点,涉及到数组转换为字符串和字符串多行显示的知识点,详细介绍请阅读第2.4 节长数组进行分行显示。

1.3 清空管道

在进行FPGA环路代码调试之前,是不清楚USB的端点EP6内有多少字节数据未读出,EP6的深度为2KByte,那么USB管道内的无效数据数量NUM会介于0~2KByte之间。

(1)当NUM=2KByte时,上位机通过接收4次512字节数据即可完成管道清空;

(2)当NUM<512Byte时,上位机需要通过判断NUM的具体数字,来清空管道;

(3)当NUM介于512B和2KB之间时,需要进行1~3次512字节数据接收再加一次无效数据字节数的判断,即可完成管道的清空。

清空管道的程序流程如下:

2. MFC控件相关操作

2.1 Edit Control控件数值操作

将上位机文本框数值赋给内部变量:UpdateData(true);

将内部变量值更新到上位机文本框内:UpdateData(false);

2.2 使用时间命名

有关C++时间结构体CTime的知识可以阅读参考文章[1]和[2],下列代码中Y、m、d、H、M和S,依次表示年、月、日、时、分和秒,str字符串交代了文件的保存路径是“C:\USB_file_recevie”,保存的文件名形式是file_20181219213250.hex。

CTime t=CTime::GetCurrentTime();
str=t.Format(_T("C:\\USB_file_recevie\\file_%Y%m%d%H%M%S.hex"));

2.3 数据保存

    有关C++文件操作的知识可以阅读参考文章[3],本上位机仅用到文件的打开、清空、写入和关闭等操作,具体代码如下:

mFile.Open(str,CFile::modeWrite|CFile::modeCreate);         //打开文件
mFile.SetLength(0);                                    //清空文件
mFile.SeekToEnd();
mFile.Write(data,nLen);	                //向文件内写入512字节数据
mFile.Flush();                         //强制将缓冲区数据写入磁盘文件						
mFile.Close();                         //关闭文件

2.4 长数组进行分行显示

为了方便观察接收到的512字节数据,需要将数据进行分行显示。上位机将数据按字节分成32行16列,具体的实现方法如下方所示:

void CUSBprojDlg::Matrix_to_String(UCHAR * data_512)
{
	int i=0;
	int j=0;
	int line=1;	
	CString str=_T("line00:  ");
	CString tmp_str=_T("");
	for(i=0;i<512;i++)
	{
		tmp_str.Format(_T("%02X "),data_512[i]);	
		str+=tmp_str;
		if((j!=0)&&(j!=511)&&((j+1)%16==0)) 
		{
			str+=_T(" \r\n");
			tmp_str.Format(_T("line%02d:  "),line);
			str+=tmp_str;
			line++;
		}
		j++;
	}
	data_display +=str;
	data_display +=_T(" \r\n");
}

    代码的设计思路是,将512字节数组data_512分成32段,在每段的开头添加line n:,n从0增至31。每个字节的后面带两个空格,每16个字节的后面添加换行符“ \r\n”。有关数组转换为字符串的知识可以阅读参考文章[4]和[5]。

2.5 打开文件夹

void CUSBprojDlg::OnBnClickedOPEN_FOLDER()
{	
    ShellExecute(NULL, _T("open"), _T("C:\\USB_file_recevie"), NULL, NULL, SW_SHOWNORMAL);
}

3. 功能测试

3.1 传输512字节固定数值数据

先向USB发送512字节0x FF

再向USB接收512字节数据

3.2 传输512字节递增数据

先向USB发送512字节递增数据

再向USB接收512字节数据

3.3 传输混合固定数值数据

先向USB发送510字节0x 00和2字节0x FF

再向USB接收512字节数据

3.4 清空管道

        首先,模拟USB管道有无效数据的情况:向USB发送10字节0x 00。

        接着,向USB发送512字节0x 01,再接收512字节数据

        由于USB的管道内有10字节无效的数据0x 00,导致接收的512字节数据的前10字节发生了改变,如何解决以上现象呢,有以下两种方法:

方法1:让USB开发板重新上电,在电路启动时USB的FIFO会自动清空。

方法2:使用上位机的清空管道按钮,通过软件的方式实现USB的FIFO清空。

        现对方法2进行验证,先点击管道清空按钮,接着再向USB发送512字节0x 02,最后接收512字节数据。

        从上方数据可以发现USB管道内的10字节0x 01已通过上位机软件清空,所以接收的数据在数值上与上次发送的数据保持一致。

3.5 打开数据记录

        点击“打开数据记录”按钮,即可弹出数据的保持目录,打开的目录路径为“C:\USB_file_recevie”,和预设的路径是一致的。每接收512字节数据都会保存在以时刻命名的hex文件中,hex文件可以使用UltraEdit软件查看。

4. 参考

[1] MFC中获取系统当前时间GetCurrentTime用法 
https://blog.csdn.net/naibozhuan3744/article/details/78773780

[2] VC中CTime怎么转换成字符串?

https://bbs.csdn.net/topics/60232871

[3] VC++文件操作之最全篇(总结一下希望对大家有用) 

https://blog.csdn.net/u010258235/article/details/24477429

[4] MFC怎么让编辑框多行显示文本内容

https://bbs.csdn.net/topics/390936461

[5] MFC在编辑框中显示一个二维数组 

https://blog.csdn.net/shufac/article/details/20497225

 

猜你喜欢

转载自blog.csdn.net/snaking616/article/details/84930182