11126|12

8

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

SD卡底层驱动源程序公开------【注意】我的MP3开发板回来了 [复制链接]

本程序参考自bozai的SD卡驱动程序, 增加了SD、MMC卡判断的功能,SD、MMC初始化成功后能返回卡的类型参数供主程序使用。

//--------SD_MMC.H------------------------

#ifndef __SD_MMC_H__
#define __SD_MMC_H__

// 数据宏定义
#define uint8  unsigned char
#define  int8    signed char
#define uint16 unsigned int
#define  int16   signed int
#define uint32 unsigned long
#define  int32   signed long
  
// C8051F015与SD_MMC 的接口定义
sbit SDCS        = P3^0;
sbit SDDET        = P3^1;
sbit SDWP        = P3^2;


void SPI_SendWreit(uchar temp);        // VS1003B DATA发送
uint8 SPI_SendByte(uint8 val);        // SPI传送一个字节
uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg);        //发送卡命令
uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8 *buffer);        //读一个扇区
uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 *buffer);        //写一个扇区
uint8 MMC_SD_init();        //mmc_sd卡初始化

#endif
此帖出自单片机论坛

最新回复

好东西,不错学习学习!!!  详情 回复 发表于 2010-7-8 13:20
点赞 关注
 

回复
举报

8

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

回复 楼主 的帖子

//---------SD_MMC.C-----------------

//---------------------------------------------------------
//        SD_MMC  底层驱动函数库
//        编译环境:Keil C V2.40
//        编写日期:2008-04-07
//        最后更新:2008-05-04
//---------------------------------------------------------
#include "main.h"
#include "sd_mmc.h"

//---------------------------------------------------
//        函数名:SPI_SendByte
//        功  能:SPI 数据发送
//        参  数:uchar
//        返回值:
//---------------------------------------------------

void SPI_SendWreit(uchar temp)
{
        SPI0DAT=temp;
        while(TXBSY);        // 查询发送标志位
}

//---------------------------------------------------
//        函数名:SPI_SendByte
//        功  能:SPI传送一个字节
//        参  数:uchar
//        返回值:uchar
//---------------------------------------------------

uint8 SPI_SendByte(uint8 val)        // uint8= uchar
{
        SPI0DAT = val;
        while(TXBSY);
        return SPI0DAT;
}

//---------------------------------------------------
//        函数名:MMC_SD_SendCmd
//        功  能:发送卡命令
//        参  数:uint8,uint32
//        返回值:uint8
//---------------------------------------------------

uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg)
{
        uint8 r1;
        uint8 retry=0;
         
        SPI_SendWreit(0xFF);        //发命令前先发送8个时钟
         
        SPI_SendWreit(Cmd | 0x40);        //分别写入命令
        SPI_SendWreit(arg>>24);
        SPI_SendWreit(arg>>16);
        SPI_SendWreit(arg>>8);
        SPI_SendWreit(arg);
        SPI_SendWreit(0x95);                //仅本次有效的 CRC值         
         
        while((r1 = SPI_SendByte(0xFF)) == 0xFF)        //等待响应
                if(retry++ > 8) break;        //超时退出

        return r1;        //返回状态值
}
此帖出自单片机论坛
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

回复 沙发 的帖子

//---------------------------------------------------
//        函数名:MMC_SD_ReadSingleBlock
//        功  能:读一个扇区
//        参  数:扇区,数据缓冲区
//        返回值:
//---------------------------------------------------

uint8 MMC_SD_ReadSingleBlock(uint32 sector,uint8 *buffer)
{
        uint8 r1;
        uint16 i;

        SDCS=0;                // 使能Card

        r1 = MMC_SD_SendCmd(17, sector<<9);        // 发读扇区命令
         
        if(r1 != 0x00) return r1;

        while(SPI_SendByte(0xFF) != 0xFE);        //--等待数据的起始令牌号--

        for(i=0; i<512; i++)        //读512个数据
        {
                *buffer++ = SPI_SendByte(0xFF);
        }

        SPI_SendWreit(0xFF);        // 发送伪CRC
        SPI_SendWreit(0xFF);
        SDCS=1;                        // 关闭Card
        return 0;
}

//---------------------------------------------------
//        函数名:MMC_SD_WriteSingleBlock
//        功  能:写一个扇区
//        参  数:扇区,数据缓冲区
//        返回值:
//---------------------------------------------------

uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 *buffer)
{
        uint8 r1;
        uint16 i;

        SDCS=0;                // 使能Card

        r1 = MMC_SD_SendCmd(24, sector<<9);        //写命令
        if(r1 != 0x00)
                return r1;

        SPI_SendWreit(0xFF);
        SPI_SendWreit(0xFF);
        SPI_SendWreit(0xFF);

        SPI_SendWreit(0xFE);        //发送数据起始令牌号
         
        for(i=0; i<512; i++)        //以扇区为单位写入数据
        {
                SPI_SendWreit(*buffer++);
        }
         
        SPI_SendWreit(0xFF);        // 发送伪CRC
        SPI_SendWreit(0xFF);
         
        r1 = SPI_SendByte(0xFF);        // 读数据应答令牌号
         
        if( (r1&0x1F) != 0x05)        //等待是否成功
        {
                SDCS=1;
                return r1;
        }

        while(!SPI_SendByte(0xFF));         //--等待操作完成--

        SDCS=1;                        // 关闭Card

        return 0;
}

