微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > s3c2440的SD/MMC的应用

s3c2440的SD/MMC的应用

时间:11-19 来源:互联网 点击:
总线宽,而系统默认就是1位总线宽,所以在这里无需改动数据总线宽度

//为数据的读写,准备缓存数组
Tx_buffer=(unsigned int *)0x31000000;//发送数组
for(i=0;i<2048;i++)//512(一块数据的字节数)×16(数据块)=2048×4
*(Tx_buffer+i)=2*i+1;//写值

Rx_buffer=(unsigned int *)0x31800000;//接收数组
for(i=0;i<2048;i++)
*(Rx_buffer+i)=0;//清零

//写数据,查询方式
rSDIFSTA |= 1<16;//FIFO复位

rSDIDCON=(2<22)|(1<20)|(1<17)|(1<14)|(3<12)|(block<0);//字、块发送
rSDICARG=0;//写入MMC的内存首地址

//CMD25WRITE_MULTIPLE_BLOCK,多块写入命令
while(flag)
{
rSDICCON=(0x1<9)|(0x1<8)|0x59;

tempSta=rSDICSTA;
while( !( ((tempSta&0x200)==0x200) | ((tempSta&0x400)==0x400) ))
tempSta=rSDICSTA;

if( (tempSta&0x1f00) == 0xa00 )
{
rSDICSTA=0xa00;
break;
}
rSDICSTA=0xF<9;
}

//写入MMC内存数据
i=0;
while(i<128*block)
{
//检查FIFO状态
tempSta=rSDIFSTA;
if((tempSta&0x2000)==0x2000)//FIFO没有满
{
rSDIDAT=*Tx_buffer++;
i++;
}
}

//判断数据是否发送正确
//检查数据状态
tempSta=rSDIDSTA;
while( !( ((tempSta&0x10)==0x10) | ((tempSta&0x20)==0x20) ))
tempSta=rSDIDSTA;//判断数据传输是否结束或超时

if( (tempSta&0xfc) != 0x10 )//数据传输没有结束
{
rSDIDSTA=0xec;//清状态
while(!(rUTRSTAT0 & 0x2));
rUTXH0=0x88;//向UART0发送一个信息,表示SDI的某种错误
flag=0;//清标志,结束SDI的传输
}

if(flag)
{
rSDIDCON=rSDIDCON&~(7<12);//清数据传输
rSDIDSTA=0x10;
}

//CMD12STOP_TRANSMISSION,结束传输,回到传输状态
while(flag)
{
rSDIDCON=(1<18)|(1<17)|(0<16)|(1<14)|(1<12)|(block<0);//忙检查
rSDICARG=0x0;//CMD12无参数
rSDICCON=(0x1<9)|(0x1<8)|0x4c;

tempSta=rSDICSTA;
while( !( ((tempSta&0x200)==0x200) | ((tempSta&0x400)==0x400) ))
tempSta=rSDICSTA;

if( (tempSta&0x1f00) == 0xa00 )
{
rSDICSTA=0xa00;
break;
}
rSDICSTA=0xF<9;
}

//检查是否忙
if(flag)
{
tempSta=rSDIDSTA;
while( !( ((tempSta&0x08)==0x08) | ((tempSta&0x20)==0x20) ))
tempSta=rSDIDSTA;

if( (tempSta&0xfc) != 0x08 )//数据传输不是正确结束
{
flag=0;//清标志,结束SDI传输
}
rSDIDSTA=0xf4;
}

//读取MMC内存数据
if(flag)
{
rSDIFSTA|=(1<16);//FIFO复位
rSDIDCON=(2<22)|(1<19)|(1<17)|(1<14)|(2<12)|(block<0);//字、块接收
rSDICARG=0;//设置读取MMC的内存首地址,要与写入时的首地址一致
}

//CMD18READ_MULTIPLE_BLOCK,多块读命令
while(flag)
{
rSDICCON=(0x1<9)|(0x1<8)|0x52;

tempSta=rSDICSTA;
while( !( ((tempSta&0x200)==0x200) | ((tempSta&0x400)==0x400) ))
tempSta=rSDICSTA;

if( (tempSta&0x1f00) == 0xa00 )
{
rSDICSTA=0xa00;
break;
}
rSDICSTA=0xF<9;//clear all
}

if(flag)
{
i=0;
//读MMC内存
while(i<128*block)
{
if((rSDIDSTA&0x20)==0x20)//判断是否超时
{
rSDIDSTA=(0x1<0x5);//清状态
flag=0;//清标志,退出
break;
}
tempSta=rSDIFSTA;
if((tempSta&0x1000)==0x1000)//检查FIFO是否为空
{
*Rx_buffer++=rSDIDAT;
i++;
}
}

rSDIDCON=rSDIDCON&~(7<12);//清数据传输
rSDIFSTA &= 0x200;//清FIFO
rSDIDSTA=0x10;//清数据状态
}

//CMD12STOP_TRANSMISSION,结束传输,回到传输状态
while(flag)
{
rSDICARG=0x0;
rSDICCON=(0x1<9)|(0x1<8)|0x4c;

tempSta=rSDICSTA;
while( !( ((tempSta&0x200)==0x200) | ((tempSta&0x400)==0x400) ))
tempSta=rSDICSTA;

if( (tempSta&0x1f00) == 0xa00 )
{
rSDICSTA=0xa00;
break;
}
rSDICSTA=0xF<9;//clear all
}

if(flag)
{
//比较两个数组的内容
Tx_buffer=(unsigned int *)0x31000000;
Rx_buffer=(unsigned int *)0x31800000;

for(i=0;i<128*block;i++)
{
if(Rx_buffer[i] != Tx_buffer[i])//有不相等的情况
{
while(!(rUTRSTAT0 & 0x2));
rUTXH0=0x44;//向UART0发送一个信息,表示SDI的某种错误
break;
}
}
}

//CMD7SELECT/DESELECT_CARD,把当前状态从传输状态变为待机状态
while(flag)
{
rSDICARG=0<16;//不带参数
rSDICCON= (0x1<8)|0x47;//无回复

tempSta=rSDICSTA;
if( (tempSta&0x800) != 0x800 )
{
rSDICSTA=0xa00;
break;
}
rSDICSTA=0xF<9;
}

rSDICSTA=0x800;//结束SD
rSDIDCON=0;
rSDICSTA=0xffff;

if(flag)
rGPBDAT = ~0x60;//SD数据传输正确,亮2个LED
else
rGPBDAT =~0xe0;//SD数据传输失败,亮3个LED
}

while(1)
;
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top