SD卡初始化问题u8 SD_WaitReady(void)

2019-08-12 17:27发布

使用原子的新版SD卡程序移植到stm32f103vc的板子上,在SD卡初始化中,等待卡准备好的函数中,利用串口查看,始终得到0X00,不能得到0xff,换了3种卡都不能得到0xff,移植原来挑卡那版程序初始化没有问题,请大虾帮我分析分析造成的原因吧,不胜感激。
//等待卡准备好
//返回值:0,准备好了;其他,错误代码
u8 SD_WaitReady(void)
{  
 u32 t=0;
 do
 {
  if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK 此处SD_SPI_ReadWriteByte(0XFF)返回的值一直是0x00”
  t++;     
 }while(t<0XFFFFFF);//等待
 return 1;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
31条回答
正点原子
1楼-- · 2019-08-12 21:49
回复【楼主位】hooddas:
---------------------------------
你是不是SD卡底层驱动有问题?SPI设置.
hooddas
2楼-- · 2019-08-12 23:05
回复【2楼】正点原子:

---------------------------------
SPI应该没问题,SPI也是你那里的程序,基本上原封不动的移植,只不过把CS的IO口改了下,f103vc的片选是PA4,其他的都没改变,就是返回0x00
hooddas
3楼-- · 2019-08-13 02:05
这是加上串口的程序
—————————————————————————————————————————————————— 
//等待卡准备好
//返回值:0,准备好了;其他,错误代码
u8 SD_WaitReady(void)
{
 u8 t=0;
 u8 temp;
  delay_ms(5000); 
 do
 {
  temp = SD_SPI_ReadWriteByte(0XFF);
  USART1->DR = temp;
  while((USART1->SR & 0X40) == 0);//等待发送结束
  if(temp==0XFF)return 0;//OK
  t++;     
 }while(t<200);//等待
 return 1;
}
————————————————————————



串口得到的数据。。。。
-----------------------------------------------------------------------------------------
SPI的程序
#include "spi.h"

/********************************************************
函数名称:void SPIx_Init(void)
功能描述:SPI模块的初始化代码,配置成主机模式
全局变量:无
参数说明:无
返回值:  无
说明:SPI1的初始化
*********************************************************/
void SPIx_Init(void)
{
 RCC->APB2ENR|=1<<2;       //PORTA时钟使能  
 RCC->APB2ENR|=1<<12;      //SPI1时钟使能
    
 //这里只针对SPI口初始化
 GPIOA->CRL&=0X000FFFFF;
 GPIOA->CRL|=0XBBB00000;//PA5.6.7复用     
 GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉
  
 SPI1->CR1|=0<<10;//全双工模式 
 SPI1->CR1|=1<<9; //软件nss管理
 SPI1->CR1|=1<<8; 

 SPI1->CR1|=1<<2; //SPI主机
 SPI1->CR1|=0<<11;//8bit数据格式 
 SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1
 SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1 
 SPI1->CR1|=7<<3; //Fsck=Fcpu/256
 SPI1->CR1|=0<<7; //MSBfirst  
 SPI1->CR1|=1<<6; //SPI设备使能
 SPIx_ReadWriteByte(0xff);//启动传输    
}  

/********************************************************
函数名称:void SPIx_SetSpeed(u8 SpeedSet)
功能描述:SPI 速度设置函数
全局变量:无
参数说明:SpeedSet
返回值:  无
说明:
SpeedSet:
SPI_SPEED_2   2分频   (SPI 36M@sys 72M)
SPI_SPEED_8   8分频   (SPI 9M@sys 72M)
SPI_SPEED_16  16分频  (SPI 4.5M@sys 72M)
SPI_SPEED_256 256分频 (SPI 281.25K@sys 72M)
*********************************************************/
void SPIx_SetSpeed(u8 SpeedSet)
{
 SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256
 switch(SpeedSet)
 {
  case SPI_SPEED_2://二分频
   SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz
   break;
  case SPI_SPEED_4://四分频
   SPI1->CR1|=1<<3;//Fsck=Fpclk/4=18Mhz
   break;
  case SPI_SPEED_8://八分频
   SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz
   break;
  case SPI_SPEED_16://十六分频
   SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz
   break;
  case SPI_SPEED_256://256分频
   SPI1->CR1|=7<<3;//Fsck=Fpclk/16=281.25Khz
   break;
 }  
 SPI1->CR1|=1<<6; //SPI设备使能    
}

/********************************************************
函数名称:u8 SPIx_ReadWriteByte(u8 TxData)
功能描述:SPIx 读写一个字节
全局变量:无
参数说明:TxData:要写入的字节
返回值:  读取到的字节
说明:
*********************************************************/
u8 SPIx_ReadWriteByte(u8 TxData)
{  
 while((SPI1->SR&1<<1)==0);   
 SPI1->DR=TxData;     //发送一个byte  
 while((SPI1->SR&1<<0)==0);          
 return SPI1->DR;          //返回收到的数据       
}
----------------------------------------
SPI和VS1003可以通讯,应该是没问题


 

正点原子
4楼-- · 2019-08-13 02:48
 精彩回答 2  元偷偷看……
hooddas
5楼-- · 2019-08-13 08:31

回复【5楼】 正点原子 :

---------------------------------
这个是定义了SD片选
//这部分应根据具体的连线来修改!
//Mini STM32使用的是PA4作为SD卡的CS脚.
#define SD_CS  PAout(4) //SD卡片选引脚 
-----------------------------------
这个是初始化片选IO口的程序
//SPI硬件层初始化
void SD_SPI_Init(void)
{
     //设置硬件上与SD卡相关联的控制引脚输出
 //避免NRF24L01/W25X16等的影响
 RCC->APB2ENR|=1<<2;       //PORTA时钟使能
 GPIOA->CRL&=0XFFF0FFFF;
 GPIOA->CRL|=0X00030000;//PA2.3.4 推挽     
 GPIOA->ODR|=0X7<<2;    //PA2.3.4上拉
 SPIx_Init();
  SD_SPI_SpeedLow();//设置到低速模式 
 SD_CS=1;
}
-------------------------------------------------------------
程序在执行SD初始化时到进入r1=SD_SendCmd(CMD0,0,0x95);//进入IDLE状态最后进入到上面的等待卡准备好的函数时 返回的0X00;

//初始化SD卡
//返回值:0,正常.
//   其他,不正常.
u8 SD_Initialize(void)
{
    u8 r1;      // 存放SD卡的返回值
    u16 retry;  // 用来进行超时计数
    u8 buf[4]; 
 u16 i;

 SD_SPI_Init();  //初始化IO
  SD_SPI_SpeedLow(); //设置到低速模式
    //for(i=0;i<0xf00;i++);//纯延时,等待SD卡上电完成  
 for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//发送最少74个脉冲
 retry=20;
 do
 {
  r1=SD_SendCmd(CMD0,0,0x95);//进入IDLE状态
 }while((r1!=0X01) && retry--);
  SD_Type=0;//默认无卡
--------------------------------------------------------------------------
在主函数里对片选口进行测试,用万用表量,每个2秒高低电平会有变化,正常。
int main(void)
{
 u8 temp;
 stm32_init();//stm32初始化
 hardware_init();//外围器件初始化
 while(1)
 {
  delay_ms(1000);
  SD_CS = ~SD_CS;
  delay_ms(1000);
--------------------------------------------------------------------------------



SPI的初始化完全移植开发板的程序,用金士顿 adata sandisk三个牌子的SD卡 一样的现象,实在是想不明白了

正点原子
6楼-- · 2019-08-13 12:35
 SD_SPI_SpeedLow();//设置到低速模式  
是设置到多少?
SPI1的频率为SPI2的两倍哦.

一周热门 更多>