野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12155|回复: 4

用野火的K60库操作SD卡出问题

[复制链接]
发表于 2015-12-28 22:23:31 | 显示全部楼层 |阅读模式
有两个问题, 第一个稍微简单点,全速运行会在disk_read() 里的 if (Stat & STA_NOINIT) return RES_NOTRDY;     //未就绪  
这里返回error  要是在前面设了断点就不会。。  可以理解为速度太快了?  只需要延时一下就好了吗?


第二个问题, 我先把 disk_read() 贴出来
DRESULT disk_read (         //读磁盘扇区
    uint8  drv,             /* 物理驱动编号 (0) */
    uint8  *buff,           /* 指向数据缓冲区来存储读到的数据 */
    uint32 sector,          /* 开始的扇区号 (LBA) */
    uint8  count            /* 扇区总数(1..255) */
)
{
    ESDHC_CMD_t command;

    if (drv || (!count)) return RES_PARERR;       //drv 只能为 0, count 必须不等于0
    if (Stat & STA_NOINIT) return RES_NOTRDY;     //未就绪

    /* 检测参数 */
    if ((NULL == buff))
    {
        return RES_PARERR;//参数无效
    }

    if (!SDHC_card.SDHC)
    {
        sector *= SDCARD_BLOCK_SIZE;    /* 如果需要,转换为字节地址 */
    }

    if (count == 1) /* 单块读 */
    {
        command.COMMAND = ESDHC_CMD17;
        command.TYPE = ESDHC_TYPE_NORMAL;
        command.ARGUMENT = sector;
        command.READ = TRUE;
        command.BLOCKS = count;

        if (ESDHC_IOCTL_OK == SDHC_ioctl (ESDHC_IOCTL_SEND_CMD, &command))
        {
            if (rcvr_datablock(buff, SDCARD_BLOCK_SIZE))     // 单步运行到此处,IF中的返回值不为1,导致后面返回error,于是再进去看看这个函数,仍然贴在下面
            {
                count = 0;
            }
        }
    }
    else
    {
        /* 多块读 */
        //
        command.COMMAND = ESDHC_CMD18;
        //command.COMMAND = ESDHC_CMD17;
        command.TYPE = ESDHC_TYPE_NORMAL;
        command.ARGUMENT = sector;
        command.READ = TRUE;
        command.BLOCKS = count;

        if (ESDHC_IOCTL_OK == SDHC_ioctl (ESDHC_IOCTL_SEND_CMD, &command))
        {
            if (rcvr_datablock(buff, SDCARD_BLOCK_SIZE * count))
            {
                count = 0;
            }
        }
    }

    return count ? RES_ERROR : RES_OK;
}






static int rcvr_datablock (uint8   *buff, uint32  btr)
{
    uint32  bytes, i, j;
    uint32  *ptr = (uint32 *)buff;


    /* Workaround for random bit polling failures - not suitable for IO cards    */

    while(!(SDHC_IRQSTAT & SDHC_IRQSTAT_BRR_MASK));
    SDHC_IRQSTAT =  SDHC_IRQSTAT_BRR_MASK ;

    /* Read data in 4 byte counts */
    bytes = btr;
    while (bytes)
    {
        i = bytes > SDCARD_BLOCK_SIZE ? SDCARD_BLOCK_SIZE : bytes;
        for (j = (i + 3) >> 2; j != 0; j--)
        {
            if (SDHC_IRQSTAT & (SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK))  //  问题找到了,就是这句话判断出错,返回了0值,导致SD卡操作失败。
            {
                SDHC_IRQSTAT |= SDHC_IRQSTAT_DEBE_MASK | SDHC_IRQSTAT_DCE_MASK | SDHC_IRQSTAT_DTOE_MASK | SDHC_IRQSTAT_BRR_MASK;
                return 0;
            }

            while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BREN_MASK)) {};

            //小端
            *ptr++ = SDHC_DATPORT;
        }
        bytes -= i;
    }

    return 1;                       /* Return with success */
}


发现了问题,但不知道为什么,也不知道怎么解决, 求大神帮忙看看
回复

使用道具 举报

 楼主| 发表于 2015-12-28 22:30:07 | 显示全部楼层
补充:   程序运行线路 是从  f_open() --->  res = chk_mounted(&path, &dj.fs, 0)   -->     fmt = check_fs(fs, bsect = 0);   -->   
if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */
        return 3;
--->  就在这个disk_read()  里面出错了。  具体出错地方就是上面所述,还请解答。
回复 支持 反对

使用道具 举报

发表于 2015-12-29 00:12:52 | 显示全部楼层
丶丨贝尔 发表于 2015-12-28 22:30
补充:   程序运行线路 是从  f_open() --->  res = chk_mounted(&path, &dj.fs, 0)   -->     fmt = check ...

来错论坛了,哈哈
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-29 15:07:50 | 显示全部楼层

那应该去哪个论坛啊。。
回复 支持 反对

使用道具 举报

发表于 2015-12-30 08:46:27 | 显示全部楼层
K60这里讨论比较多:http://www.vcan123.com/forum.php
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-22 23:17 , Processed in 0.044441 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表