一、参考其他能正确运行的程序
1.准备工作
虽然对使用SPI通信协议读写SD卡的过程有了一些了解,但对于有些关键的细节并不是很熟悉,而这些可能是影响系统工作的关键,所以有必要先读一些能正确运行的程序,可惜智林STM32光盘上SD卡操作的程序三个中,只有一个能够运行,智能判断出SD卡操作硬件和软件都没有问题,而这个偏偏是没有源代码的。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
2、有关SPI接受和发送
u8 SPI_GetByte( void ){ //每次要收取数据时,先要发送一个字节,主要是输出时钟
while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) == RESET );
SPI_I2S_SendData( SPI1, 0xFF ) ;
while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) == RESET );
return ( SPI_I2S_ReceiveData( SPI1 ) );
}
//每次发送数据时,收到的数据没有用的话要舍弃,但是要清除RXNE位。
void SPI_PutByte( u8 SendByte ){
while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) == RESET );
SPI_I2S_SendData( SPI1, SendByte ) ;
while( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) == RESET );
SPI_I2S_ReceiveData( SPI1 ) ;
}
3、有关SPI设置
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //空闲时为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在先
4、时序问题
(1)SD卡上电后,先要延时一段时间,等待上电处理完成。
上电完成后,可以发送复位命令0,根据发送模式,SD卡进入相应的模式,这里要检测返回值是不是01,来判断是否成功,成功时SD卡位空闲模式。
(2)在各种时序关系里,一般的操作只要8SPI个时钟就完成,最多的是命令发出后的响应,最多时需要8*8个时钟。
(3)激活之前要用低速率时钟,激活后可以转到高速率。
(4)发出激活命令后,退出空闲模式,SD卡应该受到返回值0。
参考了:http://www.ourdev.cn/bbs/bbs_content_all.jsp?bbs_sn=1353639
(5)命令发送的时序:片选、延时8个时钟、写命令六个字节、等待响应(这里需要循环读取,可以设置超时,如果有响应,最高位为0命令发送正确返回,超时返回错误)、如果有状态或数据返回,先不要除能CS,等接受完数据再除能,SPI发送0xff以8个时钟结束。
(6)SD卡的激活用:CMD55+CMD41。如果是2.0的卡,还支持CMD8。
二、对程序进行大修
1、由于很多时序问题之前都模糊,程序存在较大问题,但得益于程序的层次化设计,所以工作主要是修修补补。
2、错误处理,为了简单起见,现在的程序不区别各种类型的错误,有错返回1,没错返回0。
3、终于可以读取和写入SD卡,程序的分析明天再进行。
用户1593293 2009-12-3 10:25