找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2379|回复: 1
打印 上一主题 下一主题
收起左侧

STM32F407VET6采集AD数据,保存到SD卡中 源程序

[复制链接]
跳转到指定楼层
楼主
ID:241682 发表于 2021-11-28 06:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. //单片机采用STM32F407VET6 ad采集数据,并将数据保存到sd中
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "usart.h"
  5. #include "led.h"
  6. #include "key.h"
  7. #include "adc.h"
  8. #include "sdio_sdcard.h"      
  9. #include "ff.h"  
  10. #include "exfuns.h"  
  11. #include "string.h"
  12. int main(void)
  13. {
  14.     float temp;
  15. u8 i,res;
  16. u8 ADc_Buff[200]=0;
  17. u8 ADc_temp[20]=0;
  18. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  19. delay_init(168);  //延时初始化
  20. uart_init(115200);     //串口初始化波特率为115200
  21. LED_Init();      //初始化与LED连接的硬件接口  
  22. Adc_Init();             //初始化ADC

  23. SD_Init();
  24. exfuns_init();      //为fatfs相关变量申请内存     
  25.     f_mount(fs[0],"0:",1);  //挂载SD卡
  26.   res=mf_open("0:/123/ADcData.txt",FA_OPEN_ALWAYS | FA_READ | FA_WRITE );//创建或打开一个文本文档保存数据
  27. res=mf_open("0:/ADcData.txt",FA_OPEN_ALWAYS | FA_READ | FA_WRITE );//创建或打开一个文本文档保存数据
  28. if(res==FR_OK)
  29.     {
  30.   printf("文件已经存在!\r\n");
  31. }
  32. else
  33. {
  34.   printf("建立该文件!\r\n");
  35. }

  36. while(1)
  37. {
  38.   for(i=0;i<8;i++)
  39.   {
  40.    temp=(float)(Get_Adc_Average(i,20))*(3.3/4096);   //获取计算后的带小数的实际电压值,比如3.1111
  41.    printf("通道%d=%f\r\n",i,temp);
  42.    sprintf(ADc_temp,"%f|",temp);
  43.    strcat(ADc_Buff,ADc_temp);  
  44.   }
  45.   strcat(ADc_Buff,"\r\n");
  46.   mf_lseek(mf_size());                  //将指针定位于文件尾部,准备追加数据
  47.   mf_write(ADc_Buff,strlen(ADc_Buff));  //将接收到的数据存入文件
  48.   mf_sync();   
  49.   
  50.   delay_ms(2000);
  51.   memset(ADc_temp,0,20);
  52.   memset(ADc_Buff,0,200);
  53.    mf_close( );
  54. }
  55. }
  56. #include "sdio_sdcard.h"
  57. #include "string.h"  
  58.    

  59. /*用于sdio初始化的结构体*/
  60. SDIO_InitTypeDef SDIO_InitStructure;
  61. SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
  62. SDIO_DataInitTypeDef SDIO_DataInitStructure;   
  63. SD_Error CmdError(void);  
  64. SD_Error CmdResp7Error(void);
  65. SD_Error CmdResp1Error(u8 cmd);
  66. SD_Error CmdResp3Error(void);
  67. SD_Error CmdResp2Error(void);
  68. SD_Error CmdResp6Error(u8 cmd,u16*prca);  
  69. SD_Error SDEnWideBus(u8 enx);   
  70. SD_Error IsCardProgramming(u8 *pstatus);
  71. SD_Error FindSCR(u16 rca,u32 *pscr);
  72. u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes);

  73. static u8 CardType=SDIO_STD_CAPACITY_SD_CARD_V1_1;  //SD卡类型(默认为1.x卡)
  74. static u32 CSD_Tab[4],CID_Tab[4],RCA=0;     //SD卡CSD,CID以及相对地址(RCA)数据
  75. static u8 DeviceMode=SD_DMA_MODE;         //工作模式,注意,工作模式必须通过SD_SetDeviceMode,后才算数.这里只是定义一个默认的模式(SD_DMA_MODE)
  76. static u8 StopCondition=0;         //是否发送停止传输标志位,DMA多块读写的时候用到  
  77. volatile SD_Error TransferError=SD_OK;     //数据传输错误标志,DMA读写时使用     
  78. volatile u8 TransferEnd=0;        //传输结束标志,DMA读写时使用
  79. SD_CardInfo SDCardInfo; //SD卡信息
  80. //THUMB指令不支持汇编内联
  81. //采用如下方法实现执行汇编指令WFI  
  82. __asm void WFI_SET(void)
  83. {
  84. WFI;   
  85. }
  86. //关闭所有中断(但是不包括fault和NMI中断)
  87. __asm void INTX_DISABLE(void)
  88. {
  89. CPSID   I
  90. BX      LR   
  91. }
  92. //开启所有中断
  93. __asm void INTX_ENABLE(void)
  94. {
  95. CPSIE   I
  96. BX      LR  
  97. }
  98. //设置栈顶地址
  99. //addr:栈顶地址
  100. __asm void MSR_MSP(u32 addr)
  101. {
  102. MSR MSP, r0    //set Main Stack value
  103. BX r14
  104. }
  105. //SD_ReadDisk/SD_WriteDisk函数专用buf,当这两个函数的数据缓存区地址不是4字节对齐的时候,
  106. //需要用到该数组,确保数据缓存区地址是4字节对齐的.
  107. __align(4) u8 SDIO_DATA_BUFFER[512];        


  108. void SDIO_Register_Deinit()
  109. {
  110. SDIO->POWER=0x00000000;
  111. SDIO->CLKCR=0x00000000;
  112. SDIO->ARG=0x00000000;
  113. SDIO->CMD=0x00000000;
  114. SDIO->DTIMER=0x00000000;
  115. SDIO->DLEN=0x00000000;
  116. SDIO->DCTRL=0x00000000;
  117. SDIO->ICR=0x00C007FF;
  118. SDIO->MASK=0x00000000;  
  119. }
  120. //初始化SD卡
  121. //返回值:错误代码;(0,无错误)
  122. SD_Error SD_Init(void)
  123. {
  124.   GPIO_InitTypeDef  GPIO_InitStructure;
  125. NVIC_InitTypeDef NVIC_InitStructure;

  126. SD_Error errorstatus=SD_OK;  
  127.   

  128.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_DMA2, ENABLE);//使能GPIOC,GPIOD DMA2时钟

  129.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);//SDIO时钟使能

  130. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE);//SDIO复位


  131.   GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;  //PC8,9,10,11,12复用功能输出
  132.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  133.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100M
  134.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  135.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  136.   GPIO_Init(GPIOC, &GPIO_InitStructure);// PC8,9,10,11,12复用功能输出

  137. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2;
  138.   GPIO_Init(GPIOD, &GPIO_InitStructure);//PD2复用功能输出

  139.   //引脚复用映射设置
  140. GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_SDIO); //PC8,AF12
  141.   GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_SDIO);
  142.   GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_SDIO);
  143.   GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_SDIO);
  144.   GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_SDIO);
  145.   GPIO_PinAFConfig(GPIOD,GPIO_PinSource2,GPIO_AF_SDIO);

  146. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE);//SDIO结束复位
  147.   
  148.   //SDIO外设寄存器设置为默认值      
  149. SDIO_Register_Deinit();

  150.   NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
  151. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3
  152. NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;  //子优先级3
  153. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
  154. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、

  155.     errorstatus=SD_PowerON();   //SD卡上电
  156.   if(errorstatus==SD_OK)errorstatus=SD_InitializeCards();   //初始化SD卡               
  157.    if(errorstatus==SD_OK)errorstatus=SD_GetCardInfo(&SDCardInfo); //获取卡信息
  158.   if(errorstatus==SD_OK)errorstatus=SD_SelectDeselect((u32)(SDCardInfo.RCA<<16));//选中SD卡   
  159.     if(errorstatus==SD_OK)errorstatus=SD_EnableWideBusOperation(SDIO_BusWide_4b); //4位宽度,如果是MMC卡,则不能用4位模式
  160.    if((errorstatus==SD_OK)||(SDIO_MULTIMEDIA_CARD==CardType))
  161. {        
  162.   SDIO_Clock_Set(SDIO_TRANSFER_CLK_DIV);   //设置时钟频率,SDIO时钟计算公式:SDIO_CK时钟=SDIOCLK/[clkdiv+2];其中,SDIOCLK固定为48Mhz
  163.   //errorstatus=SD_SetDeviceMode(SD_DMA_MODE); //设置为DMA模式
  164.   errorstatus=SD_SetDeviceMode(SD_POLLING_MODE);//设置为查询模式
  165.   }
  166. return errorstatus;   
  167. }
  168. //SDIO时钟初始化设置
  169. //clkdiv:时钟分频系数
  170. //CK时钟=SDIOCLK/[clkdiv+2];(SDIOCLK时钟固定为48Mhz)
  171. void SDIO_Clock_Set(u8 clkdiv)
  172. {
  173. u32 tmpreg=SDIO->CLKCR;
  174.    tmpreg&=0XFFFFFF00;
  175.   tmpreg|=clkdiv;   
  176. SDIO->CLKCR=tmpreg;
  177. }

  178. //卡上电
  179. //查询所有SDIO接口上的卡设备,并查询其电压和配置时钟
  180. //返回值:错误代码;(0,无错误)
  181. SD_Error SD_PowerON(void)
  182. {
  183.   u8 i=0;
  184. SD_Error errorstatus=SD_OK;
  185. u32 response=0,count=0,validvoltage=0;
  186. u32 SDType=SD_STD_CAPACITY;

  187.   /*初始化时的时钟不能大于400KHz*/
  188.   SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV; /* HCLK = 72MHz, SDIOCLK = 72MHz, SDIO_CK = HCLK/(178 + 2) = 400 KHz */
  189.   SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
  190.   SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;  //不使用bypass模式,直接用HCLK进行分频得到SDIO_CK
  191.   SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; // 空闲时不关闭时钟电源
  192.   SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;      //1位数据线
  193.   SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;//硬件流
  194.   SDIO_Init(&SDIO_InitStructure);
  195. SDIO_SetPowerState(SDIO_PowerState_ON); //上电状态,开启卡时钟   
  196.   SDIO->CLKCR|=1<<8;   //SDIOCK使能  

  197.   for(i=0;i<74;i++)
  198. {

  199.   SDIO_CmdInitStructure.SDIO_Argument = 0x0;//发送CMD0进入IDLE STAGE模式命令.
  200.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE; //cmd0
  201.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;  //无响应
  202.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  203.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;  //则CPSM在开始发送命令之前等待数据传输结束。
  204.     SDIO_SendCommand(&SDIO_CmdInitStructure);     //写命令进命令寄存器
  205.   
  206.   errorstatus=CmdError();
  207.   
  208.   if(errorstatus==SD_OK)break;
  209.   }
  210.   if(errorstatus)return errorstatus;//返回错误状态

  211.   SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN; //发送CMD8,短响应,检查SD卡接口特性
  212.   SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND; //cmd8
  213.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r7
  214.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;    //关闭等待中断
  215.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  216.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  217.   errorstatus=CmdResp7Error();      //等待R7响应

  218.   if(errorstatus==SD_OK)         //R7响应正常
  219. {
  220.   CardType=SDIO_STD_CAPACITY_SD_CARD_V2_0;  //SD 2.0卡
  221.   SDType=SD_HIGH_CAPACITY;         //高容量卡
  222. }
  223.    
  224.    SDIO_CmdInitStructure.SDIO_Argument = 0x00;//发送CMD55,短响应
  225.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
  226.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  227.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  228.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  229.     SDIO_SendCommand(&SDIO_CmdInitStructure);  //发送CMD55,短响应  

  230.   errorstatus=CmdResp1Error(SD_CMD_APP_CMD);     //等待R1响应   

  231. if(errorstatus==SD_OK)//SD2.0/SD 1.1,否则为MMC卡
  232. {                  
  233.   //SD卡,发送ACMD41 SD_APP_OP_COND,参数为:0x80100000
  234.   while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
  235.   {                 
  236.     SDIO_CmdInitStructure.SDIO_Argument = 0x00;//发送CMD55,短响应
  237.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;   //CMD55
  238.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  239.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  240.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  241.       SDIO_SendCommand(&SDIO_CmdInitStructure);   //发送CMD55,短响应  
  242.    
  243.    errorstatus=CmdResp1Error(SD_CMD_APP_CMD);    //等待R1响应  
  244.    
  245.     if(errorstatus!=SD_OK)return errorstatus;    //响应错误
  246.       //acmd41,命令参数由支持的电压范围及HCS位组成,HCS位置一来区分卡是SDSc还是sdhc
  247.       SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDType; //发送ACMD41,短响应
  248.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_OP_COND;
  249.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r3
  250.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  251.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  252.       SDIO_SendCommand(&SDIO_CmdInitStructure);
  253.    
  254.    errorstatus=CmdResp3Error();      //等待R3响应   
  255.    
  256.     if(errorstatus!=SD_OK)return errorstatus;    //响应错误
  257.    response=SDIO->RESP1;;          //得到响应
  258.    validvoltage=(((response>>31)==1)?1:0);   //判断SD卡上电是否完成
  259.    count++;
  260.   }
  261.   if(count>=SD_MAX_VOLT_TRIAL)
  262.   {
  263.    errorstatus=SD_INVALID_VOLTRANGE;
  264.    return errorstatus;
  265.   }  
  266.   if(response&=SD_HIGH_CAPACITY)
  267.   {
  268.    CardType=SDIO_HIGH_CAPACITY_SD_CARD;
  269.   }
  270.   }else//MMC卡
  271. {
  272.   //MMC卡,发送CMD1 SDIO_SEND_OP_COND,参数为:0x80FF8000
  273.   while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
  274.   {                        
  275.    SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_MMC;//发送CMD1,短响应   
  276.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_OP_COND;
  277.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r3
  278.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  279.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  280.       SDIO_SendCommand(&SDIO_CmdInitStructure);
  281.    
  282.    errorstatus=CmdResp3Error();      //等待R3响应   
  283.    
  284.     if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  285.    response=SDIO->RESP1;;          //得到响应
  286.    validvoltage=(((response>>31)==1)?1:0);
  287.    count++;
  288.   }
  289.   if(count>=SD_MAX_VOLT_TRIAL)
  290.   {
  291.    errorstatus=SD_INVALID_VOLTRANGE;
  292.    return errorstatus;
  293.   }         
  294.   CardType=SDIO_MULTIMEDIA_CARD;   
  295.    }  
  296.    return(errorstatus);  
  297. }
  298. //SD卡 Power OFF
  299. //返回值:错误代码;(0,无错误)
  300. SD_Error SD_PowerOFF(void)
  301. {

  302.   SDIO_SetPowerState(SDIO_PowerState_OFF);//SDIO电源关闭,时钟停止
  303.   return SD_OK;   
  304. }   
  305. //初始化所有的卡,并让卡进入就绪状态
  306. //返回值:错误代码
  307. SD_Error SD_InitializeCards(void)
  308. {
  309.   SD_Error errorstatus=SD_OK;
  310. u16 rca = 0x01;

  311.   if (SDIO_GetPowerState() == SDIO_PowerState_OFF) //检查电源状态,确保为上电状态
  312.   {
  313.     errorstatus = SD_REQUEST_NOT_APPLICABLE;
  314.     return(errorstatus);
  315.   }
  316.   if(SDIO_SECURE_DIGITAL_IO_CARD!=CardType)   //非SECURE_DIGITAL_IO_CARD
  317. {
  318.   SDIO_CmdInitStructure.SDIO_Argument = 0x0;//发送CMD2,取得CID,长响应
  319.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_ALL_SEND_CID;
  320.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
  321.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  322.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  323.     SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD2,取得CID,长响应
  324.   
  325.   errorstatus=CmdResp2Error();      //等待R2响应
  326.   
  327.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误   
  328.   
  329.    CID_Tab[0]=SDIO->RESP1;
  330.   CID_Tab[1]=SDIO->RESP2;
  331.   CID_Tab[2]=SDIO->RESP3;
  332.   CID_Tab[3]=SDIO->RESP4;
  333. }
  334. if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_SECURE_DIGITAL_IO_COMBO_CARD==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))//判断卡类型
  335. {
  336.   SDIO_CmdInitStructure.SDIO_Argument = 0x00;//发送CMD3,短响应
  337.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_REL_ADDR; //cmd3
  338.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r6
  339.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  340.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  341.     SDIO_SendCommand(&SDIO_CmdInitStructure); //发送CMD3,短响应
  342.   
  343.   errorstatus=CmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);//等待R6响应
  344.   
  345.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误      
  346. }   
  347.     if (SDIO_MULTIMEDIA_CARD==CardType)
  348.     {
  349.     SDIO_CmdInitStructure.SDIO_Argument = (u32)(rca<<16);//发送CMD3,短响应
  350.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_REL_ADDR; //cmd3
  351.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r6
  352.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  353.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  354.       SDIO_SendCommand(&SDIO_CmdInitStructure); //发送CMD3,短响应  
  355.    
  356.       errorstatus=CmdResp2Error();      //等待R2响应   
  357.    
  358.     if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  359.     }
  360. if (SDIO_SECURE_DIGITAL_IO_CARD!=CardType)   //非SECURE_DIGITAL_IO_CARD
  361. {
  362.   RCA = rca;
  363.   
  364.     SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)(rca << 16);//发送CMD9+卡RCA,取得CSD,长响应
  365.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_CSD;
  366.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long;
  367.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  368.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  369.     SDIO_SendCommand(&SDIO_CmdInitStructure);
  370.   
  371.   errorstatus=CmdResp2Error();      //等待R2响应   
  372.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误      
  373.    
  374.   CSD_Tab[0]=SDIO->RESP1;
  375.    CSD_Tab[1]=SDIO->RESP2;
  376.   CSD_Tab[2]=SDIO->RESP3;      
  377.   CSD_Tab[3]=SDIO->RESP4;         
  378. }
  379. return SD_OK;//卡初始化成功
  380. }
  381. //得到卡信息
  382. //cardinfo:卡信息存储区
  383. //返回值:错误状态
  384. SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
  385. {
  386.   SD_Error errorstatus=SD_OK;
  387. u8 tmp=0;   
  388. cardinfo->CardType=(u8)CardType;     //卡类型
  389. cardinfo->RCA=(u16)RCA;       //卡RCA值
  390. tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
  391. cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6;  //CSD结构
  392. cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2; //2.0协议还没定义这部分(为保留),应该是后续协议定义的
  393. cardinfo->SD_csd.Reserved1=tmp&0x03;   //2个保留位  
  394. tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);   //第1个字节
  395. cardinfo->SD_csd.TAAC=tmp;         //数据读时间1
  396. tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);     //第2个字节
  397. cardinfo->SD_csd.NSAC=tmp;        //数据读时间2
  398. tmp=(u8)(CSD_Tab[0]&0x000000FF);    //第3个字节
  399. cardinfo->SD_csd.MaxBusClkFrec=tmp;      //传输速度   
  400. tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24);   //第4个字节
  401. cardinfo->SD_csd.CardComdClasses=tmp<<4;     //卡指令类高四位
  402. tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16);    //第5个字节
  403. cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;//卡指令类低四位
  404. cardinfo->SD_csd.RdBlockLen=tmp&0x0F;      //最大读取数据长度
  405. tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8);   //第6个字节
  406. cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7; //允许分块读
  407. cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6; //写块错位
  408. cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5; //读块错位
  409. cardinfo->SD_csd.DSRImpl=(tmp&0x10)>>4;
  410. cardinfo->SD_csd.Reserved2=0;      //保留
  411.   if((CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1)||(CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)||(SDIO_MULTIMEDIA_CARD==CardType))//标准1.1/2.0卡/MMC卡
  412. {
  413.   cardinfo->SD_csd.DeviceSize=(tmp&0x03)<<10; //C_SIZE(12位)
  414.    tmp=(u8)(CSD_Tab[1]&0x000000FF);    //第7个字节
  415.   cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
  416.    tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);  //第8个字节
  417.   cardinfo->SD_csd.DeviceSize|=(tmp&0xC0)>>6;
  418.    cardinfo->SD_csd.MaxRdCurrentVDDMin=(tmp&0x38)>>3;
  419.   cardinfo->SD_csd.MaxRdCurrentVDDMax=(tmp&0x07);
  420.    tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);  //第9个字节
  421.   cardinfo->SD_csd.MaxWrCurrentVDDMin=(tmp&0xE0)>>5;
  422.   cardinfo->SD_csd.MaxWrCurrentVDDMax=(tmp&0x1C)>>2;
  423.   cardinfo->SD_csd.DeviceSizeMul=(tmp&0x03)<<1;//C_SIZE_MULT
  424.    tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);    //第10个字节
  425.   cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
  426.    cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);//计算卡容量
  427.   cardinfo->CardCapacity*=(1<<(cardinfo->SD_csd.DeviceSizeMul+2));
  428.   cardinfo->CardBlockSize=1<<(cardinfo->SD_csd.RdBlockLen);//块大小
  429.   cardinfo->CardCapacity*=cardinfo->CardBlockSize;
  430. }else if(CardType==SDIO_HIGH_CAPACITY_SD_CARD) //高容量卡
  431. {
  432.    tmp=(u8)(CSD_Tab[1]&0x000000FF);   //第7个字节
  433.   cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;//C_SIZE
  434.    tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);  //第8个字节
  435.    cardinfo->SD_csd.DeviceSize|=(tmp<<8);
  436.    tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16); //第9个字节
  437.    cardinfo->SD_csd.DeviceSize|=(tmp);
  438.    tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);  //第10个字节
  439.    cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;//计算卡容量
  440.   cardinfo->CardBlockSize=512;    //块大小固定为512字节
  441. }   
  442. cardinfo->SD_csd.EraseGrSize=(tmp&0x40)>>6;
  443. cardinfo->SD_csd.EraseGrMul=(tmp&0x3F)<<1;   
  444. tmp=(u8)(CSD_Tab[2]&0x000000FF);   //第11个字节
  445. cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
  446. cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
  447.   tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24);  //第12个字节
  448. cardinfo->SD_csd.WrProtectGrEnable=(tmp&0x80)>>7;
  449. cardinfo->SD_csd.ManDeflECC=(tmp&0x60)>>5;
  450. cardinfo->SD_csd.WrSpeedFact=(tmp&0x1C)>>2;
  451. cardinfo->SD_csd.MaxWrBlockLen=(tmp&0x03)<<2;  
  452. tmp=(u8)((CSD_Tab[3]&0x00FF0000)>>16);  //第13个字节
  453. cardinfo->SD_csd.MaxWrBlockLen|=(tmp&0xC0)>>6;
  454. cardinfo->SD_csd.WriteBlockPaPartial=(tmp&0x20)>>5;
  455. cardinfo->SD_csd.Reserved3=0;
  456. cardinfo->SD_csd.ContentProtectAppli=(tmp&0x01);  
  457. tmp=(u8)((CSD_Tab[3]&0x0000FF00)>>8);  //第14个字节
  458. cardinfo->SD_csd.FileFormatGrouop=(tmp&0x80)>>7;
  459. cardinfo->SD_csd.CopyFlag=(tmp&0x40)>>6;
  460. cardinfo->SD_csd.PermWrProtect=(tmp&0x20)>>5;
  461. cardinfo->SD_csd.TempWrProtect=(tmp&0x10)>>4;
  462. cardinfo->SD_csd.FileFormat=(tmp&0x0C)>>2;
  463. cardinfo->SD_csd.ECC=(tmp&0x03);  
  464. tmp=(u8)(CSD_Tab[3]&0x000000FF);   //第15个字节
  465. cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
  466. cardinfo->SD_csd.Reserved4=1;   
  467. tmp=(u8)((CID_Tab[0]&0xFF000000)>>24);  //第0个字节
  468. cardinfo->SD_cid.ManufacturerID=tmp;      
  469. tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16);  //第1个字节
  470. cardinfo->SD_cid.OEM_AppliID=tmp<<8;   
  471. tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8);  //第2个字节
  472. cardinfo->SD_cid.OEM_AppliID|=tmp;     
  473. tmp=(u8)(CID_Tab[0]&0x000000FF);   //第3个字节
  474. cardinfo->SD_cid.ProdName1=tmp<<24;      
  475. tmp=(u8)((CID_Tab[1]&0xFF000000)>>24);   //第4个字节
  476. cardinfo->SD_cid.ProdName1|=tmp<<16;   
  477. tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16);     //第5个字节
  478. cardinfo->SD_cid.ProdName1|=tmp<<8;   
  479. tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8);  //第6个字节
  480. cardinfo->SD_cid.ProdName1|=tmp;     
  481. tmp=(u8)(CID_Tab[1]&0x000000FF);     //第7个字节
  482. cardinfo->SD_cid.ProdName2=tmp;     
  483. tmp=(u8)((CID_Tab[2]&0xFF000000)>>24);   //第8个字节
  484. cardinfo->SD_cid.ProdRev=tmp;   
  485. tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16);  //第9个字节
  486. cardinfo->SD_cid.ProdSN=tmp<<24;   
  487. tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8);   //第10个字节
  488. cardinfo->SD_cid.ProdSN|=tmp<<16;   
  489. tmp=(u8)(CID_Tab[2]&0x000000FF);      //第11个字节
  490. cardinfo->SD_cid.ProdSN|=tmp<<8;     
  491. tmp=(u8)((CID_Tab[3]&0xFF000000)>>24);   //第12个字节
  492. cardinfo->SD_cid.ProdSN|=tmp;        
  493. tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16);   //第13个字节
  494. cardinfo->SD_cid.Reserved1|=(tmp&0xF0)>>4;
  495. cardinfo->SD_cid.ManufactDate=(tmp&0x0F)<<8;   
  496. tmp=(u8)((CID_Tab[3]&0x0000FF00)>>8);  //第14个字节
  497. cardinfo->SD_cid.ManufactDate|=tmp;      
  498. tmp=(u8)(CID_Tab[3]&0x000000FF);   //第15个字节
  499. cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
  500. cardinfo->SD_cid.Reserved2=1;  
  501. return errorstatus;
  502. }
  503. //设置SDIO总线宽度(MMC卡不支持4bit模式)
  504. //wmode:位宽模式.0,1位数据宽度;1,4位数据宽度;2,8位数据宽度
  505. //返回值:SD卡错误状态
  506. //设置SDIO总线宽度(MMC卡不支持4bit模式)
  507. //   @arg SDIO_BusWide_8b: 8-bit data transfer (Only for MMC)
  508. //   @arg SDIO_BusWide_4b: 4-bit data transfer
  509. //   @arg SDIO_BusWide_1b: 1-bit data transfer (默认)
  510. //返回值:SD卡错误状态

  511. SD_Error SD_EnableWideBusOperation(u32 WideMode)
  512. {
  513.    SD_Error errorstatus=SD_OK;
  514.   if (SDIO_MULTIMEDIA_CARD == CardType)
  515.   {
  516.     errorstatus = SD_UNSUPPORTED_FEATURE;
  517.     return(errorstatus);
  518.   }

  519.   else if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
  520. {
  521.    if (SDIO_BusWide_8b == WideMode)   //2.0 sd不支持8bits
  522.     {
  523.       errorstatus = SD_UNSUPPORTED_FEATURE;
  524.       return(errorstatus);
  525.     }
  526.    else   
  527.   {
  528.    errorstatus=SDEnWideBus(WideMode);
  529.     if(SD_OK==errorstatus)
  530.    {
  531.     SDIO->CLKCR&=~(3<<11);  //清除之前的位宽设置   
  532.     SDIO->CLKCR|=WideMode;//1位/4位总线宽度
  533.     SDIO->CLKCR|=0<<14;   //不开启硬件流控制
  534.    }
  535.   }  
  536. }
  537. return errorstatus;
  538. }
  539. //设置SD卡工作模式
  540. //Mode:
  541. //返回值:错误状态
  542. SD_Error SD_SetDeviceMode(u32 Mode)
  543. {
  544. SD_Error errorstatus = SD_OK;
  545.   if((Mode==SD_DMA_MODE)||(Mode==SD_POLLING_MODE))DeviceMode=Mode;
  546. else errorstatus=SD_INVALID_PARAMETER;
  547. return errorstatus;     
  548. }
  549. //选卡
  550. //发送CMD7,选择相对地址(rca)为addr的卡,取消其他卡.如果为0,则都不选择.
  551. //addr:卡的RCA地址
  552. SD_Error SD_SelectDeselect(u32 addr)
  553. {
  554.   SDIO_CmdInitStructure.SDIO_Argument =  addr;//发送CMD7,选择卡,短响应
  555.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEL_DESEL_CARD;
  556.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  557.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  558.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  559.   SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD7,选择卡,短响应

  560.   return CmdResp1Error(SD_CMD_SEL_DESEL_CARD);   
  561. }
  562. //SD卡读取一个块
  563. //buf:读数据缓存区(必须4字节对齐!!)
  564. //addr:读取地址
  565. //blksize:块大小
  566. SD_Error SD_ReadBlock(u8 *buf,long long addr,u16 blksize)
  567. {   
  568. SD_Error errorstatus=SD_OK;
  569. u8 power;
  570.   u32 count=0,*tempbuff=(u32*)buf;//转换为u32指针
  571. u32 timeout=SDIO_DATATIMEOUT;   
  572.   if(NULL==buf)
  573.   return SD_INVALID_PARAMETER;
  574.   SDIO->DCTRL=0x0; //数据控制寄存器清零(关DMA)
  575.   
  576. if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
  577. {
  578.   blksize=512;
  579.   addr>>=9;
  580. }   
  581.    SDIO_DataInitStructure.SDIO_DataBlockSize= SDIO_DataBlockSize_1b ;//清除DPSM状态机配置
  582.    SDIO_DataInitStructure.SDIO_DataLength= 0 ;
  583.    SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  584.    SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  585.    SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  586.    SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  587.     SDIO_DataConfig(&SDIO_DataInitStructure);


  588. if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
  589. if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
  590. {
  591.   power=convert_from_bytes_to_power_of_two(blksize);
  592.   
  593.    
  594.   SDIO_CmdInitStructure.SDIO_Argument =  blksize;
  595.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  596.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  597.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  598.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  599.     SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD16+设置数据长度为blksize,短响应
  600.   
  601.   
  602.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
  603.   
  604.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误
  605.   
  606. }else return SD_INVALID_PARAMETER;     

  607.    SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4 ;//清除DPSM状态机配置
  608.    SDIO_DataInitStructure.SDIO_DataLength= blksize ;
  609.    SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  610.    SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  611.    SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
  612.    SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  613.     SDIO_DataConfig(&SDIO_DataInitStructure);

  614.    SDIO_CmdInitStructure.SDIO_Argument =  addr;
  615.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
  616.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  617.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  618.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  619.     SDIO_SendCommand(&SDIO_CmdInitStructure);//发送CMD17+从addr地址出读取数据,短响应

  620. errorstatus=CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);//等待R1响应   
  621. if(errorstatus!=SD_OK)return errorstatus;     //响应错误  
  622.   if(DeviceMode==SD_POLLING_MODE)      //查询模式,轮询数据  
  623. {
  624.    INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
  625.   while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
  626.   {
  627.    if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)      //接收区半满,表示至少存了8个字
  628.    {
  629.     for(count=0;count<8;count++)   //循环读取数据
  630.     {
  631.      *(tempbuff+count)=SDIO->FIFO;
  632.     }
  633.     tempbuff+=8;  
  634.     timeout=0X7FFFFF;  //读数据溢出时间
  635.    }else  //处理超时
  636.    {
  637.     if(timeout==0)return SD_DATA_TIMEOUT;
  638.     timeout--;
  639.    }
  640.   }
  641.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //数据超时错误
  642.   {            
  643.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清错误标志
  644.    return SD_DATA_TIMEOUT;
  645.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
  646.   {
  647.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  648.    return SD_DATA_CRC_FAIL;     
  649.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢错误
  650.   {
  651.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清错误标志
  652.    return SD_RX_OVERRUN;   
  653.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位错误
  654.   {
  655.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
  656.    return SD_START_BIT_ERR;   
  657.   }   
  658.   while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) //FIFO里面,还存在可用数据
  659.   {
  660.    *tempbuff=SDIO->FIFO; //循环读取数据
  661.    tempbuff++;
  662.   }
  663.   INTX_ENABLE();//开启总中断
  664.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  665.   
  666. }else if(DeviceMode==SD_DMA_MODE)
  667. {
  668.    TransferError=SD_OK;
  669.   StopCondition=0;   //单块读,不需要发送停止传输指令
  670.   TransferEnd=0;    //传输结束标置位,在中断服务置1
  671.   SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9); //配置需要的中断
  672.    SDIO->DCTRL|=1<<3;    //SDIO DMA使能
  673.       SD_DMA_Config((u32*)buf,blksize,DMA_DIR_PeripheralToMemory);
  674.    while(((DMA2->LISR&(1<<27))==RESET)&&(TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;//等待传输完成
  675.   if(timeout==0)return SD_DATA_TIMEOUT;//超时
  676.   if(TransferError!=SD_OK)errorstatus=TransferError;  
  677.     }   
  678.   return errorstatus;
  679. }
  680. //SD卡读取多个块
  681. //buf:读数据缓存区
  682. //addr:读取地址
  683. //blksize:块大小
  684. //nblks:要读取的块数
  685. //返回值:错误状态
  686. __align(4) u32 *tempbuff;
  687. SD_Error SD_ReadMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
  688. {
  689.   SD_Error errorstatus=SD_OK;
  690. u8 power;
  691.   u32 count=0;
  692. u32 timeout=SDIO_DATATIMEOUT;  
  693. tempbuff=(u32*)buf;//转换为u32指针

  694.   SDIO->DCTRL=0x0;  //数据控制寄存器清零(关DMA)   
  695. if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
  696. {
  697.   blksize=512;
  698.   addr>>=9;
  699. }  

  700.    SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;//清除DPSM状态机配置
  701.    SDIO_DataInitStructure.SDIO_DataLength= 0 ;
  702.    SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  703.    SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  704.    SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  705.    SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  706.     SDIO_DataConfig(&SDIO_DataInitStructure);

  707. if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
  708. if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
  709. {
  710.   power=convert_from_bytes_to_power_of_two(blksize);     
  711.   
  712.    SDIO_CmdInitStructure.SDIO_Argument =  blksize;//发送CMD16+设置数据长度为blksize,短响应
  713.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  714.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  715.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  716.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  717.   SDIO_SendCommand(&SDIO_CmdInitStructure);
  718.   
  719.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应  
  720.   
  721.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  722.   
  723. }else return SD_INVALID_PARAMETER;   

  724. if(nblks>1)           //多块读  
  725. {            
  726.      if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;//判断是否超过最大接收长度
  727.   
  728.      SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;//nblks*blksize,512块大小,卡到控制器
  729.     SDIO_DataInitStructure.SDIO_DataLength= nblks*blksize ;
  730.     SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  731.     SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  732.     SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
  733.     SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  734.     SDIO_DataConfig(&SDIO_DataInitStructure);
  735.        SDIO_CmdInitStructure.SDIO_Argument =  addr;//发送CMD18+从addr地址出读取数据,短响应
  736.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_MULT_BLOCK;
  737.      SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  738.      SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  739.      SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  740.      SDIO_SendCommand(&SDIO_CmdInitStructure);
  741.   
  742.   errorstatus=CmdResp1Error(SD_CMD_READ_MULT_BLOCK);//等待R1响应
  743.   
  744.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  745.   
  746.    if(DeviceMode==SD_POLLING_MODE)
  747.   {
  748.    INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
  749.    while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<8)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
  750.    {
  751.     if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)      //接收区半满,表示至少存了8个字
  752.     {
  753.      for(count=0;count<8;count++)   //循环读取数据
  754.      {
  755.       *(tempbuff+count)=SDIO->FIFO;
  756.      }
  757.      tempbuff+=8;  
  758.      timeout=0X7FFFFF;  //读数据溢出时间
  759.     }else  //处理超时
  760.     {
  761.      if(timeout==0)return SD_DATA_TIMEOUT;
  762.      timeout--;
  763.     }
  764.    }  
  765.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //数据超时错误
  766.   {            
  767.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清错误标志
  768.    return SD_DATA_TIMEOUT;
  769.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
  770.   {
  771.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  772.    return SD_DATA_CRC_FAIL;     
  773.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢错误
  774.   {
  775.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清错误标志
  776.    return SD_RX_OVERRUN;   
  777.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位错误
  778.   {
  779.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
  780.    return SD_START_BIT_ERR;   
  781.   }   
  782.      
  783.   while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) //FIFO里面,还存在可用数据
  784.   {
  785.    *tempbuff=SDIO->FIFO; //循环读取数据
  786.    tempbuff++;
  787.   }
  788.     if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)  //接收结束
  789.    {
  790.     if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
  791.     {   
  792.      SDIO_CmdInitStructure.SDIO_Argument =  0;//发送CMD12+结束传输
  793.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
  794.      SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  795.      SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  796.      SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  797.      SDIO_SendCommand(&SDIO_CmdInitStructure);
  798.      
  799.      errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//等待R1响应   
  800.      
  801.      if(errorstatus!=SD_OK)return errorstatus;  
  802.     }
  803.     }
  804.    INTX_ENABLE();//开启总中断
  805.     SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  806.    }else if(DeviceMode==SD_DMA_MODE)
  807.   {
  808.       TransferError=SD_OK;
  809.    StopCondition=1;   //多块读,需要发送停止传输指令
  810.    TransferEnd=0;    //传输结束标置位,在中断服务置1
  811.    SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<5)|(1<<9); //配置需要的中断
  812.     SDIO->DCTRL|=1<<3;         //SDIO DMA使能
  813.        SD_DMA_Config((u32*)buf,nblks*blksize,DMA_DIR_PeripheralToMemory);
  814.     while(((DMA2->LISR&(1<<27))==RESET)&&timeout)timeout--;//等待传输完成
  815.    if(timeout==0)return SD_DATA_TIMEOUT;//超时
  816.    while((TransferEnd==0)&&(TransferError==SD_OK));
  817.    if(TransferError!=SD_OK)errorstatus=TransferError;   
  818.   }   
  819.    }
  820. return errorstatus;
  821. }                        
  822. //SD卡写1个块
  823. //buf:数据缓存区
  824. //addr:写地址
  825. //blksize:块大小   
  826. //返回值:错误状态
  827. SD_Error SD_WriteBlock(u8 *buf,long long addr,  u16 blksize)
  828. {
  829. SD_Error errorstatus = SD_OK;

  830. u8  power=0,cardstate=0;

  831. u32 timeout=0,bytestransferred=0;

  832. u32 cardstatus=0,count=0,restwords=0;

  833. u32 tlen=blksize;      //总长度(字节)

  834. u32*tempbuff=(u32*)buf;     

  835.   if(buf==NULL)return SD_INVALID_PARAMETER;//参数错误  

  836.   SDIO->DCTRL=0x0;       //数据控制寄存器清零(关DMA)

  837. SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;//清除DPSM状态机配置
  838. SDIO_DataInitStructure.SDIO_DataLength= 0 ;
  839. SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  840. SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  841. SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  842. SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  843.   SDIO_DataConfig(&SDIO_DataInitStructure);


  844. if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
  845.   if(CardType==SDIO_HIGH_CAPACITY_SD_CARD) //大容量卡
  846. {
  847.   blksize=512;
  848.   addr>>=9;
  849. }   
  850. if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
  851. {
  852.   power=convert_from_bytes_to_power_of_two(blksize);
  853.   
  854.   SDIO_CmdInitStructure.SDIO_Argument = blksize;//发送CMD16+设置数据长度为blksize,短响应  
  855.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  856.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  857.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  858.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  859.   SDIO_SendCommand(&SDIO_CmdInitStructure);
  860.   
  861.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应  
  862.   
  863.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  864.   
  865. }else return SD_INVALID_PARAMETER;

  866.    SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应  
  867.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  868.    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  869.    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  870.    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  871.    SDIO_SendCommand(&SDIO_CmdInitStructure);
  872.    errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);  //等待R1响应  

  873. if(errorstatus!=SD_OK)return errorstatus;
  874. cardstatus=SDIO->RESP1;               
  875. timeout=SD_DATATIMEOUT;
  876.     while(((cardstatus&0x00000100)==0)&&(timeout>0))  //检查READY_FOR_DATA位是否置位
  877. {
  878.   timeout--;  
  879.   
  880.   SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应
  881.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  882.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  883.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  884.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  885.   SDIO_SendCommand(&SDIO_CmdInitStructure);
  886.   
  887.   errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //等待R1响应   
  888.   
  889.   if(errorstatus!=SD_OK)return errorstatus;  
  890.   
  891.   cardstatus=SDIO->RESP1;               
  892. }
  893. if(timeout==0)return SD_ERROR;
  894.    SDIO_CmdInitStructure.SDIO_Argument = addr;//发送CMD24,写单块指令,短响应  
  895.    SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
  896.    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  897.    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  898.    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  899.    SDIO_SendCommand(&SDIO_CmdInitStructure);

  900. errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//等待R1响应  

  901. if(errorstatus!=SD_OK)return errorstatus;     

  902. StopCondition=0;         //单块写,不需要发送停止传输指令
  903. SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ; //blksize, 控制器到卡
  904. SDIO_DataInitStructure.SDIO_DataLength= blksize ;
  905. SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  906. SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  907. SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  908. SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  909.   SDIO_DataConfig(&SDIO_DataInitStructure);


  910. timeout=SDIO_DATATIMEOUT;

  911. if (DeviceMode == SD_POLLING_MODE)
  912. {
  913.   INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
  914.   while(!(SDIO->STA&((1<<10)|(1<<4)|(1<<1)|(1<<3)|(1<<9))))//数据块发送成功/下溢/CRC/超时/起始位错误
  915.   {
  916.    if(SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)       //发送区半空,表示至少存了8个字
  917.    {
  918.     if((tlen-bytestransferred)<SD_HALFFIFOBYTES)//不够32字节了
  919.     {
  920.      restwords=((tlen-bytestransferred)%4==0)?((tlen-bytestransferred)/4):((tlen-bytestransferred)/4+1);
  921.      
  922.      for(count=0;count<restwords;count++,tempbuff++,bytestransferred+=4)
  923.      {
  924.       SDIO->FIFO=*tempbuff;
  925.      }
  926.     }else
  927.     {
  928.      for(count=0;count<8;count++)
  929.      {
  930.       SDIO->FIFO=*(tempbuff+count);
  931.      }
  932.      tempbuff+=8;
  933.      bytestransferred+=32;
  934.     }
  935.     timeout=0X3FFFFFFF; //写数据溢出时间
  936.    }else
  937.    {
  938.     if(timeout==0)return SD_DATA_TIMEOUT;
  939.     timeout--;
  940.    }
  941.   }
  942.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //数据超时错误
  943.   {            
  944.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清错误标志
  945.    return SD_DATA_TIMEOUT;
  946.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
  947.   {
  948.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  949.    return SD_DATA_CRC_FAIL;     
  950.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)  //接收fifo下溢错误
  951.   {
  952.     SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);  //清错误标志
  953.    return SD_TX_UNDERRUN;   
  954.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位错误
  955.   {
  956.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
  957.    return SD_START_BIT_ERR;   
  958.   }   
  959.       
  960.   INTX_ENABLE();//开启总中断
  961.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记  
  962. }else if(DeviceMode==SD_DMA_MODE)
  963. {
  964.      TransferError=SD_OK;
  965.   StopCondition=0;   //单块写,不需要发送停止传输指令
  966.   TransferEnd=0;    //传输结束标置位,在中断服务置1
  967.   SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9); //配置产生数据接收完成中断
  968.   SD_DMA_Config((u32*)buf,blksize,DMA_DIR_MemoryToPeripheral);    //SDIO DMA配置
  969.     SDIO->DCTRL|=1<<3;        //SDIO DMA使能.  
  970.    while(((DMA2->LISR&(1<<27))==RESET)&&timeout)timeout--;//等待传输完成
  971.   if(timeout==0)
  972.   {
  973.      SD_Init();       //重新初始化SD卡,可以解决写入死机的问题
  974.    return SD_DATA_TIMEOUT;   //超时  
  975.    }
  976.   timeout=SDIO_DATATIMEOUT;
  977.   while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
  978.    if(timeout==0)return SD_DATA_TIMEOUT;   //超时  
  979.     if(TransferError!=SD_OK)return TransferError;
  980.   }  
  981.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  982.   errorstatus=IsCardProgramming(&cardstate);
  983.   while((errorstatus==SD_OK)&&((cardstate==SD_CARD_PROGRAMMING)||(cardstate==SD_CARD_RECEIVING)))
  984. {
  985.   errorstatus=IsCardProgramming(&cardstate);
  986. }   
  987. return errorstatus;
  988. }
  989. //SD卡写多个块
  990. //buf:数据缓存区
  991. //addr:写地址
  992. //blksize:块大小
  993. //nblks:要写入的块数
  994. //返回值:错误状态               
  995. SD_Error SD_WriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
  996. {
  997. SD_Error errorstatus = SD_OK;
  998. u8  power = 0, cardstate = 0;
  999. u32 timeout=0,bytestransferred=0;
  1000. u32 count = 0, restwords = 0;
  1001. u32 tlen=nblks*blksize;    //总长度(字节)
  1002. u32 *tempbuff = (u32*)buf;  
  1003.   if(buf==NULL)return SD_INVALID_PARAMETER; //参数错误  
  1004.   SDIO->DCTRL=0x0;       //数据控制寄存器清零(关DMA)   

  1005. SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ; //清除DPSM状态机配置
  1006. SDIO_DataInitStructure.SDIO_DataLength= 0 ;
  1007. SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  1008. SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  1009. SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  1010. SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  1011.   SDIO_DataConfig(&SDIO_DataInitStructure);

  1012. if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
  1013.   if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
  1014. {
  1015.   blksize=512;
  1016.   addr>>=9;
  1017. }   
  1018. if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
  1019. {
  1020.   power=convert_from_bytes_to_power_of_two(blksize);
  1021.   
  1022.   SDIO_CmdInitStructure.SDIO_Argument = blksize; //发送CMD16+设置数据长度为blksize,短响应
  1023.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  1024.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1025.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1026.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1027.   SDIO_SendCommand(&SDIO_CmdInitStructure);
  1028.   
  1029.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应  
  1030.   
  1031.   if(errorstatus!=SD_OK)return errorstatus;    //响应错误  
  1032.   
  1033. }else return SD_INVALID_PARAMETER;  
  1034. if(nblks>1)
  1035. {      
  1036.   if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;   
  1037.       if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
  1038.      {
  1039.    //提高性能
  1040.     SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;  //发送ACMD55,短响应  
  1041.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
  1042.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1043.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1044.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1045.     SDIO_SendCommand(&SDIO_CmdInitStructure);
  1046.    
  1047.    errorstatus=CmdResp1Error(SD_CMD_APP_CMD);  //等待R1响应
  1048.    
  1049.    if(errorstatus!=SD_OK)return errorstatus;     
  1050.    
  1051.     SDIO_CmdInitStructure.SDIO_Argument =nblks;  //发送CMD23,设置块数量,短响应   
  1052.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCK_COUNT;
  1053.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1054.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1055.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1056.     SDIO_SendCommand(&SDIO_CmdInitStructure);
  1057.      
  1058.     errorstatus=CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);//等待R1响应
  1059.    
  1060.    if(errorstatus!=SD_OK)return errorstatus;  
  1061.       
  1062.   }
  1063.     SDIO_CmdInitStructure.SDIO_Argument =addr; //发送CMD25,多块写指令,短响应   
  1064.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
  1065.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1066.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1067.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1068.     SDIO_SendCommand(&SDIO_CmdInitStructure);
  1069.    errorstatus=CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK); //等待R1响应        

  1070.   if(errorstatus!=SD_OK)return errorstatus;
  1071.         SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ; //blksize, 控制器到卡
  1072.     SDIO_DataInitStructure.SDIO_DataLength= nblks*blksize ;
  1073.     SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  1074.     SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  1075.     SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  1076.     SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  1077.     SDIO_DataConfig(&SDIO_DataInitStructure);
  1078.    
  1079.   if(DeviceMode==SD_POLLING_MODE)
  1080.      {
  1081.    timeout=SDIO_DATATIMEOUT;
  1082.    INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
  1083.    while(!(SDIO->STA&((1<<4)|(1<<1)|(1<<8)|(1<<3)|(1<<9))))//下溢/CRC/数据结束/超时/起始位错误
  1084.    {
  1085.     if(SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)       //发送区半空,表示至少存了8字(32字节)
  1086.     {   
  1087.      if((tlen-bytestransferred)<SD_HALFFIFOBYTES)//不够32字节了
  1088.      {
  1089.       restwords=((tlen-bytestransferred)%4==0)?((tlen-bytestransferred)/4):((tlen-bytestransferred)/4+1);
  1090.       for(count=0;count<restwords;count++,tempbuff++,bytestransferred+=4)
  1091.       {
  1092.        SDIO->FIFO=*tempbuff;
  1093.       }
  1094.      }else           //发送区半空,可以发送至少8字(32字节)数据
  1095.      {
  1096.       for(count=0;count<SD_HALFFIFO;count++)
  1097.       {
  1098.        SDIO->FIFO=*(tempbuff+count);
  1099.       }
  1100.       tempbuff+=SD_HALFFIFO;
  1101.       bytestransferred+=SD_HALFFIFOBYTES;
  1102.      }
  1103.      timeout=0X3FFFFFFF; //写数据溢出时间
  1104.     }else
  1105.     {
  1106.      if(timeout==0)return SD_DATA_TIMEOUT;
  1107.      timeout--;
  1108.     }
  1109.    }
  1110.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //数据超时错误
  1111.   {            
  1112.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清错误标志
  1113.    return SD_DATA_TIMEOUT;
  1114.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
  1115.   {
  1116.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  1117.    return SD_DATA_CRC_FAIL;     
  1118.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)  //接收fifo下溢错误
  1119.   {
  1120.     SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);  //清错误标志
  1121.    return SD_TX_UNDERRUN;   
  1122.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位错误
  1123.   {
  1124.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
  1125.    return SD_START_BIT_ERR;   
  1126.   }   
  1127.                     
  1128.    if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)  //发送结束
  1129.    {               
  1130.     if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
  1131.     {   
  1132.      SDIO_CmdInitStructure.SDIO_Argument =0;//发送CMD12+结束传输   
  1133.      SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
  1134.      SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1135.      SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1136.      SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1137.      SDIO_SendCommand(&SDIO_CmdInitStructure);
  1138.      
  1139.      errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//等待R1响应   
  1140.      if(errorstatus!=SD_OK)return errorstatus;  
  1141.     }
  1142.    }
  1143.    INTX_ENABLE();//开启总中断
  1144.     SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1145.      }else if(DeviceMode==SD_DMA_MODE)
  1146.   {
  1147.      TransferError=SD_OK;
  1148.    StopCondition=1;   //多块写,需要发送停止传输指令
  1149.    TransferEnd=0;    //传输结束标置位,在中断服务置1
  1150.    SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9); //配置产生数据接收完成中断
  1151.    SD_DMA_Config((u32*)buf,nblks*blksize,DMA_DIR_MemoryToPeripheral);  //SDIO DMA配置
  1152.      SDIO->DCTRL|=1<<3;        //SDIO DMA使能.
  1153.    timeout=SDIO_DATATIMEOUT;
  1154.     while(((DMA2->LISR&(1<<27))==RESET)&&timeout)timeout--;//等待传输完成
  1155.    if(timeout==0)          //超时
  1156.    {           
  1157.       SD_Init();       //重新初始化SD卡,可以解决写入死机的问题
  1158.      return SD_DATA_TIMEOUT;   //超时  
  1159.     }
  1160.    timeout=SDIO_DATATIMEOUT;
  1161.    while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
  1162.     if(timeout==0)return SD_DATA_TIMEOUT;   //超时  
  1163.     if(TransferError!=SD_OK)return TransferError;  
  1164.   }
  1165.    }
  1166.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1167.   errorstatus=IsCardProgramming(&cardstate);
  1168.   while((errorstatus==SD_OK)&&((cardstate==SD_CARD_PROGRAMMING)||(cardstate==SD_CARD_RECEIVING)))
  1169. {
  1170.   errorstatus=IsCardProgramming(&cardstate);
  1171. }   
  1172. return errorstatus;   
  1173. }
  1174. //SDIO中断服务函数   
  1175. void SDIO_IRQHandler(void)
  1176. {           
  1177.   SD_ProcessIRQSrc();//处理所有SDIO相关中断
  1178. }                     
  1179. //SDIO中断处理函数
  1180. //处理SDIO传输过程中的各种中断事务
  1181. //返回值:错误代码
  1182. SD_Error SD_ProcessIRQSrc(void)
  1183. {
  1184. if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)//接收完成中断
  1185. {  
  1186.   if (StopCondition==1)
  1187.   {  
  1188.     SDIO_CmdInitStructure.SDIO_Argument =0;//发送CMD12+结束传输   
  1189.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
  1190.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1191.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1192.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1193.     SDIO_SendCommand(&SDIO_CmdInitStructure);
  1194.      
  1195.    TransferError=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
  1196.   }else TransferError = SD_OK;
  1197.    SDIO->ICR|=1<<8;//清除完成中断标记
  1198.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1199.    TransferEnd = 1;
  1200.   return(TransferError);
  1201. }
  1202.   if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)//数据CRC错误
  1203. {
  1204.   SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  1205.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1206.      TransferError = SD_DATA_CRC_FAIL;
  1207.      return(SD_DATA_CRC_FAIL);
  1208. }
  1209.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)//数据超时错误
  1210. {
  1211.   SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);     //清中断标志
  1212.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1213.      TransferError = SD_DATA_TIMEOUT;
  1214.      return(SD_DATA_TIMEOUT);
  1215. }
  1216.    if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)//FIFO上溢错误
  1217. {
  1218.   SDIO_ClearFlag(SDIO_FLAG_RXOVERR);     //清中断标志
  1219.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1220.      TransferError = SD_RX_OVERRUN;
  1221.      return(SD_RX_OVERRUN);
  1222. }
  1223.     if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)//FIFO下溢错误
  1224. {
  1225.   SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);     //清中断标志
  1226.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1227.      TransferError = SD_TX_UNDERRUN;
  1228.      return(SD_TX_UNDERRUN);
  1229. }
  1230. if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)//起始位错误
  1231. {
  1232.   SDIO_ClearFlag(SDIO_FLAG_STBITERR);    //清中断标志
  1233.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//关闭相关中断
  1234.      TransferError = SD_START_BIT_ERR;
  1235.      return(SD_START_BIT_ERR);
  1236. }
  1237. return(SD_OK);
  1238. }
  1239.   
  1240. //检查CMD0的执行状态
  1241. //返回值:sd卡错误码
  1242. SD_Error CmdError(void)
  1243. {
  1244. SD_Error errorstatus = SD_OK;
  1245. u32 timeout=SDIO_CMD0TIMEOUT;   
  1246. while(timeout--)
  1247. {
  1248.   if(SDIO_GetFlagStatus(SDIO_FLAG_CMDSENT) != RESET)break; //命令已发送(无需响应)  
  1249. }     
  1250. if(timeout==0)return SD_CMD_RSP_TIMEOUT;  
  1251. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1252. return errorstatus;
  1253. }  
  1254. //检查R7响应的错误状态
  1255. //返回值:sd卡错误码
  1256. SD_Error CmdResp7Error(void)
  1257. {
  1258. SD_Error errorstatus=SD_OK;
  1259. u32 status;
  1260. u32 timeout=SDIO_CMD0TIMEOUT;
  1261.   while(timeout--)
  1262. {
  1263.   status=SDIO->STA;
  1264.   if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
  1265. }
  1266.   if((timeout==0)||(status&(1<<2))) //响应超时
  1267. {                        
  1268.   errorstatus=SD_CMD_RSP_TIMEOUT; //当前卡不是2.0兼容卡,或者不支持设定的电压范围
  1269.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);    //清除命令响应超时标志
  1270.   return errorstatus;
  1271. }  
  1272. if(status&1<<6)      //成功接收到响应
  1273. {           
  1274.   errorstatus=SD_OK;
  1275.   SDIO_ClearFlag(SDIO_FLAG_CMDREND);     //清除响应标志
  1276.   }
  1277. return errorstatus;
  1278. }   
  1279. //检查R1响应的错误状态
  1280. //cmd:当前命令
  1281. //返回值:sd卡错误码
  1282. SD_Error CmdResp1Error(u8 cmd)
  1283. {   
  1284.     u32 status;
  1285. while(1)
  1286. {
  1287.   status=SDIO->STA;
  1288.   if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
  1289. }
  1290. if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //响应超时
  1291. {                        
  1292.    SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);     //清除命令响应超时标志
  1293.   return SD_CMD_RSP_TIMEOUT;
  1294. }
  1295.   if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)     //CRC错误
  1296. {                        
  1297.    SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);     //清除标志
  1298.   return SD_CMD_CRC_FAIL;
  1299. }  
  1300. if(SDIO->RESPCMD!=cmd)return SD_ILLEGAL_CMD;//命令不匹配
  1301.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1302. return (SD_Error)(SDIO->RESP1&SD_OCR_ERRORBITS);//返回卡响应
  1303. }
  1304. //检查R3响应的错误状态
  1305. //返回值:错误状态
  1306. SD_Error CmdResp3Error(void)
  1307. {
  1308. u32 status;      
  1309.   while(1)
  1310. {
  1311.   status=SDIO->STA;
  1312.   if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
  1313. }
  1314.   if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //响应超时
  1315. {            
  1316.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令响应超时标志
  1317.   return SD_CMD_RSP_TIMEOUT;
  1318. }  
  1319.    SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1320.   return SD_OK;         
  1321. }
  1322. //检查R2响应的错误状态
  1323. //返回值:错误状态
  1324. SD_Error CmdResp2Error(void)
  1325. {
  1326. SD_Error errorstatus=SD_OK;
  1327. u32 status;
  1328. u32 timeout=SDIO_CMD0TIMEOUT;
  1329.   while(timeout--)
  1330. {
  1331.   status=SDIO->STA;
  1332.   if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
  1333. }
  1334.    if((timeout==0)||(status&(1<<2))) //响应超时
  1335. {                        
  1336.   errorstatus=SD_CMD_RSP_TIMEOUT;
  1337.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令响应超时标志
  1338.   return errorstatus;
  1339. }  
  1340. if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)      //CRC错误
  1341. {           
  1342.   errorstatus=SD_CMD_CRC_FAIL;
  1343.   SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);  //清除响应标志
  1344.   }
  1345. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1346.   return errorstatus;               
  1347. }
  1348. //检查R6响应的错误状态
  1349. //cmd:之前发送的命令
  1350. //prca:卡返回的RCA地址
  1351. //返回值:错误状态
  1352. SD_Error CmdResp6Error(u8 cmd,u16*prca)
  1353. {
  1354. SD_Error errorstatus=SD_OK;
  1355. u32 status;         
  1356. u32 rspr1;
  1357.   while(1)
  1358. {
  1359.   status=SDIO->STA;
  1360.   if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
  1361. }
  1362. if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //响应超时
  1363. {                        
  1364.    SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令响应超时标志
  1365.   return SD_CMD_RSP_TIMEOUT;
  1366. }   
  1367. if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)      //CRC错误
  1368. {           
  1369.   SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);     //清除响应标志
  1370.    return SD_CMD_CRC_FAIL;
  1371. }
  1372. if(SDIO->RESPCMD!=cmd)    //判断是否响应cmd命令
  1373. {
  1374.    return SD_ILLEGAL_CMD;   
  1375. }     
  1376. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1377. rspr1=SDIO->RESP1;     //得到响应   
  1378. if(SD_ALLZERO==(rspr1&(SD_R6_GENERAL_UNKNOWN_ERROR|SD_R6_ILLEGAL_CMD|SD_R6_COM_CRC_FAILED)))
  1379. {
  1380.   *prca=(u16)(rspr1>>16);   //右移16位得到,rca
  1381.   return errorstatus;
  1382. }
  1383.     if(rspr1&SD_R6_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR;
  1384.     if(rspr1&SD_R6_ILLEGAL_CMD)return SD_ILLEGAL_CMD;
  1385.     if(rspr1&SD_R6_COM_CRC_FAILED)return SD_COM_CRC_FAILED;
  1386. return errorstatus;
  1387. }
  1388. //SDIO使能宽总线模式
  1389. //enx:0,不使能;1,使能;
  1390. //返回值:错误状态
  1391. SD_Error SDEnWideBus(u8 enx)
  1392. {
  1393. SD_Error errorstatus = SD_OK;
  1394.   u32 scr[2]={0,0};
  1395. u8 arg=0X00;
  1396. if(enx)arg=0X02;
  1397. else arg=0X00;
  1398.   if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//SD卡处于LOCKED状态      
  1399.   errorstatus=FindSCR(RCA,scr);      //得到SCR寄存器数据
  1400.   if(errorstatus!=SD_OK)return errorstatus;
  1401. if((scr[1]&SD_WIDE_BUS_SUPPORT)!=SD_ALLZERO)  //支持宽总线
  1402. {
  1403.     SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;//发送CMD55+RCA,短响应
  1404.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
  1405.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1406.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1407.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1408.       SDIO_SendCommand(&SDIO_CmdInitStructure);
  1409.   
  1410.    errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
  1411.   
  1412.    if(errorstatus!=SD_OK)return errorstatus;
  1413.   
  1414.     SDIO_CmdInitStructure.SDIO_Argument = arg;//发送ACMD6,短响应,参数:10,4位;00,1位.
  1415.       SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
  1416.       SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1417.       SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1418.       SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1419.       SDIO_SendCommand(&SDIO_CmdInitStructure);
  1420.    
  1421.      errorstatus=CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);
  1422.   
  1423.   return errorstatus;
  1424. }else return SD_REQUEST_NOT_APPLICABLE;    //不支持宽总线设置   
  1425. }               
  1426. //检查卡是否正在执行写操作
  1427. //pstatus:当前状态.
  1428. //返回值:错误代码
  1429. SD_Error IsCardProgramming(u8 *pstatus)
  1430. {
  1431.   vu32 respR1 = 0, status = 0;  
  1432.   
  1433.   SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16; //卡相对地址参数
  1434.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;//发送CMD13  
  1435.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1436.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1437.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1438.   SDIO_SendCommand(&SDIO_CmdInitStructure);
  1439.   
  1440. status=SDIO->STA;

  1441. while(!(status&((1<<0)|(1<<6)|(1<<2))))status=SDIO->STA;//等待操作完成
  1442.     if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)   //CRC检测失败
  1443. {  
  1444.    SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); //清除错误标记
  1445.   return SD_CMD_CRC_FAIL;
  1446. }
  1447.     if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)   //命令超时
  1448. {
  1449.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除错误标记
  1450.   return SD_CMD_RSP_TIMEOUT;
  1451. }
  1452.   if(SDIO->RESPCMD!=SD_CMD_SEND_STATUS)return SD_ILLEGAL_CMD;
  1453. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1454. respR1=SDIO->RESP1;
  1455. *pstatus=(u8)((respR1>>9)&0x0000000F);
  1456. return SD_OK;
  1457. }
  1458. //读取当前卡状态
  1459. //pcardstatus:卡状态
  1460. //返回值:错误代码
  1461. SD_Error SD_SendStatus(uint32_t *pcardstatus)
  1462. {
  1463. SD_Error errorstatus = SD_OK;
  1464. if(pcardstatus==NULL)
  1465. {
  1466.   errorstatus=SD_INVALID_PARAMETER;
  1467.   return errorstatus;
  1468. }

  1469. SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;//发送CMD13,短响应   
  1470.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  1471.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1472.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1473.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1474.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  1475. errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //查询响应状态
  1476. if(errorstatus!=SD_OK)return errorstatus;
  1477. *pcardstatus=SDIO->RESP1;//读取响应值
  1478. return errorstatus;
  1479. }
  1480. //返回SD卡的状态
  1481. //返回值:SD卡状态
  1482. SDCardState SD_GetState(void)
  1483. {
  1484. u32 resp1=0;
  1485. if(SD_SendStatus(&resp1)!=SD_OK)return SD_CARD_ERROR;
  1486. else return (SDCardState)((resp1>>9) & 0x0F);
  1487. }
  1488. //查找SD卡的SCR寄存器值
  1489. //rca:卡相对地址
  1490. //pscr:数据缓存区(存储SCR内容)
  1491. //返回值:错误状态     
  1492. SD_Error FindSCR(u16 rca,u32 *pscr)
  1493. {
  1494. u32 index = 0;
  1495. SD_Error errorstatus = SD_OK;
  1496. u32 tempscr[2]={0,0};  

  1497. SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)8;  //发送CMD16,短响应,设置Block Size为8字节
  1498.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN; //  cmd16
  1499.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r1
  1500.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1501.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1502.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  1503.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);

  1504.   if(errorstatus!=SD_OK)return errorstatus;  

  1505.   SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
  1506.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;//发送CMD55,短响应  
  1507.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  1508.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1509.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1510.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  1511.   errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
  1512.   if(errorstatus!=SD_OK)return errorstatus;

  1513.   SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  1514.   SDIO_DataInitStructure.SDIO_DataLength = 8;  //8个字节长度,block为8字节,SD卡到SDIO.
  1515.   SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_8b  ;  //块大小8byte
  1516.   SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
  1517.   SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  1518.   SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  1519.   SDIO_DataConfig(&SDIO_DataInitStructure);  
  1520.   SDIO_CmdInitStructure.SDIO_Argument = 0x0;
  1521.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_SEND_SCR; //发送ACMD51,短响应,参数为0
  1522.   SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;  //r1
  1523.   SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  1524.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  1525.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  1526.   errorstatus=CmdResp1Error(SD_CMD_SD_APP_SEND_SCR);
  1527.   if(errorstatus!=SD_OK)return errorstatus;         
  1528.   while(!(SDIO->STA&(SDIO_FLAG_RXOVERR|SDIO_FLAG_DCRCFAIL|SDIO_FLAG_DTIMEOUT|SDIO_FLAG_DBCKEND|SDIO_FLAG_STBITERR)))
  1529. {
  1530.   if(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)//接收FIFO数据可用
  1531.   {
  1532.    *(tempscr+index)=SDIO->FIFO; //读取FIFO内容
  1533.    index++;
  1534.    if(index>=2)break;
  1535.   }
  1536. }
  1537.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //数据超时错误
  1538.   {            
  1539.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清错误标志
  1540.    return SD_DATA_TIMEOUT;
  1541.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
  1542.   {
  1543.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清错误标志
  1544.    return SD_DATA_CRC_FAIL;     
  1545.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢错误
  1546.   {
  1547.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清错误标志
  1548.    return SD_RX_OVERRUN;   
  1549.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位错误
  1550.   {
  1551.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
  1552.    return SD_START_BIT_ERR;   
  1553.   }  
  1554.    SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有标记
  1555. //把数据顺序按8位为单位倒过来.   
  1556. *(pscr+1)=((tempscr[0]&SD_0TO7BITS)<<24)|((tempscr[0]&SD_8TO15BITS)<<8)|((tempscr[0]&SD_16TO23BITS)>>8)|((tempscr[0]&SD_24TO31BITS)>>24);
  1557. *(pscr)=((tempscr[1]&SD_0TO7BITS)<<24)|((tempscr[1]&SD_8TO15BITS)<<8)|((tempscr[1]&SD_16TO23BITS)>>8)|((tempscr[1]&SD_24TO31BITS)>>24);
  1558.   return errorstatus;
  1559. }
  1560. //得到NumberOfBytes以2为底的指数.
  1561. //NumberOfBytes:字节数.
  1562. //返回值:以2为底的指数值
  1563. u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes)
  1564. {
  1565. u8 count=0;
  1566. while(NumberOfBytes!=1)
  1567. {
  1568.   NumberOfBytes>>=1;
  1569.   count++;
  1570. }
  1571. return count;
  1572. }   
  1573. //配置SDIO DMA  
  1574. //mbuf:存储器地址
  1575. //bufsize:传输数据量
  1576. //dir:方向;DMA_DIR_MemoryToPeripheral  存储器-->SDIO(写数据);DMA_DIR_PeripheralToMemory SDIO-->存储器(读数据);
  1577. void SD_DMA_Config(u32*mbuf,u32 bufsize,u32 dir)
  1578. {   
  1579.   DMA_InitTypeDef  DMA_InitStructure;

  1580. while (DMA_GetCmdStatus(DMA2_Stream3) != DISABLE){}//等待DMA可配置
  1581.   
  1582.   DMA_DeInit(DMA2_Stream3);//清空之前该stream3上的所有中断标志


  1583.   DMA_InitStructure.DMA_Channel = DMA_Channel_4;  //通道选择
  1584.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO->FIFO;//DMA外设地址
  1585.   DMA_InitStructure.DMA_Memory0BaseAddr = (u32)mbuf;//DMA 存储器0地址
  1586.   DMA_InitStructure.DMA_DIR = dir;//存储器到外设模式
  1587.   DMA_InitStructure.DMA_BufferSize = 0;//数据传输量
  1588.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  1589.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  1590.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据长度:32位
  1591.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//存储器数据长度:32位
  1592.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
  1593.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//最高优先级
  1594.   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;   //FIFO使能      
  1595.   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//全FIFO
  1596.   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;//外设突发4次传输
  1597.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;//存储器突发4次传输
  1598.   DMA_Init(DMA2_Stream3, &DMA_InitStructure);//初始化DMA Stream
  1599. DMA_FlowControllerConfig(DMA2_Stream3,DMA_FlowCtrl_Peripheral);//外设流控制
  1600.   
  1601.   DMA_Cmd(DMA2_Stream3 ,ENABLE);//开启DMA传输  
  1602. }   

  1603. //读SD卡
  1604. //buf:读数据缓存区
  1605. //sector:扇区地址
  1606. //cnt:扇区个数
  1607. //返回值:错误状态;0,正常;其他,错误代码;           
  1608. u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
  1609. {
  1610. u8 sta=SD_OK;
  1611. long long lsector=sector;
  1612. u8 n;
  1613. if(CardType!=SDIO_STD_CAPACITY_SD_CARD_V1_1)lsector<<=9;
  1614. if((u32)buf%4!=0)
  1615. {
  1616.    for(n=0;n<cnt;n++)
  1617.   {
  1618.     sta=SD_ReadBlock(SDIO_DATA_BUFFER,lsector+512*n,512);//单个sector的读操作
  1619.    memcpy(buf,SDIO_DATA_BUFFER,512);
  1620.    buf+=512;
  1621.   }
  1622. }else
  1623. {
  1624.   if(cnt==1)sta=SD_ReadBlock(buf,lsector,512);     //单个sector的读操作
  1625.   else sta=SD_ReadMultiBlocks(buf,lsector,512,cnt);//多个sector  
  1626. }
  1627. return sta;
  1628. }
  1629. //写SD卡
  1630. //buf:写数据缓存区
  1631. //sector:扇区地址
  1632. //cnt:扇区个数
  1633. //返回值:错误状态;0,正常;其他,错误代码;
  1634. u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
  1635. {
  1636. u8 sta=SD_OK;
  1637. u8 n;
  1638. long long lsector=sector;
  1639. if(CardType!=SDIO_STD_CAPACITY_SD_CARD_V1_1)lsector<<=9;
  1640. if((u32)buf%4!=0)
  1641. {
  1642.    for(n=0;n<cnt;n++)
  1643.   {
  1644.    memcpy(SDIO_DATA_BUFFER,buf,512);
  1645.     sta=SD_WriteBlock(SDIO_DATA_BUFFER,lsector+512*n,512);//单个sector的写操作
  1646.    buf+=512;
  1647.   }
  1648. }else
  1649. {
  1650.   if(cnt==1)sta=SD_WriteBlock(buf,lsector,512);     //单个sector的写操作
  1651.   else sta=SD_WriteMultiBlocks(buf,lsector,512,cnt); //多个sector  
  1652. }
  1653. return sta;
  1654. }
复制代码

代码下载: 6-ADC采集+文件系统.7z (829.79 KB, 下载次数: 76)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:114007 发表于 2023-9-19 14:24 | 只看该作者
下载之后直接编译报错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表