完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
新手移植FatFs文件系统,利用STM32Cube,初始化SPI2,选择PB9作为片选信号,没用使用cube自带的fatfs文件系统;问题如标题所示,f_Open返回FR_NOT_READY,通过断点调试,发现在调用SD_Init()函数中,发送CMD0,让SD进入IDLE状态时,返回值不是0x01;调试了一周,也没找到问题所在。【系统时钟160MHz,SPI2所在的APBH1时钟为40MHz,SD卡为16G的SDHC卡】,跪求指导; 代码见楼下: |
|
相关推荐
8个回答
|
|
main.c
/* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" #include "main.h" #include "diskio.h" /* Private variables ---------------------------------------------------------*/ SPI_HandleTypeDef hspi2; /* USER CODE BEGIN 0 */ FATFS fs;// Work area (file system object) for logical drive // DIR dir; FIL fsrc, fdst; // file objects FRESULT fr;// FatFs function common result code /* USER CODE END 0 */ /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_SPI2_Init(void); int main(void) { /* USER CODE BEGIN 1 */ char buffer[100]; // file copy buffer UINT br, bw; // File R/W count // DSTATUS status; unsigned char w_buffer[]="123456789123456789123456789123456789";//?????? /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI2_Init(); /* USER CODE BEGIN 2 */ // status = disk_initialize(0); // if(status==0) // { // return RES_OK; // } fr=f_mount(0,&fs); //fr=f_opendir(&dir,""); fr = f_open(&fsrc,"0:/srcfile.txt",FA_CREATE_ALWAYS|FA_WRITE); if(fr==FR_OK) fr = f_write(&fsrc,w_buffer,strlen(w_buffer),&bw); fr = f_close(&fsrc); f_mount(0,NULL); /* USER CODE END 2 */ /* USER CODE BEGIN 3 */ /* Infinite loop */ while (1) { } /* USER CODE END 3 */ } /** System Clock Configuration */ static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 15; RCC_OscInitStruct.PLL.PLLN = 192; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 4; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1 |RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } /* SPI2 init function */ void MX_SPI2_Init(void) { hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLED; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED; hspi2.Init.CRCPolynomial = 7; HAL_SPI_Init(&hspi2); } /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __GPIOH_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); /*Configure GPIO pin : PB9 */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } |
|
|
|
diskio.c
/* Includes ------------------------------------------------------------------*/ #include "diskio.h" #include "ffconf.h" #include "Spi_SD_Driver.h" #include /* Private variables ---------------------------------------------------------*/ //extern MSD_CARDINFO SD0_CardInfo; DSTATUS disk_initialize ( BYTE drv /* Physical drive nmuber (0..) */ ) { int Status; Status = SD_Init(); if(Status==0) { return RES_OK; }else{ return STA_NOINIT; } } DSTATUS disk_status ( BYTE drv /* Physical drive nmuber (0..) */ ) { return RES_OK; } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ DRESULT disk_read ( BYTE drv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to read (1..255) */ ) { int Status; if( !count ) { return RES_PARERR; /* count²»ÄܵÈÓÚ0£¬·ñÔò·µ»Ø²ÎÊý´íÎó */ } if(count==1) /* 1¸ösectorµÄ¶Á²Ù×÷ */ { Status = SD_ReadSingleBlock( sector ,buff ); if(Status == 0){ return RES_OK; }else{ return RES_ERROR; } } else /* ¶à¸ösectorµÄ¶Á²Ù×÷ */ { Status = SD_ReadMultiBlock( sector , buff ,count); if(Status == 0){ return RES_OK; }else{ return RES_ERROR; } } } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ #if _READONLY == 0 DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0..) */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to write (1..255) */ ) { int Status; if( !count ) { return RES_PARERR; /* count²»ÄܵÈÓÚ0£¬·ñÔò·µ»Ø²ÎÊý´íÎó */ } if(count==1) /* 1¸ösectorµÄд²Ù×÷ */ { Status = SD_WriteSingleBlock( sector , (uint8_t *)(&buff[0]) ); if(Status == 0){ return RES_OK; }else{ return RES_ERROR; } } else /* ¶à¸ösectorµÄд²Ù×÷ */ { Status = SD_WriteMultiBlock( sector , (uint8_t *)(&buff[0]) , count ); if(Status == 0){ return RES_OK; }else{ return RES_ERROR; } } } #endif /* _READONLY */ /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ //DRESULT disk_ioctl ( // BYTE drv, /* Physical drive nmuber (0..) */ // BYTE ctrl, /* Control code */ // void *buff /* Buffer to send/receive control data */ //) //{ // //MSD0_GetCardInfo(&SD0_CardInfo); // switch (ctrl) // { // case CTRL_SYNC : // return RES_OK; // case GET_SECTOR_COUNT : // //*(DWORD*)buff = SD0_CardInfo.Capacity/SD0_CardInfo.BlockSize; // return RES_OK; // case GET_BLOCK_SIZE : // //*(WORD*)buff = SD0_CardInfo.BlockSize; // return RES_OK; // case CTRL_POWER : // break; // case CTRL_LOCK : // break; // case CTRL_EJECT : // break; // /* MMC/SDC command */ // case MMC_GET_TYPE : // break; // case MMC_GET_CSD : // break; // case MMC_GET_CID : // break; // case MMC_GET_OCR : // break; // case MMC_GET_SDSTAT : // break; // } // //} DRESULT disk_ioctl(BYTE drv, /* Physical drive nmuber (0..) */ BYTE ctrl, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { return RES_OK; } /* µÃµ½ÎļþCalendar¸ñʽµÄ½¨Á¢ÈÕÆÚ,ÊÇDWORD get_fattime (void) Äæ±ä»» */ /*-----------------------------------------------------------------------*/ /* User defined function to give a current time to fatfs module */ /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */ /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */ DWORD get_fattime (void) { return 0; } |
|
|
|
SPI_SD_Driver.c分3部分上传,Part1:
/* Includes ------------------------------------------------------------------*/ //#include "config.h" #include "Spi_SD_Driver.h" #include "stm32f4xx.h" #include "main.h" u8 SD_Type=0; /* Private functions ---------------------------------------------------------*/ // ÒÔÏÂÊÇSPIÄ£¿éµÄ³õʼ»¯´úÂ룬ÅäÖóÉÖ÷»úģʽ£¬·ÃÎÊSD¿¨ /******************************************************************************* * Function Name : SPI_SetSpeed * Description : SPIÉèÖÃËÙ¶ÈΪ¸ßËÙ * Input : u8 SpeedSet * Èç¹ûËÙ¶ÈÉèÖÃÊäÈë0£¬ÔòµÍËÙģʽ£¬·Ç0Ôò¸ßËÙģʽ * SPI_SPEED_HIGH 1 * SPI_SPEED_LOW 0 * Output : None * Return : None *******************************************************************************/ void SPI_SetSpeed(u8 SpeedSet) { hspi2.Instance=SPI2; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLED; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED; hspi2.Init.CRCPolynomial = 7; if(SpeedSet==SPI_SPEED_LOW) { hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; } else { hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; } HAL_SPI_Init(&hspi2); } /******************************************************************************* * Function Name : SPI_ReadWriteByte * Description : SPI¶Áдһ¸ö×Ö½Ú£¨·¢ËÍÍê³Éºó·µ»Ø±¾´ÎͨѶ¶ÁÈ¡µÄÊý¾Ý£© * Input : u8 TxData ´ý·¢Ë͵ÄÊý * Output : None * Return : u8 RxData ÊÕµ½µÄÊý *******************************************************************************/ u8 SPI_ReadWriteByte(u8 TxData) { u8 RxData; HAL_SPI_TransmitReceive(&hspi2,&TxData,&RxData,1,1); return RxData; } /******************************************************************************* * Function Name : SD_WaitReady * Description : µÈ´ýSD¿¨Ready * Input : None * Output : None * Return : u8 * 0£º ³É¹¦ * other£ºÊ§°Ü *******************************************************************************/ u8 SD_WaitReady(void) { u8 r1; u16 retry; retry = 0; do { r1 = SPI_ReadWriteByte(0xFF); if(retry==0xfffe) { return 1; } }while(r1!=0xFF); return 0; } /******************************************************************************* * Function Name : SD_SendCommand * Description : ÏòSD¿¨·¢ËÍÒ»¸öÃüÁî * Input : u8 cmd ÃüÁî * u32 arg ÃüÁî²ÎÊý * u8 crc crcУÑéÖµ * Output : None * Return : u8 r1 SD¿¨·µ»ØµÄÏìÓ¦ *******************************************************************************/ u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc) { unsigned char r1; unsigned char Retry = 0; //???????? SPI_ReadWriteByte(0xff); //Ƭѡ¶ËÖõͣ¬Ñ¡ÖÐSD¿¨ SD_CS_ENABLE(); //·¢ËÍ SPI_ReadWriteByte(cmd | 0x40); //·Ö±ðдÈëÃüÁî SPI_ReadWriteByte(arg >> 24); SPI_ReadWriteByte(arg >> 16); SPI_ReadWriteByte(arg >> 8); SPI_ReadWriteByte(arg); SPI_ReadWriteByte(crc); //µÈ´ýÏìÓ¦£¬»ò³¬Ê±Í˳ö while((r1 = SPI_ReadWriteByte(0xFF))==0xFF) { Retry++; if(Retry > 200) { break; } } //¹Ø±ÕƬѡ SD_CS_DISABLE(); //ÔÚ×ÜÏßÉ϶îÍâÔö¼Ó8¸öʱÖÓ£¬ÈÃSD¿¨Íê³ÉÊ£ÏµĹ¤×÷ SPI_ReadWriteByte(0xFF); //·µ»Ø״ֵ̬ return r1; } /******************************************************************************* * Function Name : SD_SendCommand_NoDeassert * Description : ÏòSD¿¨·¢ËÍÒ»¸öÃüÁî(½áÊøÊDz»Ê§ÄÜƬѡ£¬»¹ÓкóÐøÊý¾Ý´«À´£© * Input : u8 cmd ÃüÁî * u32 arg ÃüÁî²ÎÊý * u8 crc crcУÑéÖµ * Output : None * Return : u8 r1 SD¿¨·µ»ØµÄÏìÓ¦ *******************************************************************************/ u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc) { unsigned char r1; unsigned char Retry = 0; //???????? SPI_ReadWriteByte(0xff); //Ƭѡ¶ËÖõͣ¬Ñ¡ÖÐSD¿¨ SD_CS_ENABLE(); //·¢ËÍ SPI_ReadWriteByte(cmd | 0x40); //·Ö±ðдÈëÃüÁî SPI_ReadWriteByte(arg >> 24); SPI_ReadWriteByte(arg >> 16); SPI_ReadWriteByte(arg >> 8); SPI_ReadWriteByte(arg); SPI_ReadWriteByte(crc); //µÈ´ýÏìÓ¦£¬»ò³¬Ê±Í˳ö while((r1 = SPI_ReadWriteByte(0xFF))==0xFF) { Retry++; if(Retry > 200) { break; } } //·µ»ØÏìÓ¦Öµ return r1; } |
|
|
|
Part2:
/******************************************************************************* * Function Name : SD_Init * Description : ³õʼ»¯SD¿¨ * Input : None * Output : None * Return : u8 * 0£ºNO_ERR * 1£ºTIME_OUT * 99£ºNO_CARD *******************************************************************************/ u8 SD_Init(void) { u16 i; // ÓÃÀ´Ñ»·¼ÆÊý u8 r1; // ´æ·ÅSD¿¨µÄ·µ»ØÖµ u16 retry; // ÓÃÀ´½øÐг¬Ê±¼ÆÊý u8 buff[6]; //Èç¹ûûÓмì²âµ½¿¨²åÈ룬ֱ½ÓÍ˳ö£¬·µ»Ø´íÎó±êÖ¾ // if(!SD_DET()) // { // //return 99; // return STA_NODISK; // FatFS´íÎó±êÖ¾£ºÃ»ÓвåÈë´ÅÅÌ // } //SD¿¨Éϵç // SD_PWR_ON(); // ´¿ÑÓʱ£¬µÈ´ýSD¿¨ÉϵçÍê³É /******************************************************* //Õâ¸öµØ·½Òª¼ÓÒ»¾ä,ÉèÖÃSPIËÙ¶ÈΪµÍËÙ¡£ //ΪʲôÓеĿ¨¿ÉÒÔÄØ£¿ÒòΪSPI³õʼ»¯Ê±ÊǵÍËٵģ¬SD¿¨³õʼ»¯ //Íê³ÉºóÉèÖÃΪ¸ßËÙ£¬ÓеĿ¨Ö»Òª³õʼ»¯Ò»´Î¾ÍÐУ¬³ÌÐò¾Íok£» //µ«ÓеĿ¨ÐèÒª¶à´Î¸´Î»£¬ºÇºÇ£¬Õâ¸öµØ·½²îÕâÒ»¾ä£¬ //ÕâÖÖ¿¨¾ÍÓò»³É¿©£¡ *******************************************************/ SPI_SetSpeed(0); //ÉèÖÃSPIËÙ¶ÈΪµÍËÙ //ÏȲúÉú>74¸öÂö³å£¬ÈÃSD¿¨×Ô¼º³õʼ»¯Íê³É for(i=0;i<10;i++) { SPI_ReadWriteByte(0xFF); } //-----------------SD¿¨¸´Î»µ½idle¿ªÊ¼----------------- //Ñ»·Á¬Ðø·¢ËÍCMD0£¬Ö±µ½SD¿¨·µ»Ø0x01,½øÈëIDLE״̬ //³¬Ê±ÔòÖ±½ÓÍ˳ö SD_CS_ENABLE(); retry = 0; do { //·¢ËÍCMD0£¬ÈÃSD¿¨½øÈëIDLE״̬ r1 = SD_SendCommand(CMD0, 0, 0x95); retry++; }while((r1 != 0x01) && (retry<200)); //Ìø³öÑ»·ºó£¬¼ì²éÔÒò£º³õʼ»¯³É¹¦£¿or ÖØÊÔ³¬Ê±£¿ if(retry==200) { return 1; //³¬Ê±·µ»Ø1 } // retry=20; // do // { // r1=SD_SendCommand(CMD0,0,0x95); // }while((r1!=0x01)&&retry--); // SD_Type=0; //-----------------SD¿¨¸´Î»µ½idle½áÊø----------------- //»ñÈ¡¿¨Æ¬µÄSD°æ±¾ÐÅÏ¢ r1 = SD_SendCommand_NoDeassert(8, 0x1aa, 0x87); //Èç¹û¿¨Æ¬°æ±¾ÐÅÏ¢ÊÇv1.0°æ±¾µÄ£¬¼´r1=0x05£¬Ôò½øÐÐÒÔϳõʼ»¯ if(r1 == 0x05) { //ÉèÖÿ¨ÀàÐÍΪSDV1.0£¬Èç¹ûºóÃæ¼ì²âµ½ÎªMMC¿¨£¬ÔÙÐÞ¸ÄΪMMC SD_Type = SD_TYPE_V1; //Èç¹ûÊÇV1.0¿¨£¬CMD8Ö¸ÁîºóûÓкóÐøÊý¾Ý //ƬѡÖøߣ¬½áÊø±¾´ÎÃüÁî SD_CS_DISABLE(); //¶à·¢8¸öCLK£¬ÈÃSD½áÊøºóÐø²Ù×÷ SPI_ReadWriteByte(0xFF); //-----------------SD¿¨¡¢MMC¿¨³õʼ»¯¿ªÊ¼----------------- //·¢¿¨³õʼ»¯Ö¸ÁîCMD55+ACMD41 // Èç¹ûÓÐÓ¦´ð£¬ËµÃ÷ÊÇSD¿¨£¬ÇÒ³õʼ»¯Íê³É // ûÓлØÓ¦£¬ËµÃ÷ÊÇMMC¿¨£¬¶îÍâ½øÐÐÏàÓ¦³õʼ»¯ retry = 0; do { //ÏÈ·¢CMD55£¬Ó¦·µ»Ø0x01£»·ñÔò³ö´í r1 = SD_SendCommand(CMD55, 0, 0); if(r1 != 0x01) { return r1; } //µÃµ½ÕýÈ·ÏìÓ¦ºó£¬·¢ACMD41£¬Ó¦µÃµ½·µ»ØÖµ0x00£¬·ñÔòÖØÊÔ200´Î r1 = SD_SendCommand(ACMD41, 0, 0); retry++; }while((r1!=0x00) && (retry<400)); // ÅжÏÊdz¬Ê±»¹Êǵõ½ÕýÈ·»ØÓ¦ // ÈôÓлØÓ¦£ºÊÇSD¿¨£»Ã»ÓлØÓ¦£ºÊÇMMC¿¨ //----------MMC¿¨¶îÍâ³õʼ»¯²Ù×÷¿ªÊ¼------------ if(retry==400) { retry = 0; //·¢ËÍMMC¿¨³õʼ»¯ÃüÁûÓвâÊÔ£© do { r1 = SD_SendCommand(1, 0, 0); retry++; }while((r1!=0x00)&& (retry<400)); if(retry==400) { return 1; //MMC¿¨³õʼ»¯³¬Ê± } //дÈ뿨ÀàÐÍ SD_Type = SD_TYPE_MMC; } //----------MMC¿¨¶îÍâ³õʼ»¯²Ù×÷½áÊø------------ //ÉèÖÃSPIΪ¸ßËÙģʽ SPI_SetSpeed(1); SPI_ReadWriteByte(0xFF); //½ûÖ¹CRCУÑé /* r1 = SD_SendCommand(CMD59, 0, 0x01); if(r1 != 0x00) { return r1; //ÃüÁî´íÎ󣬷µ»Ør1 } */ //ÉèÖÃSector Size r1 = SD_SendCommand(CMD16, 512, 0xff); if(r1 != 0x00) { return r1; //ÃüÁî´íÎ󣬷µ»Ør1 } //-----------------SD¿¨¡¢MMC¿¨³õʼ»¯½áÊø----------------- }//SD¿¨ÎªV1.0°æ±¾µÄ³õʼ»¯½áÊø //ÏÂÃæÊÇV2.0¿¨µÄ³õʼ»¯ //ÆäÖÐÐèÒª¶ÁÈ¡OCRÊý¾Ý£¬ÅжÏÊÇSD2.0»¹ÊÇSD2.0HC¿¨ else if( r1 == 0x01) { //V2.0µÄ¿¨£¬CMD8ÃüÁîºó»á´«»Ø4×Ö½ÚµÄÊý¾Ý£¬ÒªÌø¹ýÔÙ½áÊø±¾ÃüÁî buff[0] = SPI_ReadWriteByte(0xFF); //should be 0x00 buff[1] = SPI_ReadWriteByte(0xFF); //should be 0x00 buff[2] = SPI_ReadWriteByte(0xFF); //should be 0x01 buff[3] = SPI_ReadWriteByte(0xFF); //should be 0xAA SD_CS_DISABLE(); //the next 8 clocks SPI_ReadWriteByte(0xFF); //Åжϸÿ¨ÊÇ·ñÖ§³Ö2.7V-3.6VµÄµçѹ·¶Î§ if(buff[2]==0x01 && buff[3]==0xAA) { //Ö§³Öµçѹ·¶Î§£¬¿ÉÒÔ²Ù×÷ retry = 0; //·¢¿¨³õʼ»¯Ö¸ÁîCMD55+ACMD41 do { r1 = SD_SendCommand(CMD55, 0, 0); if(r1!=0x01) { return r1; } r1 = SD_SendCommand(ACMD41, 0x40000000, 0); if(retry>200) { return r1; //³¬Ê±Ôò·µ»Ør1״̬ } }while(r1!=0); //³õʼ»¯Ö¸Áî·¢ËÍÍê³É£¬½ÓÏÂÀ´»ñÈ¡OCRÐÅÏ¢ //-----------¼ø±ðSD2.0¿¨°æ±¾¿ªÊ¼----------- r1 = SD_SendCommand_NoDeassert(CMD58, 0, 0); if(r1!=0x00) { return r1; //Èç¹ûÃüÁîûÓзµ»ØÕýÈ·Ó¦´ð£¬Ö±½ÓÍ˳ö£¬·µ»ØÓ¦´ð } //¶ÁOCRÖ¸Áî·¢³öºó£¬½ô½Ó×ÅÊÇ4×Ö½ÚµÄOCRÐÅÏ¢ buff[0] = SPI_ReadWriteByte(0xFF); buff[1] = SPI_ReadWriteByte(0xFF); buff[2] = SPI_ReadWriteByte(0xFF); buff[3] = SPI_ReadWriteByte(0xFF); //OCR½ÓÊÕÍê³É£¬Æ¬Ñ¡ÖÃ¸ß SD_CS_DISABLE(); SPI_ReadWriteByte(0xFF); //¼ì²é½ÓÊÕµ½µÄOCRÖеÄbit30루CCS£©£¬È·¶¨ÆäΪSD2.0»¹ÊÇSDHC //Èç¹ûCCS=1£ºSDHC CCS=0£ºSD2.0 if(buff[0]&0x40) //¼ì²éCCS { SD_Type = SD_TYPE_V2HC; } else { SD_Type = SD_TYPE_V2; } //-----------¼ø±ðSD2.0¿¨°æ±¾½áÊø----------- //ÉèÖÃSPIΪ¸ßËÙģʽ SPI_SetSpeed(1); } } return r1; } /******************************************************************************* * Function Name : SD_ReceiveData * Description : ´ÓSD¿¨ÖжÁ»ØÖ¸¶¨³¤¶ÈµÄÊý¾Ý£¬·ÅÖÃÔÚ¸ø¶¨Î»Öà * Input : u8 *data(´æ·Å¶Á»ØÊý¾ÝµÄÄÚ´æ>len) * u16 len(Êý¾Ý³¤¶È£© * u8 release(´«ÊäÍê³ÉºóÊÇ·ñÊÍ·Å×ÜÏßCSÖÃ¸ß 0£º²»ÊÍ·Å 1£ºÊÍ·Å£© * Output : None * Return : u8 * 0£ºNO_ERR * other£º´íÎóÐÅÏ¢ *******************************************************************************/ u8 SD_ReceiveData(u8 *data, u16 len, u8 release) { u16 retry; u8 r1; // Æô¶¯Ò»´Î´«Êä SD_CS_ENABLE(); //µÈ´ýSD¿¨·¢»ØÊý¾ÝÆðʼÁîÅÆ0xFE retry = 0; do { r1 = SPI_ReadWriteByte(0xFF); retry++; if(retry>2000) //2000´ÎµÈ´ýºóûÓÐÓ¦´ð£¬Í˳ö±¨´í { SD_CS_DISABLE(); return 1; } }while(r1 != 0xFE); //¿ªÊ¼½ÓÊÕÊý¾Ý while(len--) { *data = SPI_ReadWriteByte(0xFF); data++; } //ÏÂÃæÊÇ2¸öαCRC£¨dummy CRC£© SPI_ReadWriteByte(0xFF); SPI_ReadWriteByte(0xFF); //°´ÐèÊÍ·Å×ÜÏߣ¬½«CSÖÃ¸ß if(release == RELEASE) { //´«Êä½áÊø SD_CS_DISABLE(); SPI_ReadWriteByte(0xFF); } return 0; } |
|
|
|
Part3:
/******************************************************************************* * Function Name : SD_GetCID * Description : »ñÈ¡SD¿¨µÄCIDÐÅÏ¢£¬°üÀ¨ÖÆÔìÉÌÐÅÏ¢ * Input : u8 *cid_data(´æ·ÅCIDµÄÄڴ棬ÖÁÉÙ16Byte£© * Output : None * Return : u8 * 0£ºNO_ERR * 1£ºTIME_OUT * other£º´íÎóÐÅÏ¢ *******************************************************************************/ u8 SD_GetCID(u8 *cid_data) { u8 r1; //·¢CMD10ÃüÁ¶ÁCID r1 = SD_SendCommand(CMD10, 0, 0xFF); if(r1 != 0x00) { return r1; //û·µ»ØÕýÈ·Ó¦´ð£¬ÔòÍ˳ö£¬±¨´í } //½ÓÊÕ16¸ö×Ö½ÚµÄÊý¾Ý SD_ReceiveData(cid_data, 16, RELEASE); return 0; } /******************************************************************************* * Function Name : SD_GetCSD * Description : »ñÈ¡SD¿¨µÄCSDÐÅÏ¢£¬°üÀ¨ÈÝÁ¿ºÍËÙ¶ÈÐÅÏ¢ * Input : u8 *cid_data(´æ·ÅCIDµÄÄڴ棬ÖÁÉÙ16Byte£© * Output : None * Return : u8 * 0£ºNO_ERR * 1£ºTIME_OUT * other£º´íÎóÐÅÏ¢ *******************************************************************************/ u8 SD_GetCSD(u8 *csd_data) { u8 r1; //·¢CMD9ÃüÁ¶ÁCSD r1 = SD_SendCommand(CMD9, 0, 0xFF); if(r1 != 0x00) { return r1; //û·µ»ØÕýÈ·Ó¦´ð£¬ÔòÍ˳ö£¬±¨´í } //½ÓÊÕ16¸ö×Ö½ÚµÄÊý¾Ý SD_ReceiveData(csd_data, 16, RELEASE); return 0; } /******************************************************************************* * Function Name : SD_GetCapacity * Description : »ñÈ¡SD¿¨µÄÈÝÁ¿ * Input : None * Output : None * Return : u32 capacity * 0£º È¡ÈÝÁ¿³ö´í *******************************************************************************/ u32 SD_GetCapacity(void) { u8 csd[16]; u32 Capacity; u8 r1; u16 i; u16 temp; //È¡CSDÐÅÏ¢£¬Èç¹ûÆÚ¼ä³ö´í£¬·µ»Ø0 if(SD_GetCSD(csd)!=0) { return 0; } //Èç¹ûΪSDHC¿¨£¬°´ÕÕÏÂÃ淽ʽ¼ÆËã if((csd[0]&0xC0)==0x40) { Capacity = (((u32)csd[8])<<8 + (u32)csd[9] +1)*(u32)1024; } else { //ÏÂÃæ´úÂëΪÍøÉÏ°æ±¾ ////////////formula of the capacity/////////////// // // memory capacity = BLOCKNR * BLOCK_LEN // // BLOCKNR = (C_SIZE + 1)* MULT // // C_SIZE_MULT+2 // MULT = 2 // // READ_BL_LEN // BLOCK_LEN = 2 /**********************************************/ //C_SIZE i = csd[6]&0x03; i<<=8; i += csd[7]; i<<=2; i += ((csd[8]&0xc0)>>6); //C_SIZE_MULT r1 = csd[9]&0x03; r1<<=1; r1 += ((csd[10]&0x80)>>7); //BLOCKNR r1+=2; temp = 1; while(r1) { temp*=2; r1--; } Capacity = ((u32)(i+1))*((u32)temp); // READ_BL_LEN i = csd[5]&0x0f; //BLOCK_LEN temp = 1; while(i) { temp*=2; i--; } //The final result Capacity *= (u32)temp; //Capacity /= 512; } return (u32)Capacity; } /******************************************************************************* * Function Name : SD_ReadSingleBlock * Description : ¶ÁSD¿¨µÄÒ»¸öblock * Input : u32 sector È¡µØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£© * u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£© * Output : None * Return : u8 r1 * 0£º ³É¹¦ * other£ºÊ§°Ü *******************************************************************************/ u8 SD_ReadSingleBlock(u32 sector, u8 *buffer) { u8 r1; //ÉèÖÃΪ¸ßËÙģʽ SPI_SetSpeed(SPI_SPEED_LOW); //Èç¹û²»ÊÇSDHC£¬½«sectorµØַת³ÉbyteµØÖ· if(SD_Type!=SD_TYPE_V2HC) { sector = sector<<9; } r1 = SD_SendCommand(CMD17, sector, 0);//¶ÁÃüÁî if(r1 != 0x00) { return r1; } r1 = SD_ReceiveData(buffer, 512, RELEASE); if(r1 != 0) { return r1; //¶ÁÊý¾Ý³ö´í£¡ } else { return 0; } } /******************************************************************************* * Function Name : SD_WriteSingleBlock * Description : дÈëSD¿¨µÄÒ»¸öblock * Input : u32 sector ÉÈÇøµØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£© * u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£© * Output : None * Return : u8 r1 * 0£º ³É¹¦ * other£ºÊ§°Ü *******************************************************************************/ u8 SD_WriteSingleBlock(u32 sector, const u8 *data) { u8 r1; u16 i; u16 retry; //ÉèÖÃΪ¸ßËÙģʽ SPI_SetSpeed(SPI_SPEED_LOW); //Èç¹û²»ÊÇSDHC£¬¸ø¶¨µÄÊÇsectorµØÖ·£¬½«Æäת»»³ÉbyteµØÖ· if(SD_Type!=SD_TYPE_V2HC) { sector = sector<<9; } r1 = SD_SendCommand(CMD24, sector, 0x00); if(r1 != 0x00) { return r1; //Ó¦´ð²»ÕýÈ·£¬Ö±½Ó·µ»Ø } //¿ªÊ¼×¼±¸Êý¾Ý´«Êä SD_CS_ENABLE(); //ÏÈ·Å3¸ö¿ÕÊý¾Ý£¬µÈ´ýSD¿¨×¼±¸ºÃ SPI_ReadWriteByte(0xff); SPI_ReadWriteByte(0xff); SPI_ReadWriteByte(0xff); //·ÅÆðʼÁîÅÆ0xFE SPI_ReadWriteByte(0xFE); //·ÅÒ»¸ösectorµÄÊý¾Ý for(i=0;i<512;i++) { SPI_ReadWriteByte(*data++); } //·¢2¸öByteµÄdummy CRC SPI_ReadWriteByte(0xff); SPI_ReadWriteByte(0xff); //µÈ´ýSD¿¨Ó¦´ð r1 = SPI_ReadWriteByte(0xff); if((r1&0x1F)!=0x05) { SD_CS_DISABLE(); return r1; } //µÈ´ý²Ù×÷Íê³É retry = 0; while(!SPI_ReadWriteByte(0xff)) { retry++; if(retry>0xfffe) //Èç¹û³¤Ê±¼äдÈëûÓÐÍê³É£¬±¨´íÍ˳ö { SD_CS_DISABLE(); return 1; //дÈ볬ʱ·µ»Ø1 } } //дÈëÍê³É£¬Æ¬Ñ¡ÖÃ1 SD_CS_DISABLE(); SPI_ReadWriteByte(0xff); return 0; } |
|
|
|
由于字数限制,3部分没传完,只能补一部分啦,Part4:
/******************************************************************************* * Function Name : SD_ReadMultiBlock * Description : ¶ÁSD¿¨µÄ¶à¸öblock * Input : u32 sector È¡µØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£© * u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£© * u8 count Á¬Ðø¶Ácount¸öblock * Output : None * Return : u8 r1 * 0£º ³É¹¦ * other£ºÊ§°Ü *******************************************************************************/ u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count) { u8 r1; //ÉèÖÃΪ¸ßËÙģʽ SPI_SetSpeed(SPI_SPEED_LOW); //Èç¹û²»ÊÇSDHC£¬½«sectorµØַת³ÉbyteµØÖ· if(SD_Type!=SD_TYPE_V2HC) { sector = sector<<9; } //SD_WaitReady(); //·¢¶Á¶à¿éÃüÁî r1 = SD_SendCommand(CMD18, sector, 0);//¶ÁÃüÁî if(r1 != 0x00) { return r1; } //¿ªÊ¼½ÓÊÕÊý¾Ý do { if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00) { break; } buffer += 512; } while(--count); //È«²¿´«ÊäÍê±Ï£¬·¢ËÍÍ£Ö¹ÃüÁî SD_SendCommand(CMD12, 0, 0); //ÊÍ·Å×ÜÏß SD_CS_DISABLE(); SPI_ReadWriteByte(0xFF); if(count != 0) { return count; //Èç¹ûûÓд«Í꣬·µ»ØÊ£Óà¸öÊý } else { return 0; } } /******************************************************************************* * Function Name : SD_WriteMultiBlock * Description : дÈëSD¿¨µÄN¸öblock * Input : u32 sector ÉÈÇøµØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£© * u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£© * u8 count дÈëµÄblockÊýÄ¿ * Output : None * Return : u8 r1 * 0£º ³É¹¦ * other£ºÊ§°Ü *******************************************************************************/ u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count) { u8 r1; u16 i=0; //ÉèÖÃΪ¸ßËÙģʽ SPI_SetSpeed(SPI_SPEED_LOW); //Èç¹û²»ÊÇSDHC£¬¸ø¶¨µÄÊÇsectorµØÖ·£¬½«Æäת»»³ÉbyteµØÖ· if(SD_Type != SD_TYPE_V2HC) { sector = sector<<9; } //Èç¹ûÄ¿±ê¿¨²»ÊÇMMC¿¨£¬ÆôÓÃACMD23Ö¸ÁîʹÄÜÔ¤²Á³ý if(SD_Type != SD_TYPE_MMC) { r1 = SD_SendCommand(ACMD23, count, 0x00); } //·¢¶à¿éдÈëÖ¸Áî r1 = SD_SendCommand(CMD25, sector, 0x00); if(r1 != 0x00) { return r1; //Ó¦´ð²»ÕýÈ·£¬Ö±½Ó·µ»Ø } //¿ªÊ¼×¼±¸Êý¾Ý´«Êä SD_CS_ENABLE(); //ÏÈ·Å3¸ö¿ÕÊý¾Ý£¬µÈ´ýSD¿¨×¼±¸ºÃ SPI_ReadWriteByte(0xff); SPI_ReadWriteByte(0xff); //--------ÏÂÃæÊÇN¸ösectorдÈëµÄÑ»·²¿·Ö do { //·ÅÆðʼÁîÅÆ0xFC ±íÃ÷ÊǶà¿éдÈë SPI_ReadWriteByte(0xFC); //·ÅÒ»¸ösectorµÄÊý¾Ý for(i=0;i<512;i++) { SPI_ReadWriteByte(*data++); } //·¢2¸öByteµÄdummy CRC SPI_ReadWriteByte(0xff); SPI_ReadWriteByte(0xff); //µÈ´ýSD¿¨Ó¦´ð r1 = SPI_ReadWriteByte(0xff); if((r1&0x1F)!=0x05) { SD_CS_DISABLE(); //Èç¹ûÓ¦´ðΪ±¨´í£¬Ôò´ø´íÎó´úÂëÖ±½ÓÍ˳ö return r1; } //µÈ´ýSD¿¨Ð´ÈëÍê³É if(SD_WaitReady()==1) { SD_CS_DISABLE(); //µÈ´ýSD¿¨Ð´ÈëÍê³É³¬Ê±£¬Ö±½ÓÍ˳ö±¨´í return 1; } //±¾sectorÊý¾Ý´«ÊäÍê³É }while(--count); //·¢½áÊø´«ÊäÁîÅÆ0xFD r1 = SPI_ReadWriteByte(0xFD); if(r1==0x00) { count = 0xfe; } if(SD_WaitReady()) { while(1) { } } //дÈëÍê³É£¬Æ¬Ñ¡ÖÃ1 SD_CS_DISABLE(); SPI_ReadWriteByte(0xff); return count; //·µ»ØcountÖµ£¬Èç¹ûдÍêÔòcount=0£¬·ñÔòcount=1 } |
|
|
|
LZ您好,我现在也遇到了您同样的问题,请问您解决了吗?
|
|
|
|
在线等您的答案
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1187 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1122 浏览 2 评论
2223 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1311 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1735 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 15:29 , Processed in 0.731520 second(s), Total 56, Slave 49 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号