實驗名稱:SD/MMC接口功能實現(xiàn)
實驗內(nèi)容:學(xué)習(xí)SD/MMC接口機制,并在ADSP-EDU-BF561開發(fā)板上實現(xiàn)SD/MMC卡讀寫功能
教學(xué)實驗平臺:ADSP-BF561EZ-KIT開發(fā)板,ADSP-EDU-BF561開發(fā)板,SD或MMC卡
實驗原理:
內(nèi)容:通過對ADSP-BF561處理器SPI端口編程對SD/MMC卡進行的讀寫。
原理:SD/MMC卡已成為數(shù)碼產(chǎn)品首選的存儲設(shè)備,其工作模式可以符合BF561 的SPI接口。通過 BF561的編程控制,實現(xiàn)對SD/MMC卡的讀寫。
硬件的實現(xiàn):
如圖1所示,BF561的SPI接口直接與SD卡座接口相連接,SPI接口的片選接口與PF接口復(fù)用,為節(jié)省PF接口資源,在硬件設(shè)計時,采用PF2口作為SPI接口片選,通過CPLD做切換開關(guān),來選擇SPI接口設(shè)備。SD卡共有9個引腳,在硬件設(shè)計時,為了能檢測到SD卡是否插入,根據(jù)SD卡座增加了兩個個卡插入識別引腳。通過訪問CPLD的寄存器,可以訪問到這個引腳的狀態(tài)。
SD卡有兩種工作模式:SDIO模式和SPI模式。SDIO模式為半字節(jié)讀寫模式,其特點是有四根數(shù)據(jù)線,每次可對半個字節(jié)作操作,其速度相對快點。SPI模式有4根控制線:MOSI,MISO,SPICLK,SPISS。因為每次只能對一位數(shù)據(jù)作操作,其速度相對慢點。BF561的SPI接口最快可達到系統(tǒng)始終的1/4,按系統(tǒng)時鐘為118.8M/S計算,SPI的最快可達到29.7M/S。
SD/MMC卡尋址方式:
SD/MMC卡的尋址方式是按字節(jié)尋址的,為方便使用,將其尋址方式定義成連續(xù)的存儲單元尋址方式。類似于IDE的邏輯扇區(qū)尋址,NAND FLASH的頁尋址。每個存儲單元為512個字節(jié)。每個存儲單元編號唯一,為連續(xù)遞增的編號。
CPLD:
CPLD為SD/MMC卡配置了選通SPI片選的接口地址,選通一個SPI接口器件,須配置pCtrIner_Flag_OE寄存器,使能SPI,然后配置pCtrOut_Flag_B寄存器,選擇SPI器件。
pCtrIner_Flag_OE 位定義表(0x2C06000):
D0 |
D1 |
D2 |
D3 |
D4 |
D5 |
D6 |
D7 |
MOUSE_SW_OE |
EY_SW_OE |
LEDCS |
SPI_OE |
PCM_MEM |
PCM_IO |
保留 |
保留 |
MOUSE_SW_OE:0x01
KEY_SW_OE: 0x02
LEDCS: 0x04
SPI_OE: 0x08
以上為內(nèi)部控制片選允許,低有效
對pCtrOut_Flag地址某位寫0,將該位置0,使能外部器件;對pCtrOut_Flag地址某位寫1,將該位置1,關(guān)斷外部器件。
pCtrOut_Flag_B 位定義表(0x2C08000):
D0 |
D1 |
D2 |
D3 |
D4 |
D5 |
D6 |
D7 |
SPI_A0 |
SPI_A1 |
SPI_A2 |
保留 |
LED_A0 |
LED_A1 |
CMOSCLK_SET |
TFTCLK_SET |
對應(yīng)位寫0,將該位置0
對應(yīng)位寫1,將該位置1
通過配置pCtrOut_Flag_B寄存器的D0-D2,可以選通不同的SPI接口設(shè)備,SD卡的配置地址為:
SPI_OE |
SPI_A2 |
SPI_A1 |
SPI_A0 |
BF561_SPISS |
說明 |
0 |
0 |
1 |
0 |
SD_SPISS |
使能SD片選 |
由此可以看出,選通SD卡,需:
配置pCtrIner_Flag_OE位定義表(0x2C06000)寄存器的D3=0,使能SPI端口。
配置pCtrOut_Flag_B位定義表(0x2C08000)寄存器的D0=0,D1=1,D2=0,選通SD/MMC卡接口。
實例分析(核心代碼分析)
SPI_TransferByte(unsigned char value) //SPI數(shù)據(jù)傳輸函數(shù)
{
uchar incoming=0;
while(!(*pSPI_STAT & SPIF)); //判斷是否可以傳輸數(shù)據(jù)
*pSPI_TDBR = value; //將數(shù)據(jù)傳輸
while(*pSPI_STAT & RXS) //判斷是否可以接受數(shù)據(jù)
incoming = *pSPI_RDBR; //讀取數(shù)據(jù)
return(incoming); //將讀到的數(shù)據(jù)返回
}
uchar MMC_Init(void) //初始化函數(shù)
{
uchar retry,temp;
uchar i;
for (i=0;i<10;i++)
{
SPI_TransferByte(0xff); //send 74 clock at least!!! //發(fā)送0xff
}
SPI_TransferByte(MMC_RESET); //復(fù)位
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x00);
SPI_TransferByte(0x95);
SPI_TransferByte(0xff);
SPI_TransferByte(0xff);
retry=0;
do{
temp=Write_Command_MMC(MMC_INIT,0) //送入初始化命令,讀取返回值;
retry++;
if(retry==1000) //循環(huán)檢測返回值
{
printf("MMC_INIT is ERROR!\n "); //初始化失敗
return(INIT_CMD1_ERROR);
}
}while(temp!=0);
printf("MMC_INIT is OK!\n"); //初始化完成
return (1);
}
uchar MMC_read_sector(ulong sector,uchar *Buffer) //讀卡函數(shù)
{
uchar temp;
uint i;
SPI_TransferByte(0xff); 將傳輸數(shù)據(jù)線置1
temp = Write_Command_MMC(MMC_READ_BLOCK,sector<<9); //將地址送入,讀取返回值
if(temp != 0x00) //判斷是否出錯
{
return(READ_BLOCK_ERROR);
}
while(SPI_TransferByte(0xff) != 0xfe);
for(i=0;i<512;i++) //讀取數(shù)據(jù)
{
*Buffer++ = SPI_TransferByte(0xff);
}
SPI_TransferByte(0xff); //將傳輸數(shù)據(jù)線置高
SPI_TransferByte(0xff);
return (1); //返回1
}
unsigned char MMC_Write_sector(ulong sector, uchar *Buffer) //寫卡函數(shù)
{
unsigned int i,flag;
unsigned char *p, by;
unsigned long startadr;
p=Buffer;
startadr=sector * (unsigned long)BYTE_PER_SEC; //計算地址
Write_Command_MMC (MMC_WRITE_BLOCK,startadr); //送入地址
SPI_TransferByte(0xFF); //將傳輸數(shù)據(jù)線置1
SPI_TransferByte(0xFF);
SPI_TransferByte(0xFE);
for(i=0; i<BYTE_PER_SEC; i++) //讀取數(shù)據(jù)
{
SPI_TransferByte(*p++);
}
SPI_TransferByte(0xFF); //將傳輸數(shù)據(jù)線置1
SPI_TransferByte(0xFF);
do
{
flag = SPI_TransferByte(0xFF); //讀取標(biāo)志
by=flag & 0x1F;
}
while(by != 0x05); //讀取標(biāo)志
do
{
flag = SPI_TransferByte(0xFF);
}while(flag !=0xFF);
return 0; //返回0
}
實驗結(jié)果:
運行程序后,得到的打印結(jié)果,SD卡自檢。
待提示測試結(jié)束后,停止運行程序,對比Blackfin Memory窗口觀察buff_t和buff_r的數(shù)據(jù),寫入與讀取的數(shù)據(jù)相同。
|