|
- void SD_LowLevel_DeInit(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- SPI_Cmd(SD_SPI, DISABLE); /*!< SD_SPI disable */
- SPI_DeInit(SD_SPI); /*!< DeInitializes the SD_SPI */
-
- /*!< SD_SPI Periph clock disable */
- RCC_APB1PeriphClockCmd(SD_SPI_CLK, DISABLE);
- /*!< Configure SD_SPI pins: SCK */
- GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(SD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
- /*!< Configure SD_SPI pins: MISO */
- GPIO_InitStructure.GPIO_Pin = SD_SPI_MISO_PIN;
- GPIO_Init(SD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
- /*!< Configure SD_SPI pins: MOSI */
- GPIO_InitStructure.GPIO_Pin = SD_SPI_MOSI_PIN;
- GPIO_Init(SD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
- /*!< Configure SD_SPI_CS_PIN pin: SD Card CS pin */
- GPIO_InitStructure.GPIO_Pin = SD_CS_PIN;
- GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure);
- /*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
- // GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
- // GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
- }
复制代码SPI初始化,应该没有什么问题,sd卡 的读文件,创建文件,和删除文件功能都是正常的
- SD_Error SD_Init(void)
- {
- uint32_t i = 0;
- uint8_t r1 = 0;
- uint16_t retry = 0;
- uint8_t buf[4];
- //SPI_InitTypeDef SPI_InitStructure;
- //logout("sd init\r\n");
- /*!< Initialize SD_SPI */
- for(i=0;i<0xf00;i++);
- //logout("SD_LowLevel_Init done\r\n");
- /*!< SD chip select high */
-
- SPI2_SetSpeed(SPI_BaudRatePrescaler_256);
- /*!< Send dummy byte 0xFF, 10 times with CS high */
- /*!< Rise CS and MOSI for 80 clocks cycles */
- for(i=0;i<10;i++)SD_ReadWriteByte(0XFF);//发送最少74个脉冲
- retry=20;
- do
- {
- r1 = SD_SendCmd1(SD_CMD_GO_IDLE_STATE,0,0x95);//进入IDLE状态
- }while((r1!=0X01) && retry--);
- //logout("SD_idle_pass\r\n");
- //logout("R1 = %d\r\n",r1);
- SD_Type=0;//默认无卡
-
- if(r1==0X01)
- {
- //logout("1111");
- if(SD_SendCmd1(SD_CMD_SEND_IF_COND,0x1AA,0x87)==1)//SD V2.0
- {
- for(i=0;i<4;i++)buf[i]=SD_ReadWriteByte(0XFF); //Get trailing return value of R7 resp
- if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V
- {
- retry=0XFFFE;
- do
- {
- SD_SendCmd1(55,0,0X01); //发送CMD55
- r1=SD_SendCmd1(41,0x40000000,0X01);//发送CMD41
- }while(r1&&retry--);
- if(retry&&SD_SendCmd1(58,0,0X01)==0)//鉴别SD2.0卡版本开始
- {
- for(i=0;i<4;i++)buf[i]=SD_ReadWriteByte(0XFF);//得到OCR值
- if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //检查CCS
- else SD_Type=SD_TYPE_V2;
- }
- }
- }
- else//SD V1.x/ MMC V3
- {
- //logout("222");
- SD_SendCmd1(55,0,0X01); //发送CMD55
- r1=SD_SendCmd1(41,0,0X01); //发送CMD41
- if(r1<=1)
- {
- SD_Type=SD_TYPE_V1;
- retry=0XFFFE;
- do //等待退出IDLE模式
- {
- SD_SendCmd1(55,0,0X01); //发送CMD55
- r1=SD_SendCmd1(41,0,0X01);//发送CMD41
- }while(r1&&retry--);
- }else//MMC卡不支持CMD55+CMD41识别
- {
- SD_Type=SD_TYPE_MMC;//MMC V3
- logout("MMC");
- retry=0XFFFE;
- do //等待退出IDLE模式
- {
- r1=SD_SendCmd1(1,0,0X01);//发送CMD1
- }while(r1&&retry--);
- }
- if(retry==0||SD_SendCmd1(16,512,0X01)!=0)SD_Type=SD_TYPE_ERR,logout("fau");//错误的卡
- }
- }
- SD_DisSelect();//取消片选
- SPI2_SetSpeed(SPI_BaudRatePrescaler_2);
- if(SD_Type)
- {
- //logout("0");
- return 0;
- }
- else if(r1)
- {
- logout("R1 = %d\r\n",r1);
- return r1;
- }
-
- }
复制代码
SD卡 的初始化仿照f103的写的
- uint8_t SD_SendCmd1(uint8_t cmd, uint32_t arg, uint8_t crc)
- {
- uint8_t r1;
- uint8_t Retry=0;
- SD_DisSelect();//取消上次片选
- if(SD_Select())return 0XFF;//片选失效
- //发送
- SD_ReadWriteByte(cmd | 0x40);//分别写入命令
- SD_ReadWriteByte(arg >> 24);
- SD_ReadWriteByte(arg >> 16);
- SD_ReadWriteByte(arg >> 8);
- SD_ReadWriteByte(arg);
- SD_ReadWriteByte(crc);
- if(cmd==SD_CMD_STOP_TRANSMISSION)SD_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
- //等待响应,或超时退出
- Retry=0X1F;
- do
- {
- r1=SD_ReadWriteByte(0xff);
- }while((r1&0X80) && Retry--);
- //返回状态值
- return r1;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //取消选择,释放SPI总线
- void SD_DisSelect(void)
- {
- SD_CS_HIGH();
- SD_ReadWriteByte(0xff);//提供额外的8个时钟
- }
- //选择sd卡,并且等待卡准备OK
- //返回值:0,成功;1,失败;
- uint8_t SD_Select(void)
- {
- SD_CS_LOW();
- if(SD_WaitReady()==0)return 0;//等待成功
- SD_DisSelect();
- return 1;//等待失败
- }
- //等待卡准备好
- //返回值:0,准备好了;其他,错误代码
- uint8_t SD_WaitReady(void)
- {
- uint32_t t=0;
- do
- {
- if(SD_ReadWriteByte(0XFF)==0XFF)return 0;//OK
- t++;
- }while(t<0XFFFFFF);//等待
- return 1;
- }
- uint32_t SD_GetSectorCount(void)
- {
- uint8_t csd[16];
- uint32_t Capacity;
- uint8_t n;
- uint16_t csize;
- //取CSD信息,如果期间出错,返回0
- if(SD_GetCSD(csd)!=0)
- {
- logout("csd fail\r\n");
- return 0;
- }
- //如果为SDHC卡,按照下面方式计算
- if((csd[0]&0xC0)==0x40) //V2.00的卡
- {
- csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;
- Capacity = (uint32_t)csize << 10;//得到扇区数
- }else//V1.XX的卡
- {
- n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
- csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
- Capacity= (uint32_t)csize << (n - 9);//得到扇区数
- }
- return Capacity;
- }
- //获取SD卡的CSD信息,包括容量和速度信息
- //输入:uint8_t *cid_data(存放CID的内存,至少16Byte)
- //返回值:0:NO_ERR
- // 1:错误
- uint8_t SD_GetCSD(uint8_t *csd_data)
- {
- uint8_t r1;
- logout("gCSD1\r\n");
- r1 = SD_SendCmd1(SD_CMD_SEND_CSD,0,0x01);//发CMD9命令,读CSD
- logout("gCSD2\r\n");
- if(r1==0)
- {
- r1= SD_RecvData(csd_data, 16);//接收16个字节的数据
- }
- SD_DisSelect();//取消片选
- if(r1)return 1;
- else return 0;
- }
- //从sd卡读取一个数据包的内容
- //buf:数据缓存区
- //len:要读取的数据长度.
- //返回值:0,成功;其他,失败;
- uint8_t SD_RecvData(uint8_t *buf,uint16_t len)
- {
- if(SD_GetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE
- while(len--)//开始接收数据
- {
- *buf=SD_ReadWriteByte(0xFF);
- buf++;
- }
- //下面是2个伪CRC(dummy CRC)
- SD_ReadWriteByte(0xFF);
- SD_ReadWriteByte(0xFF);
- return 0;//读取成功
- }
- void SPI2_SetSpeed(uint8_t SpeedSet)
- {
- SPI_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;
- SPI_Init(SPI2, &SPI_InitStructure);
- SPI_Cmd(SPI2,ENABLE);
- }
- //读SD卡
- //buf:数据缓存区
- //sector:扇区
- //cnt:扇区数
- //返回值:0,ok;其他,失败.
- uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)
- {
- uint8_t r1;
- if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址
- if(cnt==1)
- {
- r1=SD_SendCmd1(SD_CMD_READ_SINGLE_BLOCK,sector,0X01);//读命令
- if(r1==0)//指令发送成功
- {
- r1=SD_RecvData(buf,512);//接收512个字节
- }
- }else
- {
- r1=SD_SendCmd1(SD_CMD_READ_MULT_BLOCK,sector,0X01);//连续读命令
- do
- {
- r1=SD_RecvData(buf,512);//接收512个字节
- buf+=512;
- }while(--cnt && r1==0);
- SD_SendCmd(SD_CMD_STOP_TRANSMISSION,0,0X01); //发送停止命令
- }
- SD_DisSelect();//取消片选
- return r1;//
- }
- //写SD卡
- //buf:数据缓存区
- //sector:起始扇区
- //cnt:扇区数
- //返回值:0,ok;其他,失败.
- uint8_t SD_WriteDisk(const uint8_t*buf,uint32_t sector,uint8_t cnt)
- {
- uint8_t r1;
- if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//转换为字节地址
- if(cnt==1)
- {
- r1=SD_SendCmd1(SD_CMD_WRITE_SINGLE_BLOCK,sector,0X01);//读命令
- if(r1==0)//指令发送成功
- {
- r1=SD_SendBlock(buf,0xFE);//写512个字节
- }
- }else
- {
- if(SD_Type!=SD_TYPE_MMC)
- {
- SD_SendCmd1(55,0,0X01);
- SD_SendCmd1(SD_CMD_SET_BLOCK_COUNT,cnt,0X01);//发送指令
- }
- r1=SD_SendCmd1(SD_CMD_WRITE_MULT_BLOCK,sector,0X01);//连续读命令
- if(r1==0)
- {
- do
- {
- r1=SD_SendBlock(buf,0xFC);//接收512个字节
- buf+=512;
- }while(--cnt && r1==0);
- r1=SD_SendBlock(0,0xFD);//接收512个字节
- }
- }
- SD_DisSelect();//取消片选
- return r1;//
- }
- uint8_t SD_SendBlock(const uint8_t *buf,uint8_t cmd)
- {
- uint16_t t;
- if(SD_WaitReady())return 1;//等待准备失效
- SD_ReadWriteByte(cmd);
- if(cmd!=0XFD)//不是结束指令
- {
- for(t=0;t<512;t++)SD_ReadWriteByte(buf[t]);//提高速度,减少函数传参时间
- SD_ReadWriteByte(0xFF);//忽略crc
- SD_ReadWriteByte(0xFF);
- t=SD_ReadWriteByte(0xFF);//接收响应
- if((t&0x1F)!=0x05)return 2;//响应错误
- }
- return 0;//写入成功
- }
复制代码
后面的这些也是照着写的
|
|