打印

SD+FATFS+2440总结

[复制链接]
6053|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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的读程序,你可以将它改改就可以用。不过我在网上看到一个贴子
https://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的程序发现https://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的网友一次成功。



也许对你有用.zip (1.94 MB)

相关帖子

沙发
abin0415| | 2011-5-21 12:39 | 只看该作者
支持一下

使用特权

评论回复
板凳
386452199|  楼主 | 2011-5-21 12:47 | 只看该作者
:)谢谢

使用特权

评论回复
地板
lixupengarm| | 2011-5-21 21:08 | 只看该作者
参考下!!

使用特权

评论回复
5
js_xuzh| | 2011-6-2 10:13 | 只看该作者
支持下不错的**,好样的..交个朋友吧哈哈

使用特权

评论回复
6
baoliguo| | 2011-7-12 21:04 | 只看该作者
谢谢搂主

使用特权

评论回复
7
lixiaoxu2meng| | 2011-8-2 11:23 | 只看该作者
很好

使用特权

评论回复
8
xllcd2009| | 2012-5-31 09:38 | 只看该作者
写得好详细哟,不错。:handshake

使用特权

评论回复
9
纵横阡陌| | 2012-6-26 13:20 | 只看该作者
你好,我现在也正在学习这个,移植了好多天了,不能成功啊,能不能给我发一份源码?我的QQ:819441773,谢谢

使用特权

评论回复
10
6652102| | 2012-7-22 22:12 | 只看该作者
楼主写的真好,我现在学习怎样把fatfs移植到s3c2440,谢谢!:handshake

使用特权

评论回复
11
jiaowoxiaolu| | 2012-7-24 10:13 | 只看该作者
我现在移植也遇到卡子了,每次调用fatfs的函数都会重新初始化一遍sd卡,按照你说的,吧diskio里面的初始化什么都不干了,虽然不初始化了,但是还是创建不了文件,总感觉这个不是最终办法

使用特权

评论回复
12
sanliu85| | 2012-7-24 15:39 | 只看该作者
想楼主学习

使用特权

评论回复
13
szembed| | 2012-7-24 17:55 | 只看该作者
这个东西不错。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

23

帖子

1

粉丝