弄了挺 长时间,但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_InitTypeDef spiStruct; 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[16]; u32 capacity; u8 n; u16 csize; if (GetCSD(csd)!=0) return 0; if ((csd[0] & 0xc0)==0x40) { //V2.00քߨ csize=csd[9] + ((u16)csd[8]<<8)+1; capacity=(u32)csize<<10; } else { n=(csd[5] & 15) + ((csd[10] & 128)>>7)+((csd[9] &3)<<1) +2; csize=(csd[8]>>6) + ((u16)csd[7]<<2) + ((u16)(csd[6] &3)<<10)+1; capacity=(u32)csize<<(n-9); } return capacity; } u16 SD::Initialize() { u16 ret; u16 retry; u8 buf[4]; 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[i]=spi.R(); if (buf[2]==0x1 && buf[3]==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[i]=spi.R(); if (buf[0] & 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; } |
评分
查看全部评分