赞
踩
本章节记录Xilinx ZYNQ PS端实现SD卡txt文件的数据读取。
踩坑记录,本章节主要内容参考原子哥
板子:xilinx zynq 7010
xilinx zynq 7010使用的sd卡的引脚,通过手册可知,
SD引脚为MIO40-45,card detect MIO47,
所以采用SD 0,如下图:
注意:直接跑原子哥的工程代码是行不通的,因为原子哥是7020板子,自己的是7010
导入xilffs库,因为需要使用FATFS文件系统
如果代码无法识别到f_mount()函数,则需要的手动添加xilffs库,
如下图:
但我导入了这个之后,虽然可以识别到f_mount(),但无法使用ff.h中的f_gets()(已经include “ff.h”),不知道为什么,
如果有解决方法的,非常希望大家能够评论区给出。
在copy原子哥代码时,需要注意xilffs的版本,版本不同函数有所改动,形参调用也不同。我的是xilinx zynq 7010,xilffs是3.7,原子哥是xilinx zynq 7020,xilffs是4.0.
//原子哥xilffs4.0代码:
status = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
//我xilffs3.7代码:
status = f_mkfs(Path, 1,sizeof work);
同时需要注意,因为使用的是SD 0 ,所以f_mount()函数需要选择挂载0口
status = f_mount(&fatfs, Path, 0); //挂载SD卡
同时注意,读取代码中的buffer[100]是用来获取一次100个数据的,temp_out_buffer[100]用于存储每一行的数据,用于输出或者处理,这样子分开两个数组进行分别操作,可以防止只使用一个数组出现数据覆盖的现象。
(因为txt每行的数据最多只有20个,所以buffer和temp_out_buffer数组定义只需要定义20个也是行得通的,但没试过,反正内存够)
每一行的数据获取结束标志位十分重要,这段代码不能丢!!!
temp_out_buffer[buffer_index] = '\0'; // 结束符号标志!重要!!
#include "xparameters.h" #include "xil_printf.h" #include "ff.h" #include "xdevcfg.h" #include "stdio.h" #define FILE_NAME "data.txt" //定义文件名 const char src_str[30] = "www.openedv.com"; //定义文本内容 static FATFS fatfs; //文件系统 //初始化文件系统 int platform_init_fs() { FRESULT status; TCHAR *Path = "0:/"; BYTE work[512]; //注册一个工作区(挂载分区文件系统) //在使用任何其它文件函数之前,必须使用f_mount函数为每个使用卷注册一个工作区 status = f_mount(&fatfs, Path, 0); //挂载SD卡 if (status != FR_OK) { xil_printf("Volume is not FAT formated; formating FAT\r\n"); //格式化SD卡 status = f_mkfs(Path, 1,sizeof work); if (status != FR_OK) { xil_printf("Unable to format FATfs\r\n"); return -1; } //格式化之后,重新挂载SD卡 status = f_mount(&fatfs, Path, 1); if (status != FR_OK) { xil_printf("Unable to mount FATfs\r\n"); return -1; } } return 0; } //挂载SD(TF)卡 int sd_mount() { FRESULT status; //初始化文件系统(挂载SD卡,如果挂载不成功,则格式化SD卡) status = platform_init_fs(); if(status){ xil_printf("ERROR: f_mount returned %d!\n",status); return XST_FAILURE; } return XST_SUCCESS; } //SD卡写数据 int sd_write_data(char *file_name,u32 src_addr,u32 byte_len) { FIL fil; //文件对象 UINT bw; //f_write函数返回已写入的字节数 //打开一个文件,如果不存在,则创建一个文件 f_open(&fil,file_name,FA_CREATE_ALWAYS | FA_WRITE); //移动打开的文件对象的文件读/写指针 0:指向文件开头 f_lseek(&fil, 0); //向文件中写入数据 f_write(&fil,(void*) src_addr,byte_len,&bw); //关闭文件 f_close(&fil); return 0; } //SD卡读数据 int sd_read_data(char *file_name,u32 src_addr,u32 byte_len) { FIL fil; //文件对象 UINT br; //f_read函数返回已读出的字节数 //打开一个只读的文件 f_open(&fil,file_name,FA_READ); //移动打开的文件对象的文件读/写指针 0:指向文件开头 f_lseek(&fil,0); //从SD卡中读出数据 f_read(&fil,(void*)src_addr,byte_len,&br); //关闭文件 f_close(&fil); return 0; } // 定义结构体存储X和Y的数值 typedef struct { int x; int y; } DataPoint; int parse_line(char *line, int *x, int *y) { return sscanf(line, "X: %d, Y: %d", x, y); } //main函数 int main() { int status,len; char line[100]; // 适当的缓冲区大小以逐行读取数据 status = sd_mount(); //挂载SD卡 if(status != XST_SUCCESS){ xil_printf("Failed to open SD card!\n"); return 0; } else xil_printf("Success to open SD card!\n\n"); //SD卡读数据 FIL fil; // 文件对象 TCHAR buffer[100]; // 适当的缓冲区大小以读取数据 TCHAR temp_out_buffer[100]={0};//用于临时存储一行数据并输出,会被下一行数据覆盖 UINT bytesRead; int buffer_index = 0; if (f_open(&fil, FILE_NAME, FA_READ) == FR_OK) { while (f_read(&fil, buffer, sizeof(buffer), &bytesRead) == FR_OK && bytesRead > 0) { for (int i = 0; i < bytesRead; i++) { // printf("buffer[%d] = %c\n",i,buffer[i]); if (buffer[i] == '\n' || buffer[i] == '\r') { temp_out_buffer[buffer_index] = '\0'; // 结束符号标志!重要!! buffer_index = 0; DataPoint dataPoint; if (parse_line(temp_out_buffer, &dataPoint.x, &dataPoint.y) == 2) { xil_printf("X: %d, Y: %d\r\n", dataPoint.x, dataPoint.y); } else { // xil_printf("Error parsing line: %s\n", buffer); } } else { temp_out_buffer[buffer_index++] = buffer[i]; } } } f_close(&fil); } else { printf("open file failed \n"); } return 0; }
本章节对于FPGA PS 端SD卡文件数据读取处理进行了记录,主要还是防坑记录,毕竟自己也是找了不少资料才完成。
还有一些待完善内容,包括:文件读取数据存DDR,从DDR读出来处理后再存回DDR,然后再把处理好的数据传给PL端进行操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。