SPI,SD CMD41返回总是1
弄了挺 长时间,但CMD41总是返回1请大家帮忙看看。
只贴了主要代码。
void SPI::InitHard(SPI_TypeDef* spino,u8 speed,u8 mode) {
isSoft=false;
spi=spino;
GPIO_InitTypeDef gpiodef;
SCS=PORT(GPIOA,4);
SCS.setMode(GPIO_Mode_Out_PP);
SPI_InitTypeDefspiStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
spiStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spiStruct.SPI_Mode = SPI_Mode_Master;
spiStruct.SPI_DataSize = SPI_DataSize_8b;
spiStruct.SPI_CPOL = SPI_CPOL_High;
spiStruct.SPI_CPHA = SPI_CPHA_2Edge;
spiStruct.SPI_NSS = SPI_NSS_Soft;
spiStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
spiStruct.SPI_FirstBit = SPI_FirstBit_MSB;
spiStruct.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &spiStruct);
SPI_Cmd(SPI1, ENABLE);
W(0xff);
}
u8 SPI::R() {return W(0xff);}
u8 SPI::W(u8 d) {
while((spi->SR&SPI_I2S_FLAG_TXE)==RESET);
spi->DR=d;
while((spi->SR&SPI_I2S_FLAG_RXNE)==RESET);
return spi->DR;
}
==============================================================
#include "sd.h"
void SD::Init() {
spi.InitHard(SPI1);
}
void SD::SetSpeed(u8 speed) {
spi.setSpeed(speed);
return;
spi.spiStruct.SPI_BaudRatePrescaler=speed;
SPI_Init(SPI1,&spi.spiStruct);
SPI_Cmd(SPI1,ENABLE);
}
void SD::unSelect() {
spi.SCS.High();
}
u8 SD::Select() {
spi.SCS.Low();
uint32_t t=0;
do {
if (spi.R()==0xff) return 0;
t++;
} while(t<0xfff);
unSelect();
return 1;
}
u8 SD::SendCmd(u8 cmd,u32 arg,u8 crc) {
u8 r1;
u8 retry=0;
unSelect();
//spi.W(0xff);
if (Select()) return 0xff;
spi.W(cmd | 0x40);
spi.W(arg>>24);
spi.W(arg>>16);
spi.W(arg>>8);
spi.W(arg);
spi.W(crc);
spi.W(0xff);
retry=0x1f;
do {
r1=spi.R();
retry--;
} while((r1 &0x80) && retry);
return r1;
}
u8 SD::GetCID(u8 *buf) {
u8 r1;
r1=SendCmd(CMD10,0,0x1);
if (r1==0) {
r1=RecvData(buf,16);
}
unSelect();
return r1;
}
u8 SD::GetCSD(u8 *buf) {
u8 r1;
r1=SendCmd(CMD9,0,1);
if (r1==0) {
r1=RecvData(buf,16);
}
unSelect();
return r1;
}
u32 SD::GetSectorCount() {
u8 csd;
u32 capacity;
u8 n;
u16 csize;
if (GetCSD(csd)!=0) return 0;
if ((csd & 0xc0)==0x40) { //V2.00քߨ
csize=csd + ((u16)csd<<8)+1;
capacity=(u32)csize<<10;
} else {
n=(csd & 15) + ((csd & 128)>>7)+((csd &3)<<1) +2;
csize=(csd>>6) + ((u16)csd<<2) + ((u16)(csd &3)<<10)+1;
capacity=(u32)csize<<(n-9);
}
return capacity;
}
u16 SD::Initialize() {
u16 ret;
u16 retry;
u8 buf;
u16 i;
step=0;
Init();
spi.setSpeed(SPI_BaudRatePrescaler_256);
//spi.setSpeed(100);
for(i=0;i<200;i++) spi.W(0xff);
retry=20;
step=1;
do {
ret=SendCmd(CMD0,0,0x95);
}while((ret!=1) &&retry--);
step=11;
if (ret==1) {
step=2;
if (SendCmd(CMD8,0x1aa,0x87)==1){
step=3;
for(i=0;i<4;i++) buf=spi.R();
if (buf==0x1 && buf==0xaa) {
step=4;
retry=0xffe;
do {
ret=SendCmd(CMD55,0,1);
if (ret!=1) {
step=15;
} else{
step=16;
ret=SendCmd(CMD41,0x40000000,0); //<<-----这里返回总是1
}
}while(ret && retry--);
if (retry && SendCmd(CMD58,0,0x1)==0){
step=5;
for(i=0;i<4;i++) buf=spi.R();
if (buf & 0x40) type=SD_TYPE_V2HC;
else type=SD_TYPE_V2;
}
}
} else {
step=6;
SendCmd(CMD55,0,1);
SendCmd(CMD41,0,1);
if (ret<=1) {
step=7;
type=SD_TYPE_V1;
retry=0xffe;
do {
SendCmd(CMD55,0,1);
ret=SendCmd(CMD41,0,1);
}while(ret && retry--);
} else {
step=8;
type=SD_TYPE_MMC;
retry=0xffe;
do {
ret=SendCmd(CMD1,0,1);
}while(ret && retry--);
}
if (retry==0 || SendCmd(CMD16,512,1)!=0) type=SD_TYPE_UNKNOW;
}
}
unSelect();
spi.setSpeed(SPI_BaudRatePrescaler_2);
if (type) return 0;
else if (ret) return ret; else return 0xaa;
}
你这个是什么代码?你直接先看看示波器,看看返回是什么,在接收那里设个断点,看看接收寄存器是什么值,如果不对,那就是spi的设置问题,看看那个接收的边沿寄存器是否一致
页:
[1]