<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
https://static.assets-stash.eet-china.com/album/old-resources/2009/11/16/48a25ccc-b857-4943-bd8d-c031fbd098c1.rar 用于智林STM32开发板一、概述
经过两天的修改、调试,SD卡的读写程序已经可以正常工作了(擦除还不好用,原因未知),获取容量的函数也工作正常,基本用于文件系统移植的底层函数都准备完成了。现在来做一个简单的总结。
二、程序框架分析
1、串口命令
该程序建立在简单串口命令界面上实现,对于SD卡的操作实现了两个命令:sdrd和sdwr。比如在串口输入命令sdrd后,通过命令处理函数调用函数void UartCmdSDRead(void)。
2、命令处理函数
在void UartCmdSDRead(void)中,首先对SD进行配置:调用SD_Config()函数。主要工作是复位、激活、设置块长度512、禁止CRC和设置SPI高速。
然后调用SD_GetCardInfo( &SDCardInfo )得到卡的块数量、块长度和容量,并在串口中断显示。
接着调用函数SD_ReadMultiBlock( BlockIndex,2,SDReadBuf )将开始两个块的数据共1024个字节读取到缓冲区,然后转变为十六进制字符串,在串口终端显示。
3、SD卡用户层
共实现7个函数:
u8 SD_Config( void );
u8 SD_GetCardInfo( CardInfo * CardInfoPtr );
u8 SD_ReadBlock( u32 BlockIndex, u8* ReadBuf );
u8 SD_WriteBlock( u32 BlockIndex, u8* WriteBuf );
u8 SD_EraseBlock( u32 BlockIndex, u32 BlockNum );
u8 SD_WriteMultiBlock( u32 BlockIndex,u32 BlockNum, u8* WriteBuf );
u8 SD_ReadMultiBlock( u32 BlockIndex,u32 BlockNum, u8* ReadBuf );
各个函数的意义就在函数名称中,而各个函数的实现依据SD卡操作时序而来。比如其中SD_ReadMultiBlock函数的实现:
u8 SD_WriteMultiBlock( u32 BlockIndex,u32 BlockNum, u8* WriteBuf ){
u16 i,j;
u8 TmpByte; //发写单块命令24
BlockIndex <<=9;
if ( BlockNum ==0 )return 1;
if ( SD_CmdWriteMulti( BlockIndex ) )
{ SD_CSDisable( ); SPI_PutByte( 0xFF ); return 1; }
for ( j="0"; j<BlockNum; j++ )
{
SPI_PutByte ( 0xFC ); //多块数据起始令牌
for ( i="0"; i<BlockLen; i++ )
SPI_PutByte( WriteBuf); //写入SD卡缓冲区
SPI_PutByte( 0xEE );
SPI_PutByte ( 0xEE ); //CRC校验,这里不使用
TmpByte =SPI_GetByte( ); //获取数据响应
if ( TmpByte&0x05 !=0x05 )
{ SD_CSDisable( ); SPI_PutByte( 0xFF ); return 1; }
SD_WaitInBusy( ); //SD忙时,一直等待。
WriteBuf +=BlockLen; //缓冲区移动512字节
}
if ( SD_CmdStopTransmit( ) ) //发出停止传输命令
{ SD_CSDisable( ); SPI_PutByte( 0xFF ); return 1; }
SD_WaitInBusy( ); //SD忙时,一直等待。
SD_CSEnable( );
SPI_PutByte( 0xFF );
return 0;
}
4、SD卡命令层
主要是函数u8 SD_SendCmd()的实现,然后将一些基本操作封装起来。
比如:u8 SD_Reset( void);
u8 SD_Activate( void);
u8 SD_SetBlockLen( u16 BlockSize );
u8 SD_DisableCRC( void );
u8 SD_CmdGetCSD( void );
u8 SD_CmdReadSingle( u32 BlockIndex );
u8 SD_CmdWriteSingle( u32 BlockIndex );
void SD_WaitInBusy(void ); 等等。这些函数基本工作是调用命令发送函数来完成。
如u8 SD_Reset( void ){
u8 Reply;
Reply =SD_SendCmd ( CmdReset, 0, 0x95 ) ;
if ( Reply != 0x01 )return 1;
SD_CSDisable( );
SPI_PutByte( 0xFF );
return 0;
}
5、底层操作:
void SD_CSEnable( void );
void SD_CSDisable( void );
void SPI_HighSpeed( void );
u8 SPI_GetByte( void );
void SPI_PutByte( u8 SendByte);
包括SD卡选择操作、SPI的发送和接收操作,SPI高速设置操作。
三、实现结果演示。
先执行sdrd,显示如下所示,第一个扇区结束有55 AA字符。
然后执行sdwr,这个命令在第一扇区全部写入0x11,第二个扇区写入0x22,这是执行后的结果。读取第1扇区,显示全部为11.
文章评论(0条评论)
登录后参与讨论