【原创】从SD卡读取bin图片文件并用VGA显示(FAT32文件系统)(quartus11.0)(DE0)
2011-08-18 20:10
726 查看
这几天搞定了SD卡之后,又接着看文件系统。说实话想短时间内把整个FAT32的文件系统都搞定,而且很稳定很健壮,是不太容易的。有现成的ZnFAT可以移植,振南兄可是花了不少心思在上面。我这里没有移植他的文件系统,而是自己写了个很简单的只能读取文件的“所谓文件系统”,至于创建文件,比读取麻烦多了,还是让PC机来做吧,而且如果FPGA不做CMOS摄像头数据采集的话,也没必要往SD卡里写图片数据,一般创建个txt记录采集数据还是可以的,所以我只做了读取的部分,完全与FAT32兼容。
网上能搜到的关于数码相框的资料,大多是基于液晶屏显示的,我手里没有现成的液晶屏,VGA倒是有两个。大家选择液晶屏而不选VGA的原因,我后来才知道。因为VGA显示需要的显存比较大,一般至少2M,这么大的显存是要银子的。DE2上是有2M的sram的,而DE0上除了SDRAM和FLASH之外什么都没有。这板子穷啊,资源少,没有办法,只能把图片的尺寸和大小减小到能放在片内RAM里才行。DE0用的是cycloneiiiEP3C16F484C6的FPGA,片上只有56个M9KRAM,56这个数字很鸡肋,介于32和64之间,所以我就建立了一个32K的双口RAM,由CPU读取SD卡的内容,写入RAM,然后VGA以50M的时钟读取并显示,VGA分辨率为800*600@72HZ,选这个就是因为时钟为50M跟DE0上的有源晶振一样,不用分频也不用倍频,省事了。
先找个美女图片,不要太大,大约在120*160左右。然后用Image2Lcd转化成.bin格式,宽度为97,高度为150(这个奇怪的大小是为了将就可怜的32KB显存)。
将SD卡格式化成FAT32格式:
然后将刚才用Image2Lcd生成的.bin文件发送到SD卡内,OK了,不用管了,注意整个过程是不需要使用WinHex的,这就是有文件系统的好处,呵呵。
搭建硬件系统,这回得说一下了,因为这个跟上一篇读取SD卡的不一样,这个有些小麻烦。
VGA接口就用的我博文里写的那个“基于DE0的VGA显示驱动”,同步模块没有变化,控制模块改动了一下。注意到DE0的VGA接口RGB信号都是4位宽,而16位图要求RGB为5,6,5宽度,那么做个小处理,丢弃低位只取高4位。控制模块变为纯组合逻辑,如下:
显示区域为屏幕的300=<x<=297和250<=y<=400的矩形内,注意,图片尺寸为:97*150,刚好吻合。
VGA的数据来自RAM,建立一个双口RAM:
然后下一页RAM容量这里要注意,16位图的一个像素用16位数据描述,所以RAM用16位宽,深度是越大越好,但是实测只能为32KB了:
然后选择双时钟,有读使能信号:
输出数据锁存一个时钟:
然后不初始化,让RAM里面开始是空的:
后面的内容全部默认设置即可,完成设置后,加到工程里面来。然后用verilog写一个模块,作为RAM的地址计数器用,很简单:
注意计数器计满值不是全1,而是根据图片大小调整的。使能信号就是上面vga_ctrl_module里的display信号。
SOPC里面除了CPU,SDRAM,FLASH,UART,systemID意外,还有一堆PIO,分别为:WR_DA,16位;WR_EN,1位;WR_ADDR,14位;RAM_CLK,1位;RD_EN,1位;SD_CLK,1位;SD_CMD,1位,双向;SD_CS_N,1位;SD_DA,1位;LED,8位,用来指示软件是否工作的。
RAM和VGA部分硬件图:
至此硬件就搭建完毕了。
软件部分涉及到FAT32文件系统的读取,比较麻烦,不想细讲。
首先建议大家看几个资料:http://blog.csdn.net/thnh169/article/details/6312944和http://wenku.baidu.com/view/50087d335a8102d276a22f6b.html
这两个讲的比较入门,可以看懂的话,读文件基本就没问题了。
直接贴代码了,我在代码开头建立了一个结构体位域,本来希望用位域来读取CSD寄存器内容的,后来DEBUG后发现不行,打印出来的内容与实际不符合,大家也可以想想这是为什么哈,后来我直接用缓存区的内容计算卡容量了。
头文件:
主函数:
程序只读取SD卡里面根目录下第一个文件,如果想切换画面的话也不难,留给读者思考吧。
最后的效果图:
土鳖的DE0:
蔚姐:
很小是吧?没办法DE0上没有片外RAM,那块SDRAM还拿来当运存了,实在是不知道怎么把它当显存。有时间在用DE2做个漂亮点的吧。。。
网上能搜到的关于数码相框的资料,大多是基于液晶屏显示的,我手里没有现成的液晶屏,VGA倒是有两个。大家选择液晶屏而不选VGA的原因,我后来才知道。因为VGA显示需要的显存比较大,一般至少2M,这么大的显存是要银子的。DE2上是有2M的sram的,而DE0上除了SDRAM和FLASH之外什么都没有。这板子穷啊,资源少,没有办法,只能把图片的尺寸和大小减小到能放在片内RAM里才行。DE0用的是cycloneiiiEP3C16F484C6的FPGA,片上只有56个M9KRAM,56这个数字很鸡肋,介于32和64之间,所以我就建立了一个32K的双口RAM,由CPU读取SD卡的内容,写入RAM,然后VGA以50M的时钟读取并显示,VGA分辨率为800*600@72HZ,选这个就是因为时钟为50M跟DE0上的有源晶振一样,不用分频也不用倍频,省事了。
先找个美女图片,不要太大,大约在120*160左右。然后用Image2Lcd转化成.bin格式,宽度为97,高度为150(这个奇怪的大小是为了将就可怜的32KB显存)。
将SD卡格式化成FAT32格式:
然后将刚才用Image2Lcd生成的.bin文件发送到SD卡内,OK了,不用管了,注意整个过程是不需要使用WinHex的,这就是有文件系统的好处,呵呵。
搭建硬件系统,这回得说一下了,因为这个跟上一篇读取SD卡的不一样,这个有些小麻烦。
VGA接口就用的我博文里写的那个“基于DE0的VGA显示驱动”,同步模块没有变化,控制模块改动了一下。注意到DE0的VGA接口RGB信号都是4位宽,而16位图要求RGB为5,6,5宽度,那么做个小处理,丢弃低位只取高4位。控制模块变为纯组合逻辑,如下:
module vga_ctrl_module( input ready, input [10:0]x_addr, input [10:0]y_addr, input [15:0]data_in, output [3:0]red, output [3:0]green, output [3:0]blue, output display ); assign display=ready & (((x_addr>=300)&&(x_addr<397))&&((y_addr>=250)&&(y_addr<400))); assign red[3:0]=(display)?data_in[15:12]:(ready)?4'b1111:4'd0; assign green[3:0]=(display)?data_in[10:7]:(ready)?4'b1111:4'd0; assign blue[3:0]=(display)?data_in[4:1]:(ready)?4'b1111:4'd0; endmodule
显示区域为屏幕的300=<x<=297和250<=y<=400的矩形内,注意,图片尺寸为:97*150,刚好吻合。
VGA的数据来自RAM,建立一个双口RAM:
然后下一页RAM容量这里要注意,16位图的一个像素用16位数据描述,所以RAM用16位宽,深度是越大越好,但是实测只能为32KB了:
然后选择双时钟,有读使能信号:
输出数据锁存一个时钟:
然后不初始化,让RAM里面开始是空的:
后面的内容全部默认设置即可,完成设置后,加到工程里面来。然后用verilog写一个模块,作为RAM的地址计数器用,很简单:
module ram_rd_addr ( input clk, input en, input rst_n, output reg[13:0]addr ); always@(posedge clk or negedge rst_n) begin if(!rst_n) addr<=14'b00_0000_0000_0000; else if(en && (addr==14'b11_1000_1101_0101)) addr<=14'b00_0000_0000_0000; else if(en) addr<=addr+1'b1; else addr<=addr; end endmodule
注意计数器计满值不是全1,而是根据图片大小调整的。使能信号就是上面vga_ctrl_module里的display信号。
SOPC里面除了CPU,SDRAM,FLASH,UART,systemID意外,还有一堆PIO,分别为:WR_DA,16位;WR_EN,1位;WR_ADDR,14位;RAM_CLK,1位;RD_EN,1位;SD_CLK,1位;SD_CMD,1位,双向;SD_CS_N,1位;SD_DA,1位;LED,8位,用来指示软件是否工作的。
RAM和VGA部分硬件图:
至此硬件就搭建完毕了。
软件部分涉及到FAT32文件系统的读取,比较麻烦,不想细讲。
首先建议大家看几个资料:http://blog.csdn.net/thnh169/article/details/6312944和http://wenku.baidu.com/view/50087d335a8102d276a22f6b.html
这两个讲的比较入门,可以看懂的话,读文件基本就没问题了。
直接贴代码了,我在代码开头建立了一个结构体位域,本来希望用位域来读取CSD寄存器内容的,后来DEBUG后发现不行,打印出来的内容与实际不符合,大家也可以想想这是为什么哈,后来我直接用缓存区的内容计算卡容量了。
头文件:
/* * sopc.h * * Created on: 2011-8-10 * Author: Fu-xiaoliang */ #ifndef SOPC_H_ #define SOPC_H_ #include "system.h" #define _LED typedef struct { unsigned long int DATA; unsigned long int DIRECTION; unsigned long int INTERRUPT_MASK; unsigned long int EDGE_CAPTURE; }PIO_STR; #ifdef _LED #define SD_DA ((PIO_STR *)SD_DA_BASE) #define SD_CMD ((PIO_STR *)SD_CMD_BASE) #define SD_CS ((PIO_STR *)SD_CS_N_BASE) #define SD_CLK ((PIO_STR *)SD_CLK_BASE) #define RD_EN ((PIO_STR *)RD_EN_BASE) #define RAM_CLK ((PIO_STR *)RAM_CLK_BASE) #define WR_ADDR ((PIO_STR *)WR_ADDR_BASE) #define WR_DA ((PIO_STR *)WR_DA_BASE) #define WR_EN ((PIO_STR *)WR_EN_BASE) #define LED ((PIO_STR *)LED_BASE) #define _SD #endif #ifdef _SD #define data (SD_DA->DATA) #define cmd (SD_CMD->DATA) #define cs (SD_CS->DATA) #define clk (SD_CLK->DATA) #endif #define uc unsigned char #endif /* SOPC_H_ */
主函数:
/* * "Hello World" example. * * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT * device in your system's hardware. * The memory footprint of this hosted application is ~69 kbytes by default * using the standard reference design. * * For a reduced footprint version of this template, and an explanation of how * to reduce the memory footprint for a given application, see the * "small_hello_world" template. * */ #include <stdio.h> #include "alt_types.h" // alt_u32 #include <unistd.h> #include "D:\FPGA-PROJECT\myself\SD_VGA\software\SD_VGA\inc\sopc.h" uc Resp_buffer[16]={0}; uc data_buffer[512]={0}; uc data_buffer1[512]={0}; unsigned long int DBR_ADDR=0; unsigned long int FAT1_ADDR=0; unsigned long int FAT2_ADDR=0; unsigned long int FDT_ADDR=0; unsigned long int CLUS_ADDR=0; unsigned long int CLUS_CURRENT=0;//current clus number unsigned long int CLUS_LEN=0;//clus lenth unsigned long int CLUS_NEXT=0; unsigned int RAM_ADDR=0; uc not_finish=0; struct { union { unsigned char CSD[16]; struct { unsigned CSD_STRUCTURE :2; unsigned reserve :6;//0 unsigned TAAC :8;//1 unsigned NSAC :8;//2 unsigned TRAN_SPEED :8;//3 unsigned CCC :12;//4+5.4 unsigned READ_BL_LEN :4;//5 unsigned READ_BL_PARTIAL :1;//6 unsigned WRITE_BLK_MISALIGN :1;//6 unsigned READ_BLK_MISALIGN :1; unsigned DSR_IMP :1; unsigned reserve1 :2;//6 unsigned C_SIZE :12;//6.2+7+8.2 unsigned VDD_R_CURR_MIN :3;//8 unsigned VDD_R_CURR_MAX :3; unsigned VDD_W_CURR_MIN :3;//9 unsigned VDD_W_CURR_MAX :3; unsigned C_SIZE_MULT :3;//9.2+10.1 unsigned ERASE_BLK_EN :1; unsigned SECTOR_SIZE :7; unsigned WP_GRP_SIZE :7; unsigned WP_GRP_ENABLE :1; unsigned reserve2 :2; unsigned R2W_FACTOR :3; unsigned WRITE_BL_LEN :4; unsigned WRITE_BL_PARTIAL :1; unsigned reserve3 :5; unsigned FILE_OFRMAT_GRP :1; unsigned COPY :1; unsigned PERM_WRITE_PROTECT :1; unsigned TMP_WRITE_PROTECT :1; unsigned FIL_FORMAT :2; unsigned reserve4 :2; unsigned CRC :7; unsigned one :1; }CSD_BIT; }CSD_DA; union { unsigned char buf1[16]; struct { long long int MID :8; long long int OID :16; long long int PNM :40; long long int PRV :8; long long int PSN :32; long long int RES :4; long long int MDT :12; long long int CRC :7; long long int ONE :1; }CID; }CID_DA; }REG; uc send_byte(uc sda) { uc cnt=0,rda=0; SD_CLK->DATA=1; SD_CMD->DIRECTION=1; for(cnt=0;cnt<8;cnt++) { SD_CLK->DATA=0; SD_CMD->DATA=0; if(sda & 0x80) SD_CMD->DATA=1; usleep(50); sda=sda<<1; rda=rda<<1; SD_CLK->DATA=1; if(SD_DA->DATA) { rda=rda|0x01; } // SD_CLK->DATA=1; } SD_CLK->DATA=1; return rda; } uc send_byte_fast(uc sda) { uc cnt=0,rda=0; SD_CLK->DATA=1; SD_CMD->DIRECTION=1; for(cnt=0;cnt<8;cnt++) { SD_CLK->DATA=0; SD_CMD->DATA=0; if(sda & 0x80) SD_CMD->DATA=1; // usleep(70); sda=sda<<1; rda=rda<<1; SD_CLK->DATA=1; if(SD_DA->DATA) { rda=rda|0x01; } } SD_CLK->DATA=1; return rda; } uc write_CMD0(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x40); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x95); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD0 no replay\n"); break; } }while(a!=0x01); // SD_CS->DATA=1; return a; } uc send_CMD(uc number,uc x,uc y,uc z,uc w, uc u,uc v,uc r) { uc b=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(x); send_byte(y); send_byte(z); send_byte(w); send_byte(u); send_byte(v); do { b=send_byte(0xff); i++; if(i==200) { printf("CMD%d no replay\n",number); break; } }while(b!=r); // SD_CS->DATA=1; return b; } uc write_CMD1(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x41); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD1 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD16(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x50); send_byte(0x00); send_byte(0x00); send_byte(0x02); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD16 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD17(uc x,uc y,uc z,uc w) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x51); send_byte(w); send_byte(z); send_byte(y); send_byte(x); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD17 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD24(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x58); send_byte(0x00); send_byte(0x00); send_byte(0x02); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD24 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD58(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x7a); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD58 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD59(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x7b); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD59 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD9(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte(0xff); SD_CS->DATA=0; send_byte(0x49); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0x00); send_byte(0xff); do { a=send_byte(0xff); i++; if(i==200) { printf("CMD9 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc write_CMD10(void) { uc a=0,i=0; SD_CS->DATA=1; send_byte_fast(0xff); SD_CS->DATA=0; send_byte_fast(0x4a); send_byte_fast(0x00); send_byte_fast(0x00); send_byte_fast(0x00); send_byte_fast(0x00); send_byte_fast(0xff); do { a=send_byte_fast(0xff); i++; if(i==200) { printf("CMD10 no replay\n"); break; } }while(a!=0x00); // SD_CS->DATA=1; return a; } uc sd_init(void) { uc i=0; uc a,b; SD_CS->DATA=1; for(i=0;i<100;i++) { send_byte(0xff); } usleep(250); i=0; do { b=write_CMD0(); i++; if(i==100) break; }while(b!=0x01); printf("CMD0 replay %x\n",b); i=0; do { b=write_CMD0(); i++; if(i==100) break; }while(b!=0x01); printf("CMD0 replay %x\n",b); i=0; do { usleep(500); a=send_CMD(0x01,0x41,0x00,0x00,0x00,0x00,0xff,0x00); i++; if(i==100) break; }while(a!=0x00); printf("CMD1 replay %x\n",a); i=0; do { a=write_CMD1(); i++; if(i==100) break; }while(a!=0x00); printf("CMD1 replay %x\n",a); i=0; do { a=write_CMD16(); i++; if(i==10) break; }while(a!=0x00); printf("CMD16 replay %x\n",a); i=0; do { a=send_CMD(59,0x7b,0x00,0x00,0x00,0x00,0xff,0x00); i++; if(i==10) break; }while(a!=0x00); printf("CMD59 replay %x\n",a); do { a=write_CMD9(); i++; if(i==10) break; }while(a!=0x00); printf("CMD9 replay %x\n",a); if(a==0x00) { uc tem=0; do { printf("tem is %x\n",tem); tem=send_byte(0xff); }while(tem!=0xfe); printf("tem is %x\n",tem); if(tem==0xfe) { printf("0xfe is received\n"); for(i=0;i<16;i++) { Resp_buffer[i]=send_byte(0xff); } send_byte(0xff); send_byte(0xff); SD_CS->DATA=1; send_byte(0xff); } } for(i=0;i<16;i++) { printf("CSD is %x\n",Resp_buffer[i]); REG.CSD_DA.CSD[i]=Resp_buffer[i]; } return 0; } int main() { int i=0,j=0,k=0; uc a; for(i=0;i<8;i++) { LED->DATA=1<<i; usleep(500000); } SD_CS->DATA=1; SD_CMD->DIRECTION=1; SD_CMD->DATA=1; sd_init(); i=0; do { a=write_CMD10(); i++; if(i==10) break; }while(a!=0x00); printf("CMD10 replay %x\n",a); if(a==0x00) { uc tem=0; do { printf("tem is %x\n",tem); tem=send_byte(0xff); }while(tem!=0xfe); printf("tem is %x\n",tem); if(tem==0xfe) { printf("0xfe is received\n"); for(i=0;i<16;i++) { Resp_buffer[i]=send_byte(0xff); } send_byte(0xff); send_byte(0xff); SD_CS->DATA=1; send_byte(0xff); } for(i=0;i<16;i++) { printf("CID is %x\n",Resp_buffer[i]); REG.CID_DA.buf1[i]=Resp_buffer[i]; } } i=0; do { a=write_CMD17(0x00,0x00,0x00,0x00); i++; if(i==10) break; }while(a!=0x00); printf("CMD17 replay %x\n",a); if(a==0x00) { uc temp=0; int j=0;; do{ printf("temp is %x\n",temp); temp=send_byte(0xff); j++; }while(temp!=0xfe && j<20); printf("temp is %x\n",temp); if(temp==0xfe) { printf("0xfe is received\n"); printf("block 0 data is followed\n"); for(j=0;j<512;j++) { data_buffer[j]=send_byte(0xff); } i=0; for(j=0;j<512;j++) { printf("%x ",data_buffer[j]); i++; if(i==16) { i=0; printf("\n"); } } } } if((data_buffer[0]==0x00)||(data_buffer[0]!=0xeb)||(data_buffer[0]!=0xe9)) { DBR_ADDR=(((DBR_ADDR|data_buffer[457])<<24)|((DBR_ADDR|data_buffer[456])<<16)|((DBR_ADDR|data_buffer[455])<<8)|data_buffer[454])*512; i=0; do{ a=send_CMD(17,0x51,((DBR_ADDR&0xff000000)>>24),((DBR_ADDR&0x00ff0000)>>16),((DBR_ADDR&0x0000ff00)>>8),(DBR_ADDR&0xff),0xff,0x00); i++; if(i==10) break; }while(a!=0x00); if(a==0x00) { uc temp=0; int j=0;; do{ printf("temp is %x\n",temp); temp=send_byte(0xff); j++; }while(temp!=0xfe && j<20); printf("temp is %x\n",temp); if(temp==0xfe) { printf("0xfe is received\n"); printf("DBR data is followed\n"); for(j=0;j<512;j++) { data_buffer[j]=send_byte(0xff); } i=0; for(j=0;j<512;j++) { printf("%x ",data_buffer[j]); i++; if(i==16) { i=0; printf("\n"); } } } } } else { DBR_ADDR=0; } FAT1_ADDR=DBR_ADDR+((data_buffer[14]|(data_buffer[15]<<8))*512); FAT2_ADDR=FAT1_ADDR+((data_buffer[36]|(data_buffer[37]<<8))*512); FDT_ADDR=FAT2_ADDR+((data_buffer[36]|(data_buffer[37]<<8))*512); CLUS_LEN=data_buffer[13]*512; printf("FAT1_ADDR is %lx \n",FAT1_ADDR); printf("FAT2_ADDR is %lx \n",FAT2_ADDR); printf("FDT_ADDR is %lx \n",FDT_ADDR); printf("DBR_ADDR is %lx \n",DBR_ADDR); printf("CLUS_LEN is %lx \n",CLUS_LEN); i=0; do{ a=send_CMD(17,0x51,((FDT_ADDR&0xff000000)>>24),((FDT_ADDR&0x00ff0000)>>16),((FDT_ADDR&0x0000ff00)>>8),(FDT_ADDR&0xff),0xff,0x00); i++; if(i==10) break; }while(a!=0x00); if(a==0x00) { uc temp=0; int j=0; do{ printf("temp is %x\n",temp); temp=send_byte(0xff); j++; }while(temp!=0xfe && j<20); printf("temp is %x\n",temp); if(temp==0xfe) { printf("0xfe is received\n"); printf("FDT data is followed\n"); for(j=0;j<512;j++) { data_buffer[j]=send_byte(0xff); } i=0; for(j=0;j<512;j++) { printf("%x ",data_buffer[j]); i++; if(i==16) { i=0; printf("\n"); } } } } for(i=0;i<512;i=i+32) { if((data_buffer[11+i]==0x08)&&(data_buffer[i]!=0xe5)) { printf("juan biao is %d\n",i+11); continue; } else if((data_buffer[11+i]==0x20)&&(data_buffer[i]!=0xe5)) { CLUS_CURRENT=(data_buffer[20+i]<<16)|(data_buffer[21+i]<<24)|(data_buffer[27+i]<<8)|(data_buffer[26+i]); printf("first clus is %ld\n",CLUS_CURRENT); } else if(data_buffer[i]==0xe5) continue; else if(data_buffer[i]==0x00) { break; not_finish=0;//no file behind } } i=0; do{ a=send_CMD(17,0x51,((FAT1_ADDR&0xff000000)>>24),((FAT1_ADDR&0x00ff0000)>>16),((FAT1_ADDR&0x0000ff00)>>8),(FAT1_ADDR&0xff),0xff,0x00); i++; if(i==10) break; }while(a!=0x00); if(a==0x00) { uc temp=0; int j=0;; do{ printf("temp is %x\n",temp); temp=send_byte(0xff); j++; }while(temp!=0xfe && j<20); printf("temp is %x\n",temp); if(temp==0xfe) { printf("0xfe is received\n"); printf("FAT1 data is followed\n"); for(j=0;j<512;j++) { data_buffer[j]=send_byte(0xff); } i=0; for(j=0;j<512;j++) { printf("%x ",data_buffer[j]); i++; if(i==16) { i=0; printf("\n"); } } } } CLUS_ADDR=(CLUS_CURRENT-2)*CLUS_LEN+FDT_ADDR;//first data clus address CLUS_NEXT=data_buffer[CLUS_CURRENT*4]|(data_buffer[CLUS_CURRENT*4+1]<<8)|(data_buffer[CLUS_CURRENT*4+2]<<16)|(data_buffer[CLUS_CURRENT*4+3]<<24); printf("CLUS_NEXT is %lx\n",CLUS_NEXT); RAM_ADDR=0x0; RD_EN->DATA=0; do { CLUS_ADDR=(CLUS_CURRENT-2)*CLUS_LEN+FDT_ADDR; CLUS_CURRENT=CLUS_NEXT; CLUS_NEXT=data_buffer[CLUS_CURRENT*4]|(data_buffer[CLUS_CURRENT*4+1]<<8)|(data_buffer[CLUS_CURRENT*4+2]<<16)|(data_buffer[CLUS_CURRENT*4+3]<<24); for(k=0;k<8;k++) { i=0; do{ a=send_CMD(17,0x51,(((CLUS_ADDR+512*k)&0xff000000)>>24),(((CLUS_ADDR+512*k)&0x00ff0000)>>16),(((CLUS_ADDR+512*k)&0x0000ff00)>>8),((CLUS_ADDR+512*k)&0xff),0xff,0x00); i++; if(i==10) break; }while(a!=0x00); if(a==0x00) { uc temp=0; int j=0;; do{ printf("temp is %x\n",temp); temp=send_byte(0xff); j++; }while(temp!=0xfe && j<20); printf("temp is %x\n",temp); if(temp==0xfe) { printf("0xfe is received\n"); printf("first clus data is followed\n"); for(j=0;j<512;j++) { data_buffer1[j]=send_byte(0xff); } i=0; for(j=0;j<512;j++) { usleep(10); printf("%x ",data_buffer1[j]); i++; if(i==16) { i=0; printf("\n"); } } } } for(i=0;i<511;i=i+2)//i from 0 to 510,and i+1 from 1 to 511 { WR_DA->DATA=data_buffer1[i+1]|(data_buffer1[i]<<8); RAM_CLK->DATA=0; WR_ADDR->DATA=RAM_ADDR; WR_EN->DATA=1; RAM_CLK->DATA=1; WR_EN->DATA=0; RAM_ADDR++; } } }while(CLUS_NEXT!=0x0fffffff); RD_EN->DATA=1; SD_CS->DATA=1; unsigned long int cap; double c; //(c_size+1)*mult*(1<<read_bl_len) cap=((((REG.CSD_DA.CSD[6]&0x03)<<10) | (REG.CSD_DA.CSD[7]<<2) | ((REG.CSD_DA.CSD[8]&0xC0)>>6) + 1))*(1 << ((((REG.CSD_DA.CSD[9]&0x03)<<1) | ((REG.CSD_DA.CSD[10]&0x80)>>7)) + 2))*(1<<(REG.CSD_DA.CSD[5]&0x0f)); printf("capacity is %ld MB\n",cap/1048576); printf("read_bl_len is %d B\n",(1<<(REG.CSD_DA.CSD[5]&0x0f))); c=((double)cap/1073741824); printf("capacity is %f GB\n",c); printf("send CMD0!\n"); return 0; }
程序只读取SD卡里面根目录下第一个文件,如果想切换画面的话也不难,留给读者思考吧。
最后的效果图:
土鳖的DE0:
蔚姐:
很小是吧?没办法DE0上没有片外RAM,那块SDRAM还拿来当运存了,实在是不知道怎么把它当显存。有时间在用DE2做个漂亮点的吧。。。
相关文章推荐
- 单片机读取SD卡中BMP图片文件并送往TFT彩屏上显示(测试成功)(一)
- 单片机读取SD卡中BMP图片文件并送往TFT彩屏上显示(测试成功)(二)
- [原创][连载].基于SOPC的简易数码相框 - Nios II SBTE部分(软件部分) - 从SD卡内读取图片文件,然后显示在TFT-LCD上
- FileReader:读取本地图片文件并显示
- android 根据SD卡中图片路径读取并显示SD中的图片——源代码
- FileReader:读取本地图片文件并显示
- 同一张图片从res和Sd卡中读取显示大小不一样
- Asp.net把图片存入数据库和使用文件流来读取显示
- 制作电子相册(sd卡读取bmp图片显示在tft彩屏上)读取fat32的步骤非常简单的方法
- android读取Assets图片资源保存到SD卡然后显示到ImageView里 实例
- Android中读取SD卡中的图片,并显示到ListView
- Flex的Image控件中如何在读取图片文件错误时显示一个tool tip的例子
- UNO R3从SD卡读取图片并显示到2.2寸液晶屏上(220x176)
- nodejs基础(一)创建服务器,分发路由,读文件,写文件,读取图片,图文一起显示
- input file文件上传(multiple)及FileReader:读取本地图片文件并显示
- FileReader:读取图片文件并显示
- 读取SD卡里面的BMP文件 显示到TFT上
- 读取磁盘图片文件并显示
- Android实现读取SD卡下所有TXT文件名并用listView显示出来的方法
- Servlet从本地文件中读取图片,并显示在页面中