?? sd卡單片機(jī)驅(qū)動程序.txt
字號:
//--------SD_MMC.H------------------------
#ifndef __SD_MMC_H__
#define __SD_MMC_H__
// 數(shù)據(jù)宏定義
#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發(fā)送
uint8 SPI_SendByte(uint8 val); // SPI傳送一個字節(jié)
uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg); //發(fā)送卡命令
uint8 MMC_SD_ReadSingleBlock(uint32 sector, uint8 *buffer); //讀一個扇區(qū)
uint8 MMC_SD_WriteSingleBlock(uint32 sector, uint8 *buffer); //寫一個扇區(qū)
uint8 MMC_SD_init(); //mmc_sd卡初始化
#endif
//---------SD_MMC.C-----------------
//---------------------------------------------------------
// SD_MMC 底層驅(qū)動函數(shù)庫
// 編譯環(huán)境:Keil C V2.40
// 編寫日期:2008-04-07
// 最后更新:2008-05-04
//---------------------------------------------------------
#include "main.h"
#include "sd_mmc.h"
//---------------------------------------------------
// 函數(shù)名:SPI_SendByte
// 功 能:SPI 數(shù)據(jù)發(fā)送
// 參 數(shù):uchar
// 返回值:
//---------------------------------------------------
void SPI_SendWreit(uchar temp)
{
SPI0DAT=temp;
while(TXBSY); // 查詢發(fā)送標(biāo)志位
}
//---------------------------------------------------
// 函數(shù)名:SPI_SendByte
// 功 能:SPI傳送一個字節(jié)
// 參 數(shù):uchar
// 返回值:uchar
//---------------------------------------------------
uint8 SPI_SendByte(uint8 val) // uint8= uchar
{
SPI0DAT = val;
while(TXBSY);
return SPI0DAT;
}
//---------------------------------------------------
// 函數(shù)名:MMC_SD_SendCmd
// 功 能:發(fā)送卡命令
// 參 數(shù):uint8,uint32
// 返回值:uint8
//---------------------------------------------------
uint8 MMC_SD_SendCmd(uint8 Cmd, uint32 arg)
{
uint8 r1;
uint8 retry=0;
SPI_SendWreit(0xFF); //發(fā)命令前先發(fā)送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) //等待響應(yīng)
if(retry++ > 8) break; //超時退出
return r1; //返回狀態(tài)值
}
//---------------------------------------------------
// 函數(shù)名:MMC_SD_ReadSingleBlock
// 功 能:讀一個扇區(qū)
// 參 數(shù):扇區(qū),數(shù)據(jù)緩沖區(qū)
// 返回值:
//---------------------------------------------------
uint8 MMC_SD_ReadSingleBlock(uint32 sector,uint8 *buffer)
{
uint8 r1;
uint16 i;
SDCS=0; // 使能Card
r1 = MMC_SD_SendCmd(17, sector<<9); // 發(fā)讀扇區(qū)命令
if(r1 != 0x00) return r1;
while(SPI_SendByte(0xFF) != 0xFE); //--等待數(shù)據(jù)的起始令牌號--
for(i=0; i<512; i++) //讀512個數(shù)據(jù)
{
*buffer++ = SPI_SendByte(0xFF);
}
SPI_SendWreit(0xFF); // 發(fā)送偽CRC
SPI_SendWreit(0xFF);
SDCS=1; // 關(guān)閉Card
return 0;
}
//---------------------------------------------------
// 函數(shù)名:MMC_SD_WriteSingleBlock
// 功 能:寫一個扇區(qū)
// 參 數(shù):扇區(qū),數(shù)據(jù)緩沖區(qū)
// 返回值:
//---------------------------------------------------
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); //發(fā)送數(shù)據(jù)起始令牌號
for(i=0; i<512; i++) //以扇區(qū)為單位寫入數(shù)據(jù)
{
SPI_SendWreit(*buffer++);
}
SPI_SendWreit(0xFF); // 發(fā)送偽CRC
SPI_SendWreit(0xFF);
r1 = SPI_SendByte(0xFF); // 讀數(shù)據(jù)應(yīng)答令牌號
if( (r1&0x1F) != 0x05) //等待是否成功
{
SDCS=1;
return r1;
}
while(!SPI_SendByte(0xFF)); //--等待操作完成--
SDCS=1; // 關(guān)閉Card
return 0;
}
//---------------------------------------------------
// 函數(shù)名:MMC_SD_Init
// 功 能:sd卡初始化
// 參 數(shù):無
// 返回值: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); //發(fā)送80個時鐘,使卡同步
r1 = MMC_SD_SendCmd(0, 0); //發(fā)Cmd0(復(fù)位)命令
retry++;
if(retry > 30) return (type=0x01); //超時退出,個別卡需要更多次循環(huán)才有反應(yīng)
} while(r1 != 0x01); // MMC、SD卡成功轉(zhuǎn)到SPI模式
retry = 0;
//****** SD卡在進(jìn)入SPI模式后,激活命令和MMC卡一樣為Cmd1,同時Cmd55+Cmd41 仍然有效******//
/* do
{
r1 = MMC_SD_SendCmd(1, 0); //發(fā)Cmd1(active激活)命令
retry++;
if(retry > 100) return 1; //超時退出
} while(r1);*/
do
{
r1 = MMC_SD_SendCmd(55, 0); // 先發(fā)送 Cmd55
if(r1 == 0x01) // 如果有反應(yīng)
{
r1 = MMC_SD_SendCmd(41,0); // 再發(fā)送 Cmd41 進(jìn)行激活
if(r1 == 0x00) type = 0x10; // 激活成功就是SD卡
}
else { // 如果發(fā)送 Cmd55無反應(yīng),改發(fā)送 Cmd1
r1 = MMC_SD_SendCmd(1,0);
if(r1 == 0x00) type = 0x20; // 激活成功就是MMC卡
}
retry++;
if(retry > 255) return (type=0x01); // 超時退出, 個別卡需要更多次循環(huán)才有反應(yīng)
} while(r1 != 0x00); // MMC、SD卡激活后的返回值均為0x00*/
// SPI_SendByte(0xFF); // 高速SPI前先發(fā)送8個時鐘
// SPI_speed = 0x07; // 切換到高速 SPI
r1 = MMC_SD_SendCmd(59, 0); //關(guān)CRC
r1 = MMC_SD_SendCmd(16, 512); //設(shè)置讀取一次的字節(jié)數(shù)
SDCS = 1; // 關(guān)閉Card
// SPI_speed=0x07; //切換到高速 SPI
return type; //參數(shù)返回,1為初始化錯誤,10為SD卡,20為MMC卡
}
//-----------------------------------------------------------
// End of File
//-----------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -