SD+FATFS+2440总结

[复制链接]
 楼主| 386452199 发表于 2011-5-19 23:13 | 显示全部楼层 |阅读模式
FATFS, sd, TE, ni, ST
首先在这里感谢,在我学习SD+FATFS+2440期间帮助过我、帮我顶贴的大虾们。特别是byhoo,没有他的帮助,我可能到现在还没有做出。
   我学习SD+FATFS+2440时间比较短,前后加起来大概一个星期吧。先用两天时间看MINI2440给的TEST。SDI.C这个是必看的,要想用SD就要把这个程序看明白,这样移植FATFS时才会容易一点。
   关于FATFS网上有好多文档,这里只说FATFS的移植要点。我的原则是先成功,再细看。
   ff.h  ff.c  diskio.h 这三个文件没有多少要一开始就深入掌握的东西,想了解的话网上好多。
   integer.h 这个要注意,因为里面的WORD  DWORD BYTE这三个和MINI2440的定义不一样,我的做法比较笨不过不会出错,以后再加别的也不会冲突。把 integer.h 所有在def.h中没有定义的加到def.h中,把定义一样的删掉,把定义冲突的三个定义为
WORD_fat  DWORD_fat BYTE_fat 并在FATFS中将WORD  DWORD BYTE改为
WORD_fat  DWORD_fat BYTE_fat 。这样做可能会麻烦点,但以后你要再在程序中加点别的什么都不会有冲突。我这是笨办法大家别笑我。最后,把FATFS中的#include "integer.h" 改为#include "def.h"就可以了。
   重点是diskio.c中的几个函数。disk_initialize在我程序中的理解就是SD卡初始化,但这个有点问题,每次第一次进f_open时是对的,第二次再进,SD卡初始化就会出错(f_open中调用了disk_initialize)。所以我将disk_initialize什么都不做,直接返回0,再主程序刚开始时就初始化SD。这样不会出错了。
   我只想用SD卡做为一个数据的读取,所以只要关心disk_read这个函数就可以了。别的函数如果你也想用,其实在你将disk_read自己完整写出来时,就都不是难事了,相信我。
   MINI2440中有SD的读程序,你可以将它改改就可以用。不过我在网上看到一个贴子
http://bbs.21ic.com/icview-165708-1-1.html第20楼有改好的,拿来用就可以。
   但一开始怎么都不对,跟踪程序发现f_open---->auto_mount---->check_fs这里出的错误,这里程序判断SD中有没有文件系统,就是这里。
if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)
我程序中&fs->win[BS_55AA]=0X55AA,所以出错。最后发现是大小端问题。我的ARM用的是小端,但SD卡是大端,在2440中rSDICON这里是设SD卡读数大小端的。
rSDICON=(0<<4)|1;这样就可以了。
   接着向下跑又出错,仔细看看自己的程序和byhoo的程序发现http://bbs.21ic.com/icview-165708-1-1.html  20楼的程序有点小BUG。
   rcvr_datablock(buff, 512),这里没有sector这个参数,sector很重要,我们要用它来计算读SD卡的地址。20楼的程序rcvr_datablock(buff, 512)中地址为0
rSDICARG=0x0;,f_open---->auto_mount---->check_fs这里本来就是读的0地址所以是对的,但程序再向下读时就不对了,所以要改。
static  BOOL rcvr_datablock (BYTE_fat *buff,DWORD sector,UINT btr)
{   
    //Polling read Mode
   
    int status;
   
    unsigned int rcv_num=0;
   
    UINT blk_num;
   
    DWORD_fat rcv_tmp;   
     
   
    blk_num=btr/512;
   
        rSDIFSTA=rSDIFSTA|(1<<16);        // FIFO reset
   
        rSDIDCON=(2<<22)|(1<<19)|(1<<17)|(1<<16)|(1<<14)|(2<<12)|(blk_num<<0);        //YH 040220
                //Word Rx, Rx after cmd, blk, 1bit bus, Rx start, blk num, data start, data transmit mode
    rSDICARG=sector*0x200;        // CMD17/18(addr)
RERDCMD:         
   if(blk_num<2) // SINGLE_READ
    {   
         
           rSDICCON=(0x1<<9)|(0x1<<8)|0x51;    // sht_resp, wait_resp, dat, start, CMD17
           if(!Chk_CMDend(17, 1))        //-- Check end of CMD17
                 goto RERDCMD;                  
    }
   
   else        // MULTI_READ
        {
                rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    // sht_resp, wait_resp, dat, start, CMD18
                if(!Chk_CMDend(18, 1))        //-- Check end of CMD18
                    goto RERDCMD;
        }
rSDICSTA=0xa00;        // Clear cmd_end(with rsp)
    while(rcv_num<128*blk_num)        // 512=128*4 bytes
    {
                if((rSDIDSTA&0x20)==0x20) // Check timeout
                {
                    rSDIDSTA=(0x1<<0x5);  // Clear timeout flag
                    break;
                }
               
                status=rSDIFSTA;
               
                if((status&0x1000)==0x1000)        // Is Rx data?
                {
                    rcv_tmp=rSDIDAT;
                    //Uart_Printf("%x\n",rcv_tmp);
                   //Uart_Printf("%X\n",buff[rcv_num]);
                    *(BYTE_fat*)(buff)=(BYTE_fat)(rcv_tmp);
                   // Uart_Printf("%x\n",*buff);
                    buff++;
                    *(BYTE_fat*)(buff)=(BYTE_fat)((WORD_fat)(rcv_tmp)>>8);
                   // Uart_Printf("%x\n",*buff);
                    buff++;
                    *(BYTE_fat*)(buff)=(BYTE_fat)((DWORD_fat)(rcv_tmp)>>16);
                   // Uart_Printf("%x\n",*buff);
                    buff++;
                    *(BYTE_fat*)(buff)=(BYTE_fat)((DWORD_fat)(rcv_tmp)>>24);   
                   // Uart_Printf("%x\n",*buff);
                    buff++;                  
                    
                    rcv_num++;
                }
    }

   
   
    if(!Chk_DATend())
            return FALSE;
            
        rSDIDCON=rSDIDCON&~(7<<12);                //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
        rSDIFSTA=rSDIFSTA&0x200;        //Clear Rx FIFO Last data Ready, YH 040221
    rSDIDSTA=0x10;        // Clear data Tx/Rx end detect
   
   if(blk_num>1)
    {
          RERCMD12:   
                //--Stop cmd(CMD12)
                rSDICARG=0x0;            //CMD12(stuff bit)
                rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;//sht_resp, wait_resp, start, CMD12
                //-- Check end of CMD12
                if(!Chk_CMDend(12, 1))
                    goto RERCMD12;
                rSDICSTA=0xa00;        // Clear cmd_end(with rsp)
    }
   
    return TRUE;                                        /* Return with success */           
}
调用时rcvr_datablock(buff,sector,count*512))
注意在disk_read中sector *= 512;要注掉
这样就可以了。
   再跑程序,OK,ad.txt中的数据读取成功。
   再次感谢谢byhoo,也祝想学SD+FATFS+2440的网友一次成功。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
abin0415 发表于 2011-5-21 12:39 | 显示全部楼层
支持一下
 楼主| 386452199 发表于 2011-5-21 12:47 | 显示全部楼层
:)谢谢
lixupengarm 发表于 2011-5-21 21:08 | 显示全部楼层
参考下!!
js_xuzh 发表于 2011-6-2 10:13 | 显示全部楼层
支持下不错的**,好样的..交个朋友吧哈哈
baoliguo 发表于 2011-7-12 21:04 | 显示全部楼层
谢谢搂主
lixiaoxu2meng 发表于 2011-8-2 11:23 | 显示全部楼层
很好
xllcd2009 发表于 2012-5-31 09:38 | 显示全部楼层
写得好详细哟,不错。:handshake
纵横阡陌 发表于 2012-6-26 13:20 | 显示全部楼层
你好,我现在也正在学习这个,移植了好多天了,不能成功啊,能不能给我发一份源码?我的QQ:819441773,谢谢
6652102 发表于 2012-7-22 22:12 | 显示全部楼层
楼主写的真好,我现在学习怎样把fatfs移植到s3c2440,谢谢!:handshake
jiaowoxiaolu 发表于 2012-7-24 10:13 | 显示全部楼层
我现在移植也遇到卡子了,每次调用fatfs的函数都会重新初始化一遍sd卡,按照你说的,吧diskio里面的初始化什么都不干了,虽然不初始化了,但是还是创建不了文件,总感觉这个不是最终办法
sanliu85 发表于 2012-7-24 15:39 | 显示全部楼层
想楼主学习
szembed 发表于 2012-7-24 17:55 | 显示全部楼层
这个东西不错。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

23

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

0

主题

23

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部