TA的每日心情 | 开心 2020-7-25 10:37 |
---|
签到天数: 40 天 连续签到: 1 天 [LV.5]常住居民I
|
SD 存储卡是一种基于半导体快闪记忆器的记忆设备。它具有体积小、传输速度快、支持热插拔等优点,在便携式装置领域得到了广泛的应用,如手机、多媒体播放器等。这一次我们对开发板上的SD开进行读写。
ZYNQ 中的 SD 卡控制器符合 SD2.0 协议规范,接口兼容 eMMC、MMC3.31、SDIO2.0、SD2.0、SPI,支持 SDHC、SDHS 器件。SD 卡控制器支持 SDMA(单操作 DMA)、ADMA1(4K 边界限制 DMA)和ADMA2(在 32 位系统中允许任何位置和任意大小)。ARM 处理器通过 AHB 总线访问 SD 卡控制器,SD控制器采用读和写通道各自双缓冲 FIFO 的机制提高吞吐带宽。其内部框图如下图所示:
SD 控制器读写通道采用独立的 512 字节深度的双缓冲 FIFO 执行读和写操作。在写操作时,处理器向其中一个 FIFO 写数据,将另一个 FIFO 的数据写到 SD 总线;在读操作时,SD 总线上的数据向其中一个FIFO 写数据,处理器将数据从另一个 FIFO 读出数据。SD 卡控制器通过双缓冲机制以保证最大带宽。
SD开的操作一般离不开文件系统,便于对文件的管理等操作,Xilinx SDK standalone 已经移植好了 FATFS 文件系统,因此在 SDK 中添加 xilffs 库后,就可以在程序中使用 FATFS 中的 API 函数来操作 SD 卡。关于 FATFS 源码以及 API 函数的介绍,大家可以在:http://elm-chan.org/fsw/ff/00index_e.html 这个网站上查看。
基本概念差不多就这些,下面开始我们的实验,这一次我们依然使用之前的Helloworld作为工程模板来建立工程。在ZYNQ IP和中定制SD卡相关接口如下图:
重新生成IP,编译工程后生成bit文件。
建立SDK工程,依然是建立helloworld工程模板,对工程做如下设置,以支持文件系统:
编写软件代码:
- #include "xparameters.h"
- #include "xil_printf.h"
- #include "ff.h"
- #include "xdevcfg.h"
- #define FILE_NAME "xiaohei.txt" //定义文件名
- const char src_str[30] = "米尔电子 电路城"; //定义文本内容
- static FATFS fatfs; //文件系统
- //初始化文件系统
- int platform_init_fs()
- {
- FRESULT status;
- TCHAR *Path = "0:/";
- BYTE work[_MAX_SS];
- //注册一个工作区(挂载分区文件系统)
- //在使用任何其它文件函数之前,必须使用f_mount函数为每个使用卷注册一个工作区
- status = f_mount(&fatfs, Path, 1); //挂载SD卡
- if (status != FR_OK) {
- xil_printf("Volume is not FAT formated; formating FAT\r\n");
- //格式化SD卡
- //status = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
- status = f_mkfs(Path, 0, sizeof work);
- //FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
- 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;
- }
- //main函数
- int main()
- {
- int status,len;
- char dest_str[30] = "";
- 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");
- len = strlen(src_str); //计算字符串长度
- //SD卡写数据
- sd_write_data(FILE_NAME,(u32)src_str,len);
- //SD卡读数据
- sd_read_data(FILE_NAME,(u32)dest_str,len);
- //比较写入的字符串和读出的字符串是否相等
- if (strcmp(src_str, dest_str) == 0)
- xil_printf("src_str is equal to dest_str,SD card test success!\n");
- else
- xil_printf("src_str is not equal to dest_str,SD card test failed!\n");
- return 0;
- }
实现现象:
附上我的工程:
MYiR_SD.zip
(4.58 MB, 下载次数: 5)
|
|