//---------------------------------------------------
//        函数名:MMC_SD_Init
//        功  能:sd卡初始化
//        参  数:无
//        返回值:uint8 type        // 卡类型返回值: 0x10 SD, 0x20 MMC
//---------------------------------------------------
此帖出自单片机论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

4
 

回复 板凳 的帖子

uint8 MMC_SD_init()
{
        uint8 i;
        uint8 retry;
        uint8 r1=0;
        uint8 type=0;        // 卡类型返回值:0xA0 SD 0xB0 MMC
        SDCS = 0;                // 使能Card

        SPI_speed=0x13;        //低速 SPI=300k   Fsystem=12Mhz
        retry = 0;

        do
        {
                for(i=0;i<10;i++) SPI_SendByte(0xFF);   //发送80个时钟,使卡同步
                r1 = MMC_SD_SendCmd(0, 0);        //发Cmd0(复位)命令
                retry++;
                if(retry > 30) return (type=0x01); //超时退出,个别卡需要更多次循环才有反应
        } while(r1 != 0x01);                // MMC、SD卡成功转到SPI模式

        retry = 0;

//****** SD卡在进入SPI模式后,激活命令和MMC卡一样为Cmd1,同时Cmd55+Cmd41 仍然有效******//

/*        do
        {
                r1 = MMC_SD_SendCmd(1, 0);        //发Cmd1(active激活)命令
                retry++;
                if(retry > 100) return 1;        //超时退出
        } while(r1);*/
        do
        {
                r1 = MMC_SD_SendCmd(55, 0);        // 先发送 Cmd55
                if(r1 == 0x01)                        // 如果有反应
                {
                        r1 = MMC_SD_SendCmd(41,0);        // 再发送 Cmd41 进行激活
                        if(r1 == 0x00) type = 0x10;        // 激活成功就是SD卡
                }

                else {                                   // 如果发送 Cmd55无反应,改发送 Cmd1
                                r1 = MMC_SD_SendCmd(1,0);
                                if(r1 == 0x00) type = 0x20;        // 激活成功就是MMC卡
                         }

                retry++;
                if(retry > 255) return (type=0x01);        // 超时退出, 个别卡需要更多次循环才有反应
        } while(r1 != 0x00);                // MMC、SD卡激活后的返回值均为0x00*/

//        SPI_SendByte(0xFF);        // 高速SPI前先发送8个时钟
//        SPI_speed = 0x07;        // 切换到高速 SPI

        r1 = MMC_SD_SendCmd(59, 0);        //关CRC
        r1 = MMC_SD_SendCmd(16, 512);        //设置读取一次的字节数

        SDCS = 1;                        // 关闭Card
//        SPI_speed=0x07;        //切换到高速 SPI

        return type;        //参数返回,1为初始化错误,10为SD卡,20为MMC卡
}

//-----------------------------------------------------------
//        End of File
//-----------------------------------------------------------
此帖出自单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 

回复 4楼 的帖子

希望楼主能贴个SD模式的操作程序。
此帖出自单片机论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

6
 

回复 5楼 的帖子

支持!


一直没有MMC卡,所以自己的程序没试过,虽然函数以 MMC_SD打头
此帖出自单片机论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

7
 

回复 6楼 的帖子

求教一下bozai ,在MP3播放时听起来感觉播放的很慢,播放时间比电脑上放的时间长,音调也不对劲。不知需要做些什么处理能改善此现象?你的SD卡读取速度大概是多少,我的MMC卡SCK时钟用示波器看了在1.3M左右,放128Kbps的MP3速度还行,放182K的就有点吃不消 了,感觉放出来的声音很卡,请教一下要注意些什么?
此帖出自单片机论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

8
 

回复 7楼 的帖子

我用AVR速度很快的,SCK速率要达到4M的(8MHz crystal), 这种情况有两种,一是VS1003的时钟频率不够,用4倍频最好。还有就是真的数据跟不上。  
你说声音卡,可能是数据没跟上。送的太慢。

C8051的速度可以到很高啊,不知道它的SPI最高可以达到多少
此帖出自单片机论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

9
 

SD卡底层驱动源程序公开------【注意】我的MP3开发板回来了

C8051F的SPI最大时钟是系统OSC的二分之一。
我现在比较晕的地方是怎样设置VS1003B的内核时钟倍频,说明书上看得一知半解的,看了几个程序的VS1003设置都不一样。
现在C8051F015的时钟是11.0592,分频比率是0x03,问题是MMC卡快不起来,太快就读不出了,SD卡比MMC卡的时钟频率还要低。
此帖出自单片机论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

10
 

回复 9楼 的帖子

哦,你找找我的程序是设多少,我用的是12.288的,其它的设就比较麻烦,要计算一下
此帖出自单片机论坛
 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(初级)

11
 

回复 10楼 的帖子

你的是C000,用的多的设置是9800,我把倍频设到最高F800,放MP3还是一样的慢。
还有就是SD卡的速度提不起来,一提高就读不出数据了,现在最大的问题就是这两个了,还得花时间研究。
忘了说我现在的播放程序没有文件系统支持,只是把卡里的扇区数做在了程序里,上电后直接去指定扇区位置读出来送VS1003的。
此帖出自单片机论坛
 
 
 

回复

720

帖子

0

TA的资源

纯净的硅(中级)

12
 
多谢喽……昨天刚写了一个SD驱动程序,一直没能实现功能,参考一下!
此帖出自单片机论坛
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

13
 
好东西,不错学习学习!!!
此帖出自单片机论坛
 
个人签名我的博客
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表