STM32 SD card_no file system added

Publisher:科技先锋Latest update time:2016-08-21 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
  STM32 SD card_no file system added - liuyunqian@yeah - Embedded Learning

The picture below shows the SD card part of the Wanli board

  STM32 SD card_no file system added - liuyunqian@yeah - Embedded Learning

SD_PWR is connected to PD10 through a control

  STM32 SD card_no file system added - liuyunqian@yeah - Embedded Learning
 

 

P-Channel 2.5-V (GS) MOSFET controls the power supply of the SD card

=====================================================================

SPI mode read and write SD card

 

SD card initialization process:

1. Initialize the SPI interface of STM32 to use low-speed mode
2. Delay at least 74clock
3. Send CMD0, need to return 0x01, enter the Idle state
4. Loop and send CMD55+ACMD41 until it returns 0x00, enter the Ready state
5. Set the read and write block size to 512byte 
5. Set the SPI of STM32 to high-speed mode



The process of reading a block

1. Send CMD17 (single block) or CMD18 (multiple blocks) read command, return 0x00
2. Receive data start token 0xfe + formal data 512Bytes + CRC check 2Bytes

The process of writing a block

1. Send CMD24 (single block) or CMD25 (multiple blocks) write command, return 0x00
2. Send data start token 0xfe + formal data 512Bytes + CRC check 2Bytes

/*******************************************************************************
* Function Name : SD_MMC_SPI_Init
* Description    : SD_MMC_SPI_Init
* Input          : None
* Output         : None
* Return         : zero init success, non-zero init error
*******************************************************************************/
u8 SD_MMC_SPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* Enable SPI1 and GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_SD_MMC_SPI_CS, ENABLE);

/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure SD_MMC_SPI_CS */
GPIO_InitStructure.GPIO_Pin = SD_MMC_SPI_CS_Pin_CS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SD_MMC_SPI_CS, &GPIO_InitStructure);

//////////////////////////////////////////////////////////////////////////////
/* initialize SPI with lowest frequency */
SD_MMC_Low_Speed();

/* card needs 74 cycles minimum to start up */
for(u8 i = 0; i < 10; ++i)
{
/* wait 8 clock cycles */
SD_MMC_ReadWrite_Byte(0x00);
}

    /* address card */
SD_MMC_SPI_SELECT();

    /* reset card */
u8 response;
for(u16 i = 0; ; ++i)
{
response = SD_MMC_Send_Command(CMD_GO_IDLE_STATE , 0 );
if( response == 0x01 )
break;

        if(i == 0x1ff)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}

/* wait for card to get ready */
for(u16 i = 0; ; ++i)
{
response = SD_MMC_Send_Command(CMD_SEND_OP_COND, 0);
if(!(response & (1 << R1_IDLE_STATE)))
break;

        if(i == 0x7fff)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}

    /* set block size to 512 bytes */
if(SD_MMC_Send_Command(CMD_SET_BLOCKLEN, 512))
{
SD_MMC_SPI_DESELECT();
return 1;
}

    /* deaddress card */
SD_MMC_SPI_DESELECT();

    /* switch to highest SPI frequency possible */
SD_MMC_High_Speed();

return 0;
//////////////////////////////////////////////////////////////////////////////
}
 

/*******************************************************************************
* Function Name : SD_MMC_Read_Single_Block
* Description    : SD_MMC_Read_Single_Block
* Input          : sector number and buffer data point
* Output         : None
* Return         : zero success, non-zero error
*******************************************************************************/
u8 SD_MMC_Read_Single_Block(u32 sector, u8* buffer)
{
u8 Response;
u16 i;
u16 Retry = 0;

         //读命令 send read command
Response = SD_MMC_Send_Command(CMD_READ_SINGLE_BLOCK, sector<<9);

        if(Response != 0x00)
return Response;

        SD_MMC_SPI_SELECT();

        // start byte 0xfe
while(SD_MMC_ReadWrite_Byte(0xff) != 0xfe)
{
if(++Retry > 0xfffe)
{
SD_MMC_SPI_DESELECT();
return 1; //timeout
}
}

        for(i = 0; i < 512; ++i)
{
//Read 512 data
*buffer++ = SD_MMC_ReadWrite_Byte(0xff);
}

        SD_MMC_ReadWrite_Byte(0xff); //伪crc
SD_MMC_ReadWrite_Byte(0xff); //伪crc

        SD_MMC_SPI_DESELECT();
SD_MMC_ReadWrite_Byte(0xff); // extra 8 CLK

        return 0;
}


