SD卡读写包括两种模式Word文件下载.docx
《SD卡读写包括两种模式Word文件下载.docx》由会员分享,可在线阅读,更多相关《SD卡读写包括两种模式Word文件下载.docx(37页珍藏版)》请在冰点文库上搜索。
wtent
//写数据计数器
block;
//读写块总数
TR_end=0;
Wide=0;
//0:
1bit,1:
4bitintMMC0;
SD,1:
MMC
intMaker_ID;
charProduet_Name[7];
intSerial_Num;
volatileintRCA
voidTest_SDI(void)
{
U32save_rGPEUPsave_rGPECON
RCA=0;
MMC=O;
block=3072;
〃3072Blocks=1.5MByte,
((2Block=1024Byte)*1024Block=1MByte)
save_rGPEUP=rGPEUP
save_rGPECONrGPECON
//**配置SD/MM控制器
rGPEUP=0xf83f;
//SDCMD,SDDAT[3:
0]=>
PUEn.
rGPECON=0xaaaaaaaa;
//SDCMD,SDDAT[3:
0]
Uart_Printf("
\nSDICardWriteandReadTest\n"
);
if(!
SD_card」nit())//等待SD卡初始化完成
return;
TR_Buf_new();
//发送数据缓冲区初始化
Wt_Block();
//写卡
Rd_Block();
//读卡
View_Rx_buf();
if(MMC
TR_Buf_new[);
rSDICON|=(1<
5);
//YH0519,MMCTypeSDCLK
Wt_Stream();
Rd_Stream();
}
Card_sel_desel(0);
//Carddeselect
CMD9)
GetCSDfail!
!
\n"
rSDIDCON=0;
//tark?
?
rSDICSTA=0xffff;
rGPEUP=save_rGPEUP
rGPECO=bave_rGPECON
voidTR_Buf_new(void)//发送数据缓冲区初始化
//--Tx&
RxBufferinitialize
inti,j;
Tx_buffer=(unsignedint*)0x31000000;
j=0;
for(i=0;
i<
2048;
i++)〃128[word]*16[blk]=8192[byte]
*(Tx_buffer+i)=i+j;
Flush_Rx_buf();
voidFlush_Rx_buf(void)//接收数据缓冲区清0
//--FlushingRxbuffer
inti;
Rx_buffer=(unsignedint*)0x31800000;
*(Rx_buffer+i)=0;
EndRxbufferflush'
n"
voidView_Rx_buf()
//--DisplayRxbuffer
inti,error=0;
CheckRxdata\n"
);
128*block;
i++)
if(Rx_buffer[i]!
=Tx_buffer[i])
\nTx/Rxerror\n"
Uart_Printf("
%d:
Tx-0x%08x,Rx-0x%08x\n"
i,Tx_buffer[i],Rx_buffer[i]);
error=1;
break;
error)
\nTheTx_bufferissametoRx_buffer!
SDCARDWriteandReadtestisOK!
voidView_Tx_buf(void)
intSD_card_init(void)//SD卡初始化
//--SDcontroller&
cardinitialize
/*ImportantnoticeforMMCtestcondition*/
/*Cmd&
Datalinesmustbeenabledbypullupresister*/
rSDIPRE=PCLK(INICLK)-1;
//400KHz
Init.Frequencyis%dHz\n"
(PCLK;
rSDIPREH)));
rSDICON=(1<
4)|1;
//先传高位,再传低位,使能CLK
rSDIFSTA=rSDIFSTA|(1<
16);
//SDIFIFOstatusregister,FIFO复位
rSDIBSIZE=0x200;
//SDIblocksizeregister,设置每块大小为
512byte(128word)
rSDIDTIMER=0x7fffff;
//SDIdata/busytimerregister,设置超时
周期
0x1000;
i++);
//延时,CARD!
身初始化需要74个CLK
CMD0();
//发送CMD0
Inidle\n"
//--CheckMMCcardOCR
if(Chk_MMC_OCR
InMMCready\n"
MMC1;
gotoRECMD2
MMCcheckend!
//--CheckSDcardOCR
if(Chk_SD_OCR
InSDready\n"
else
Initializefail'
nNoCardassertion\n"
return0;
RECMD2
//检查连接的卡,识别卡的状态
rSDICARG=0x0;
//CMD2(stuffbit)rSDICCON(0x1«
10)|(0x1<
9)|(0x1<
8)|0x42;
//CMD2为长应答并等待应答
开始发
//送CMD2命令卡发回CID寄存器(保存了生产厂家/时间/批号等等),产生
RSP2
//检查CMD是否成功发送并收到响应
Chk_CMDen(2,1))
gotoRECMD2//CMD2出错,重新发送
rSDICSTA=0xa00;
//清除命令和应答结束标志位
Endid\n"
RECMD3
//--发送CMD3给卡分配RCA,
rSDICARG=MMC<
16;
//CMD3参数,MMC设置RCA,SD:
请求发RCArSDICCON(0x1<
8)|0x43;
//CMD3为短应答并等待应答,开始发//送CMD3,MMC设置RCA产生RSP1,SD(设置RCA产生RSP6
Chk_CMDen((3,1))
gotoRECMD3//CMD3出错,重新发送
rSDICSTA=OxaOO;
//--PublishRCA
if(MMC{
RCA=1;
rSDIPRE=(PCLKMMCCLK1;
MMCFrequencyis%dHz\n"
(PCLK(rSDIPREM)));
RCA=(rSDIRSP0&
0xffff0000)>
>
//回读RCA卡被分配RCAf进入
//TransferMODE,准备读写
RCA=0x%x\n"
RCA;
rSDIPRE=PCLK(SDCLK1;
//Normalclock=25MHz
SDFrequencyis%dHz\n"
}〃--State(stand-by)check
//根据SD规范,rSDIRSP0高16位存储RCA低16位存储CARD勺状态
if(rSDIRSP0&
0x1e00!
=0x600)//检查CARD^态,不是处于stand-by
状态
gotoRECMD3////未就绪,重新发送CMD3
UartPrintf("
Instand-by\n"
Card_sel_desel
(1);
//Select
MMC〃若位SD卡,设置4bit的数据传输模式
Set_4bit_bus();
else//若位MMC卡设置1bit的数据传输模式
Set_1bit_bus();
return1;
voidCard_sel_desel(charsel_desel)
//--Cardselectordeselect
if(sel_desel)//选择该卡
RECMDS7//送CMD7表示选择该卡,准备读写,产生RSP1.
rSDICARG=RCA<
//CMD7参数(RCA,stuffbit),其中高16位为RCArSDICCON=(0x1<
8)|0x47;
//CMD7为短应答并等待应答,开始发//送CMD选择该卡,准备读写,产生RSP1
ChkCMDer((7,1))
gotoRECMDS7//出错,重新发送
rSDICSTA=0xa00;
//检查是否处于transfermode
=0x800)
gotoRECMDS7//不处于transfermode,重新发送CMD7
else//卸载该卡
RECMDD7
rSDICARG=0<
//CMD7参数(RCA,stuffbit),其中高16位为RCArSDICCON=(0x1«
//无应答并,并开始发送CMD7
//检查CMD是否成功
Chk_CMDer((7,0))
gotoRECMDD7//失败,重新卸载
rSDICSTA=0x800;
////清除命令结束标志位
void__irqRd_Int(void)//读中断函数
U32i,status;
status=rSDIFSTA
if((status&
0x200)==0x200)//检查接收FIFO最后是否有数据到来
for(i=(status&
0x7f)/4;
i>
0;
i--)
*Rx_buffer++=rSDIDAT
rd_cnt++;
rSDIFSTA=rSDIFSTA&
)x200;
//清RxFIFOLastdataReady标志位
elseif((status&
0x80)==0x80)//检查HalfFULLinterrupt标志,
只要大于31个字节,就会将该标志置1
8;
*Rx_buffer++=rSDIDAT
ClearPending(BIT_SDI);
//清零源中断挂起寄存器和中断挂起寄存器
}void__irqWt_Int(void)//写中断函数
rSDIDAT=*Tx_buffer++;
wt_cnt++;
if(wt_cnt==128*block)
rINTMSK|=BIT_SDI;
//屏蔽BIT_SDI中断
rSDIDAT=*Tx_buffer;
TR_end=1;
void__irqDMA_end(void)
ClearPending(BIT_DMA0//清零源中断挂起寄存器和中断挂起寄存器
TR_end=1;
voidRd_Block(void)
U32mode;
intstatus;
rd_cnt=0;
Blockreadtest[Pollingread]\n"
mode=0;
rSDIFSTA=rSDIFSTA(1<
//复位FIFO
if(mode!
=2)
rSDIDCON=(2<
22)|(1<
19)|(1<
17)|(Wide<
16)|(1<
14)|(2<
12)|(block<
0);
//YH040220
//设置数据控制寄存器:
字传输,块数据传输,4bit数据传输,开始数据传输,数据发送模〃式,共读block个块
//CMD17/18地址参数
RERDCMD
switch(mode
casePOL:
if(block<
2)//SINGLE_READ写单块
rSDICCON=(0x1<
8)|0x51;
//CMD17为短应答并等待应答,开始发
//送CMD1单块读命令,开始读,产生RSP1
Chk_CMDend7,1))//--CheckendofCMD17
gotoRERDCMD//失败,继续发送
else//MULTI_READ,读多块
rSDICCON=(Ox1«
8)|0x52;
//CMD18为短应答并等待应答,开始发
//送CMD1多块读命令,开始读,产生RSP1
Chk_CMDend8,1))//--CheckendofCMD18
//清命令和应答结束标志
while(rd_cnt<
128*block)//512块个字节
if((rSDIDSTA0x20)==0x20)//是否超时
rSDIDSTA=(0x1<
0x5);
//清超时标志位
if((status&
0x1000)==0x1000)//FIFO非空
caseINT:
plSR_SDI=(unsigned)Rd」nt;
rINTMSK=~(BIT_SDI);
//屏蔽除所有其他中断
rSDIIMSK=5;
//开启Last&
RxFIFOhalf中断.
2)//SINGLE_READ
Chk_CMDer(d7,1))//--CheckendofCMD17
else//MULTI_READ
//CMD18为短应答并等待应答,开始发
ChkCMDer(d8,1))//--CheckendofCMD18
128*block);
rINTMSK
|=(BIT_SDI);
//屏蔽BIT_SDI中断
rSDIIMSK
=0;
//屏蔽所有中断
caseDMA
pISR_DMA0=(unsigned)DMA_end
=~(BIT_DMA0
rSDIDCON=rSDIDCON1<
24);
//YH040227,Burst4Enable
rDISRC0
=(int)(SDIDAT;
//SDIDAT
rDISRCC0
=(1<
1)+(1<
//APB,fix
rDIDST0
=(U32)(Rx_buffer);
//Rx_buffer
rDIDSTC0
=(0<
1)+(0<
//AHB,inc
rDCON0=(1<
31)+(0<
30)+(1<
29)+(0<
28)+(0<
27)+(2<
24)+(1<
23)
+(1<
22)+(2<
20)+128*block;
rDMASKTRIG0=(0<
2)+(1<
1)+0;
//no-stop,DMA2channelon,no-sw
trigger
rSDIDCON=(2<
15)|(<
rSDICCON=(0x1<
//sht_resp,wait_resp,
CMD17
gotoRERDCM|D
CMD18
Chk_CMDer(d8,1))//--CheckendofCMD18
gotoRERDCMD
//Clearcmd_end(withrsp)
while(!
TR_end;
1<
14)|(2
dat,start,
〃Uart_Printf("
rSDIFSTA=0x%x\n"
rSDIFSTA);
rINTMSK|=(BIT_DMA0
TR_end=0;
rDMASKTRIGO=(1<
2);
//DMA0stop
default:
//--CheckendofDATA
Chk_DATenQ)
daterror'
rSDIDCON=rSDIDCO&
~(7<
12);
0x200;
//ClearRxFIFOLastdataReady,YH040221rSDIDSTA=0x10;
//CleardataTx/Rxenddetect
if(block>
1)
RERCMD12
//--S