【原创】从SD卡读取bin图片文件并用VGA显示(FAT32文件系统)(quartus11.0)(DE0)

  这几天搞定了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做个漂亮点的吧。。。

 

posted @ 2011-08-18 20:10  lamapig  阅读(5468)  评论(3编辑  收藏  举报