您的位置:首页 > 其它

【原创】从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位。控制模块变为纯组合逻辑,如下:

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/6312944http://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做个漂亮点的吧。。。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