首先要理清楚二进制文件和文本文件的区别。
大家都知道计算机的存储在物理上是二进制的,所以文本文件与二进制文件的区别并不是物理上的,而是逻辑上的。这两者只是在编码层次上有差异。
简单来说:
文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等。
二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码)。
从上面可以看出文本文件基本上是定长编码的,基于字符嘛,每个字符在具体编码中是固定的,ASCII码是8个比特的编码,UNICODE一般占16个比特。
而二进制文件可看成是变长编码的,因为是值编码嘛,多少个比特代表一个值,完全由你决定。
慢慢理解吧,对数据操作过才能理解好。
如果在新建的txt文件里手动打上“10 20 30”,在Nios II烧写界面中选中 Program a file into flash memory,如下图所示。
选择要烧写的txt文件,选择好要烧写的器件,是flash呢,还是EPCS呢。我做的实验是在EPCS上的,没有flash。我觉得flash上应该也可以。最后是指定好偏移量,避免数据烧写覆盖掉代码。
那么在软件中测试读到的数据又是什么呢?是不是我们需要的10 20 30呢?答案是否定的,读到的数据是49 48 32 50 48 32 51 48。读到的这些数据和我们先前写进去的数据有什么关系呢?其实在烧写的时候,是按照字符来烧写的,字符“1”对应的ASCII值是49,其余依次类推。这样,我们并没有把想要存的数值存进去。主要是数据格式的问题。
那么如何正确的烧进去呢?首先要将这些数值按照二进制存起来,我的做法是用C语言中的文件操作转化一下。(不知道还有没有其他简单的做法,欢迎讨论。)具体代码如下
1 #include<stdio.h> 2 #define SIZE 2
3 char a[SIZE]={0};
4 struct data{
5 int num;
6 }da[SIZE];
7
8 void save()
9 {
10 FILE *fp;
11 int i;
12 /*
13 fp=fopen("data.txt","rb");
14 for(i = 0;i<SIZE;i++)
15 {
16 fread(&da[i],sizeof(struct data),1,fp);
17 printf("%4d ",da[i].num);
18 }
19 */
20 if((fp = fopen("data.txt","wb")) == NULL)
21 {
22 printf("cannot open file\n");
23 return;
24 }
25 for(i = 0;i<SIZE;i++)
26 if(fwrite(&da[i],sizeof(struct data),1,fp) != 1 )
27 //if(fwrite(&a[i],1,1,fp) != 1 )
28
29 fclose(fp);
30
31 }
32 void main()
33 {
34 int i;
35 for(i = 0;i< SIZE;i++)
36 scanf("%d",&da[i].num);
37 //scanf("%c",&a[i]);
38 save();
39
40 }
代码说明:
第35,36行:输入数值,存在变量中;
第20行~第29行:以2进制方式打开文件,然后将变量中的数值写入txt中。最主要的是第20行,“wb”表示为输出打开一个二进制文件。还有其他的文件使用方式,自己可查询一下。
运行程序,我们输入10 20 30后回车。运行好程序之后,查看软件工程中的data.txt文件,发现其中是乱码,不要慌张,这说明上面的代码起作用了,我们可以以二进制方式读出来看一下,是不是我们先前所输入进去的数。将第20行~第29行,第35,36行的代码注销,打开第12行~第19行的代码,运行,我们就能看到所需要的数值了。如下图。
好了,下面我们就测试下将该data.txt文件烧写进FPGA的情况吧。
在Nios II 代码中对flash(EPCS)进行读操作,将存着的数值提取出来,并且赋值给int型数据,这样代码中就能使用外部传进来的数值啦。对flash的操作,这里就不详细贴出代码了。有需要的朋友可以一起讨论。