/*******************************************************************************
* Function Name : SD_MMC_Write_Single_Block
* Description    : SD_MMC_Write_Single_Block
* Input          : sector number and buffer data point
* Output         : None
* Return         : zero success, non-zero error.
*******************************************************************************/
u8 SD_MMC_Write_Single_Block(u32 sector, u8* buffer)
{
u8 Response;
u16 i;
u16 retry=0;

//写命令 send write command
Response = SD_MMC_Send_Command(CMD_WRITE_SINGLE_BLOCK, sector<<9);
if(Response != 0x00)
return Response;

SD_MMC_SPI_SELECT();

SD_MMC_ReadWrite_Byte(0xff);
SD_MMC_ReadWrite_Byte(0xff);
SD_MMC_ReadWrite_Byte(0xff);

        //发开始符 start byte 0xfe
SD_MMC_ReadWrite_Byte(0xfe);

//送512字节数据 send 512 bytes data
for(i=0; i<512; i++)
{
SD_MMC_ReadWrite_Byte(*buffer++);
}

SD_MMC_ReadWrite_Byte(0xff); //dummy crc
SD_MMC_ReadWrite_Byte(0xff); //dummy crc

Response = SD_MMC_ReadWrite_Byte(0xff);

//等待是否成功 judge if it successful
if( (Response&0x1f) != 0x05)
{
SD_MMC_SPI_DESELECT();
return Response;
}
//等待操作完 wait no busy
while(SD_MMC_ReadWrite_Byte(0xff) != 0x00)
{
if(retry++ > 0xfffe)
{
SD_MMC_SPI_DESELECT();
return 1;
}
}
SD_MMC_SPI_DESELECT();
SD_MMC_ReadWrite_Byte(0xff);// extra 8 CLK

return 0;
}

 

if( SD_MMC_SPI_Init() ==1)
printf(" _SD_MMC Initialization ERROR\r\n");
else
{
printf(" _SD_MMC Initialization OK\r\n");
//memset(buffer,0,512);
//Read the contents of a sector. Here, sector 0 is read.
SD_MMC_Read_Single_Block( 0 , buffer );
Uart1_PutString( buffer , 512 );
}

  STM32 SD card_no file system added - liuyunqian@yeah - Embedded Learning

Keywords:STM32 Reference address:STM32 SD card_no file system added

Previous article:6 steps to teach you how to add printf function in STM32 program
Next article:STM32 DMA learning

Recommended ReadingLatest update time:2024-11-17 02:42

Online debugging STM32 stuck in LDR R0, = SystemInit_ExtMemCtl
The program is stuck in the online debugging STM32 stuck in LDR R0, = SystemInit_ExtMemCtl. The solution is as follows: The most common situation is that there are too many breakpoints set. You can try deleting all breakpoints and setting the breakpoint in the main function. If you use C library (printf) in your pr
[Microcontroller]
What are AHB bus, APB2 bus and APB1 bus in STM32?
 I still don't understand what the AHB bus, APB2 bus, and APB1 bus are in STM32 ? The so-called address mapping is to establish a one-to-one correspondence between the memory and even I/O resources on the chip and the address. Corresponding to a certain register, we can use the C language pointer to address and mo
[Microcontroller]
STM32 Self-study Notes - External Interrupts
Each IO port of stm32 can be used as an entry for external interrupts. The interrupt controller of stm32f103 supports 19 external interrupt/event requests (question 1: What is the difference between external interrupts and time requests?). Among these 19 external interrupts, 0-15 correspond to the input interrupts of
[Microcontroller]
Basic use of DMA in stm32
What is DMA used for?        Direct memory access is used to provide high-speed data transfer between peripherals and memory or between memory and memory. Data can be moved quickly through DMA without CPU intervention. This saves CPU resources for other operations. How many DMA resources are there?        There
[Microcontroller]
Basic use of DMA in stm32
STM32 uses DAC+DMA+TIMER to output sine wave
The board used is STM32F407, and the program refers to the program in the DAC_SignalsGeneration folder of the STM32F4xx firmware library. The official routines use the Escalator Wave trapezoidal wave, Sine Wave sine wave of the DAC's disabled generation wave (DAC_WaveGeneration_None) and the built-in Noise Wave (DAC_W
[Microcontroller]
STM32 uses DAC+DMA+TIMER to output sine wave
STM32 interrupt configuration
The basic steps to use external interrupts in STM32 are as follows: 1. Set the corresponding clock; 2. Set the corresponding interrupt; 3.IO port initialization; 4. Set the corresponding IO port as the interrupt line (before setting the external interrupt) and initialize it; 5. Interrupt function in the response funct
[Microcontroller]
Winter vacation study of stm32 (17) ---- SPI communication protocol
Background knowledge: wiki:  http://wiki.csie.ncku.edu.tw/embedded/SPI#introduction Baidu: http://baike.baidu.com/item/SPI   Must read it!!! Small summary: 1. Communication mode: SPI is a high-speed, full-duplex, synchronous communication bus, and only occupies four lines on the chip pins (SDI, SDO, SCLK, CS) MISO
[Microcontroller]
Winter vacation study of stm32 (17) ---- SPI communication protocol
STM32 RTC (Real Time Clock) 32.768kHz Crystal Oscillator Start-up Guide
It is an industry consensus that the STM32 RTC crystal oscillator often fails to oscillate. Many people ask for help on various electronic forums with questions like "Ask an expert for advice! What should I do if the RTC crystal oscillator does not oscillate?", and the answer can basically be summarized as "The expert
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号