/***********************************************************************************
SPI模式 读写SD卡
SD卡初始化过程:
1. 初始化STM32的SPI接口 使用低速模式 2. 延时至少74clock
3. 发送CMD0,需要返回0x01,进入Idle状态
4. 循环发送CMD55+ACMD41,直到返回0x00,进入Ready状态 5. 设置读写block大小为512byte 5. 把STM32的SPI设置为高速模式
读一个block块的过程
1. 发送CMD17(单块)或CMD18(多块)读命令,返回0x00 2. 接收数据开始令牌0xfe + 正式数据512Bytes + CRC 校验2Bytes
写一个block块的过程
1. 发送CMD24(单块)或CMD25(多块)写命令,返回0x00 2. 发送数据开始令牌0xfe + 正式数据512Bytes + CRC校验2Bytes
-----------------------------------------------------------------------------
* ----------------------------------------------
* | STM32F10x | MSD Pin | * ----------------------------------------------
* | PE.3 | ChipSelect 1 | * | PA.7 / MOSI | DataIn 2 | * | | GND 3 (0 V) | * | | VDD 4 (3.3 V) | * | PA.5 / SCLK | Clock 5 | * | | GND 6 (0 V) | * | PA.6 / MISO | DataOut 7 |
* -----------------------------------------------
***********************************************************************************/
/* Includes ------------------------------------------------------------------*/ //#include \#include \ #include \
/* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define sd_cs_1 GPIO_SetBits(GPIOB,GPIO_Pin_12) #define sd_cs_0 GPIO_ResetBits(GPIOB,GPIO_Pin_12)
#define sd_check GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15)
/* Select MSD Card: ChipSelect pin low */
//#define MSD_CS_LOW() GPIO_ResetBits(GPIOE, GPIO_Pin_3) /* Deselect MSD Card: ChipSelect pin high */
//#define MSD_CS_HIGH() GPIO_SetBits(GPIOE, GPIO_Pin_3)
//SD传输数据结束后是否释放总线宏定义 #define NO_RELEASE 0 #define RELEASE 1 // SD卡类型定义
#define SD_TYPE_MMC 0 #define SD_TYPE_V1 1 #define SD_TYPE_V2 2 #define SD_TYPE_V2HC 4
// SD卡指令表
#define CMD0 0 //卡复位 #define CMD1 1
#define CMD9 9 //命令9 ,读CSD数据 #define CMD10 10 //命令10,读CID数据
#define CMD12 12 //命令12,停止数据传输
#define CMD16 16 //命令16,设置SectorSize 应返回0x00 #define CMD17 17 //命令17,读sector
#define CMD18 18 //命令18,读Multi sector
#define ACMD23 23 //命令23,设置多sector写入前预先擦除N个block #define CMD24 24 //命令24,写sector
#define CMD25 25 //命令25,写Multi sector #define ACMD41 41 //命令41,应返回0x00 #define CMD55 55 //命令55,应返回0x01
#define CMD58 58 //命令58,读OCR信息
#define CMD59 59 //命令59,使能/禁止CRC,应返回0x00 //数据写入回应字意义
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B #define MSD_DATA_WRITE_ERROR 0x0D #define MSD_DATA_OTHER_ERROR 0xFF //SD卡回应标记字
#define MSD_RESPONSE_NO_ERROR 0x00 #define MSD_IN_IDLE_STATE 0x01 #define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04 #define MSD_COM_CRC_ERROR 0x08 #define MSD_ERASE_SEQUENCE_ERROR 0x10 #define MSD_ADDRESS_ERROR 0x20 #define MSD_PARAMETER_ERROR 0x40 #define MSD_RESPONSE_FAILURE 0xFF
#define Dummy_Byte 0xA5 //0xff
/* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ //u8 Dummy_Byte = 0xa5; //0xff; u8 SD_Type; //SD卡的类型
u8 buf[512];
/* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ FlagStatus sd_insert_check(void);
u8 SD_WaitReady(void); //等待SD卡就绪
u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令 u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); u8 SD_Init(void); //SD卡初始化
u8 SD_Idle_Sta(void); //设置SD卡到挂起模式
u8 SD_ReceiveData(u8 *data, u16 len, u8 release);//SD卡读数据 u8 SD_GetCID(u8 *cid_data); //读SD卡CID u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD u32 SD_GetCapacity(void); //取SD卡容量 //USB 读卡器 SD卡操作函数
//u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite); //u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead); u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sector u8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sector u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sector
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count);//写多个sector
u8 SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes);//读取一byte
//--------------------------------spi speed setting-------------------------
/*******************************************************************************
* Function Name : SPI_Config
* Description : Initializes the SPI1 and CS pins. * Input : None * Output : None * Return : None
*******************************************************************************/
void SPI_Config(u16 BaudRatePrescaler) {
GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure;
/* GPIOA and GPIOC Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); /* SPI1 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* Configure SPI2 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure PE3 pin: CS pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_12);
/* SPI1 Config */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = BaudRatePrescaler; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure);
/* SPI1 enable */
SPI_Cmd(SPI2, ENABLE); }
void spi_high_speed(void) {
//SPI_InitStructure.SPI_BaudRatePrescaler
SPI_BaudRatePrescaler_4;//SPI_BaudRatePrescaler_256; //SPI_Init(SPI2, &SPI_InitStructure); SPI_Config(SPI_BaudRatePrescaler_4); }
void spi_low_speed(void)
{
//SPI_InitStructure.SPI_BaudRatePrescaler
SPI_BaudRatePrescaler_256;//SPI_BaudRatePrescaler_4; //SPI_Init(SPI2, &SPI_InitStructure);
SPI_Config(SPI_BaudRatePrescaler_256); }
//---------------sd_insert_check--------------------------- FlagStatus sd_insert_check(void) {
FlagStatus card_exist_state; if(!sd_check)
{
card_exist_state = SET; } else {
card_exist_state = RESET; }
return card_exist_state; }
=
=