⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd卡单片机驱动程序.txt

📁 这是比较通用的单片机SPI读写SD卡的程序
💻 TXT
字号:
//--------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 
//---------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;        //返回状态值 
} 

//--------------------------------------------------- 
//        函数名: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 
//--------------------------------------------------- 

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 
//----------------------------------------------------------- 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -