GET CSDinfo

SDHC card get info from CSD

    /**    
      * @brief  Read the CSD card register.
      *         Reading the contents of the CSD register in SPI mode is a simple 
      *         read-block transaction.
      * @param  SD_csd: pointer on an CSD register structure
  * @retval The SD Response: 
  *         - SD_RESPONSE_FAILURE: Sequence failed
  *         - SD_RESPONSE_NO_ERROR: Sequence succeed
  */
 SD_GetCSDRegister(SD_CSD* SD_csd)
{
  ulong i = 0;
  rvalue = SD_RESPONSE_FAILURE;
  uchar CSD_Tab[16];

  /*!< SD chip select low */
  SD_CS_LOW();
  /*!< Send CMD9 (CSD register) or CMD10(CSD register) */
  SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF);
  /*!< Wait for response in the R1 format (0x00 is no errors) */
  if (!SD_GetResponse(SD_RESPONSE_NO_ERROR))
  {
    if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ))
    {
      for (i = 0; i < 16; i++)
      {
        /*!< Store CSD register value on CSD_Tab */
        CSD_Tab[i] = SD_Read_Sector_Data();
      }
    }
    /*!< Get CRC bytes (not really needed by us, but required by SD) */
     Spi_Send_Byte(0xff); 
     Spi_Send_Byte(0xff); 
    /*!< Set response value to success */
    rvalue = SD_RESPONSE_NO_ERROR;
  }
  /*!< SD chip select high */
  SD_CS_HIGH();
  /*!< Send dummy byte: 8 Clock pulses of delay */
   Spi_Send_Byte(0xff); 

  /*!< Byte 0 */
  SD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
  SD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
  SD_csd->Reserved1 = CSD_Tab[0] & 0x03;

  /*!< Byte 1 */
  SD_csd->TAAC = CSD_Tab[1];

  /*!< Byte 2 */
  SD_csd->NSAC = CSD_Tab[2];

  /*!< Byte 3 */
  SD_csd->MaxBusClkFrec = CSD_Tab[3];

  /*!< Byte 4 */
  SD_csd->CardComdClasses = CSD_Tab[4] << 4;

  /*!< Byte 5 */
  SD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
  SD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;

  /*!< Byte 6 */
  SD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
  SD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
  SD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
  SD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
  SD_csd->Reserved2 = 0; /*!< Reserved */

  SD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;

    //V1  V1.0
  if ((SD_Type == SD_TYPE_V1) || (SD_Type == SD_TYPE_V2))
    {
        /*!< Byte 7 */
        SD_csd->DeviceSize |= (CSD_Tab[7]) << 2;

        /*!< Byte 8 */
        SD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;

        SD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
        SD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);

        /*!< Byte 9 */
        SD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
        SD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
        SD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
        /*!< Byte 10 */
        SD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
  }
    //SDHC V2.0
    else if (SD_Type == SD_TYPE_V2HC)
    {
        SD_csd->DeviceSize = (CSD_Tab[7] & 0x3F) << 16;

        SD_csd->DeviceSize |= (CSD_Tab[8] << 8);

        SD_csd->DeviceSize |= (CSD_Tab[9]);     
    }


  SD_csd->EraseGrSize = (CSD_Tab[10] & 0x40) >> 6;
  SD_csd->EraseGrMul = (CSD_Tab[10] & 0x3F) << 1;

  /*!< Byte 11 */
  SD_csd->EraseGrMul |= (CSD_Tab[11] & 0x80) >> 7;
  SD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F);

  /*!< Byte 12 */
  SD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
  SD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
  SD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
  SD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;

  /*!< Byte 13 */
  SD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xC0) >> 6;
  SD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
  SD_csd->Reserved3 = 0;
  SD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);

  /*!< Byte 14 */
  SD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
  SD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
  SD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
  SD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
  SD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
  SD_csd->ECC = (CSD_Tab[14] & 0x03);

  /*!< Byte 15 */
  SD_csd->CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1;
  SD_csd->Reserved4 = 1;

  /*!< Return the reponse */
  return rvalue;
}

`

    /**  
      * @brief  Card Specific Data: CSD Register   in "SD.h" file
      */    
    typedef struct
    {
      volatile uchar  CSDStruct;            /*!< CSD structure */
      volatile uchar  SysSpecVersion;       /*!< System specification version */
      volatile uchar  Reserved1;            /*!< Reserved */
      volatile uchar  TAAC;                 /*!< Data read access-time 1 */
      volatile uchar  NSAC;                 /*!< Data read access-time 2 in CLK cycles */
      volatile uchar  MaxBusClkFrec;        /*!< Max. bus clock frequency */
      volatile uint   CardComdClasses;      /*!< Card command classes */
      volatile uchar  RdBlockLen;           /*!< Max. read data block length */
      volatile uchar  PartBlockRead;        /*!< Partial blocks for read allowed */
      volatile uchar  WrBlockMisalign;      /*!< Write block misalignment */
      volatile uchar  RdBlockMisalign;      /*!< Read block misalignment */
      volatile uchar  DSRImpl;              /*!< DSR implemented */
      volatile uchar  Reserved2;            /*!< Reserved */
      volatile ulong  DeviceSize;           /*!< Device Size */
      volatile uchar  MaxRdCurrentVDDMin;   /*!< Max. read current @ VDD min */
      volatile uchar  MaxRdCurrentVDDMax;   /*!< Max. read current @ VDD max */
      volatile uchar  MaxWrCurrentVDDMin;   /*!< Max. write current @ VDD min */
      volatile uchar  MaxWrCurrentVDDMax;   /*!< Max. write current @ VDD max */
      volatile uchar  DeviceSizeMul;        /*!< Device size multiplier */
      volatile uchar  EraseGrSize;          /*!< Erase group size */
      volatile uchar  EraseGrMul;           /*!< Erase group size multiplier */
      volatile uchar  WrProtectGrSize;      /*!< Write protect group size */
      volatile uchar  WrProtectGrEnable;    /*!< Write protect group enable */
      volatile uchar  ManDeflECC;           /*!< Manufacturer default ECC */
      volatile uchar  WrSpeedFact;          /*!< Write speed factor */
      volatile uchar  MaxWrBlockLen;        /*!< Max. write data block length */
      volatile uchar  WriteBlockPaPartial;  /*!< Partial blocks for write allowed */
      volatile uchar  Reserved3;            /*!< Reserded */
      volatile uchar  ContentProtectAppli;  /*!< Content protection application */
      volatile uchar  FileFormatGrouop;     /*!< File format group */
      volatile uchar  CopyFlag;             /*!< Copy flag (OTP) */
      volatile uchar  PermWrProtect;        /*!< Permanent write protection */
      volatile uchar  TempWrProtect;        /*!< Temporary write protection */
      volatile uchar  FileFormat;           /*!< File Format */
      volatile uchar  ECC;                  /*!< ECC code */
      volatile uchar  CSD_CRC;              /*!< CSD CRC */
      volatile uchar  Reserved4;            /*!< always 1*/
    } SD_CSD;

key points

key word

volatile :易挥发的、不稳定的 、反复无常的量。 用这个关键词修饰之后就这些值不会随着编译器的编译而改变
编译器有两种编译方式:Debug和release 一个是调试版本,一个是发布版本。调试版本在编译的时候不会做任何修改,以便于发现漏洞,发布版本会做各种优化,以达到最快的运行速度和其他的性能指标。导致某些变量会在不确定的情况下改变,用volatile 修饰过的变量不会改变,每次读取他的时候都是直接访问内存上的值,不会访问在寄存器上的备份值。
简单的辨析volatileconst(常数) 前者修饰的词在编译器(将C语言编译成汇编再变化成机器码) 期间不能变化在运行期间(机器码在CPU中运行的时候) 也不能变化。 被后者修饰的词只作用在编译器期间告诉编译器这是一个常量,在机器码时,const不存在,没有作用。

struct

结构体

将不同的数据类型的数据组成一个结构体。
有三种形式:

  1. 只有结构体定义

     struct stuff{
    
                 uchar job[20];
                 uint sex;
                 ulong age;
                 };
    
  2. 有结构体变量

    struct stuff{
    
                 uchar job[20];
                 uint sex;
                 ulong age;
                 }stf;
    

    这种结构相当于

     struct stuff{
    
                 uchar job[20];
                 uint sex;
                 ulong age;
                 };
     struct stuff stf;//现在这一句定义的是这个结构体的变量名是 *stf* 这一句单独存在表的是,这句如果单独使用表示的意思是这个结构体只有一个成员就是stf。
    
  3. 去掉结构体名称的方式更简洁
    struct {

                 uchar job[20];
                 uint sex;
                 ulong age;
                 }stf;
    

结构体的引用

两种方式:

- 通过“.”引用 赋值

     struct {

                 uchar job[20];
                 uint sex;
                 ulong age;
                 }stf;
stf.job[0]='M';
stf.age = 27;
  • 通过“->” 引用赋值
  • stf->job[0]='M'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值