久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2774|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

STM32F407VET6采集AD數(shù)據(jù),保存到SD卡中 源程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:241682 發(fā)表于 2021-11-28 06:24 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
  1. //單片機(jī)采用STM32F407VET6 ad采集數(shù)據(jù),并將數(shù)據(jù)保存到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);//設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組2
  19. delay_init(168);  //延時(shí)初始化
  20. uart_init(115200);     //串口初始化波特率為115200
  21. LED_Init();      //初始化與LED連接的硬件接口  
  22. Adc_Init();             //初始化ADC

  23. SD_Init();
  24. exfuns_init();      //為fatfs相關(guān)變量申請(qǐng)內(nèi)存     
  25.     f_mount(fs[0],"0:",1);  //掛載SD卡
  26.   res=mf_open("0:/123/ADcData.txt",FA_OPEN_ALWAYS | FA_READ | FA_WRITE );//創(chuàng)建或打開一個(gè)文本文檔保存數(shù)據(jù)
  27. res=mf_open("0:/ADcData.txt",FA_OPEN_ALWAYS | FA_READ | FA_WRITE );//創(chuàng)建或打開一個(gè)文本文檔保存數(shù)據(jù)
  28. if(res==FR_OK)
  29.     {
  30.   printf("文件已經(jīng)存在!\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);   //獲取計(jì)算后的帶小數(shù)的實(shí)際電壓值,比如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());                  //將指針定位于文件尾部,準(zhǔn)備追加數(shù)據(jù)
  47.   mf_write(ADc_Buff,strlen(ADc_Buff));  //將接收到的數(shù)據(jù)存入文件
  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初始化的結(jié)構(gòu)體*/
  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卡類型(默認(rèn)為1.x卡)
  74. static u32 CSD_Tab[4],CID_Tab[4],RCA=0;     //SD卡CSD,CID以及相對(duì)地址(RCA)數(shù)據(jù)
  75. static u8 DeviceMode=SD_DMA_MODE;         //工作模式,注意,工作模式必須通過SD_SetDeviceMode,后才算數(shù).這里只是定義一個(gè)默認(rèn)的模式(SD_DMA_MODE)
  76. static u8 StopCondition=0;         //是否發(fā)送停止傳輸標(biāo)志位,DMA多塊讀寫的時(shí)候用到  
  77. volatile SD_Error TransferError=SD_OK;     //數(shù)據(jù)傳輸錯(cuò)誤標(biāo)志,DMA讀寫時(shí)使用     
  78. volatile u8 TransferEnd=0;        //傳輸結(jié)束標(biāo)志,DMA讀寫時(shí)使用
  79. SD_CardInfo SDCardInfo; //SD卡信息
  80. //THUMB指令不支持匯編內(nèi)聯(lián)
  81. //采用如下方法實(shí)現(xiàn)執(zhí)行匯編指令WFI  
  82. __asm void WFI_SET(void)
  83. {
  84. WFI;   
  85. }
  86. //關(guān)閉所有中斷(但是不包括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. //設(shè)置棧頂?shù)刂?br />
  99. //addr:棧頂?shù)刂?br />
  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函數(shù)專用buf,當(dāng)這兩個(gè)函數(shù)的數(shù)據(jù)緩存區(qū)地址不是4字節(jié)對(duì)齊的時(shí)候,
  106. //需要用到該數(shù)組,確保數(shù)據(jù)緩存區(qū)地址是4字節(jié)對(duì)齊的.
  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. //返回值:錯(cuò)誤代碼;(0,無錯(cuò)誤)
  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時(shí)鐘

  129.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);//SDIO時(shí)鐘使能

  130. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE);//SDIO復(fù)位


  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復(fù)用功能輸出
  132.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復(fù)用功能
  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復(fù)用功能輸出

  137. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2;
  138.   GPIO_Init(GPIOD, &GPIO_InitStructure);//PD2復(fù)用功能輸出

  139.   //引腳復(fù)用映射設(shè)置
  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結(jié)束復(fù)位
  147.   
  148.   //SDIO外設(shè)寄存器設(shè)置為默認(rèn)值      
  149. SDIO_Register_Deinit();

  150.   NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
  151. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優(yōu)先級(jí)3
  152. NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;  //子優(yōu)先級(jí)3
  153. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
  154. NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化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);   //設(shè)置時(shí)鐘頻率,SDIO時(shí)鐘計(jì)算公式:SDIO_CK時(shí)鐘=SDIOCLK/[clkdiv+2];其中,SDIOCLK固定為48Mhz
  163.   //errorstatus=SD_SetDeviceMode(SD_DMA_MODE); //設(shè)置為DMA模式
  164.   errorstatus=SD_SetDeviceMode(SD_POLLING_MODE);//設(shè)置為查詢模式
  165.   }
  166. return errorstatus;   
  167. }
  168. //SDIO時(shí)鐘初始化設(shè)置
  169. //clkdiv:時(shí)鐘分頻系數(shù)
  170. //CK時(shí)鐘=SDIOCLK/[clkdiv+2];(SDIOCLK時(shí)鐘固定為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接口上的卡設(shè)備,并查詢其電壓和配置時(shí)鐘
  180. //返回值:錯(cuò)誤代碼;(0,無錯(cuò)誤)
  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.   /*初始化時(shí)的時(shí)鐘不能大于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進(jìn)行分頻得到SDIO_CK
  191.   SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; // 空閑時(shí)不關(guān)閉時(shí)鐘電源
  192.   SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;      //1位數(shù)據(jù)線
  193.   SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;//硬件流
  194.   SDIO_Init(&SDIO_InitStructure);
  195. SDIO_SetPowerState(SDIO_PowerState_ON); //上電狀態(tài),開啟卡時(shí)鐘   
  196.   SDIO->CLKCR|=1<<8;   //SDIOCK使能  

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

  199.   SDIO_CmdInitStructure.SDIO_Argument = 0x0;//發(fā)送CMD0進(jìn)入IDLE STAGE模式命令.
  200.     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE; //cmd0
  201.     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;  //無響應(yīng)
  202.     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  203.     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;  //則CPSM在開始發(fā)送命令之前等待數(shù)據(jù)傳輸結(jié)束。
  204.     SDIO_SendCommand(&SDIO_CmdInitStructure);     //寫命令進(jìn)命令寄存器
  205.   
  206.   errorstatus=CmdError();
  207.   
  208.   if(errorstatus==SD_OK)break;
  209.   }
  210.   if(errorstatus)return errorstatus;//返回錯(cuò)誤狀態(tài)

  211.   SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN; //發(fā)送CMD8,短響應(yīng),檢查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;    //關(guān)閉等待中斷
  215.   SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  216.   SDIO_SendCommand(&SDIO_CmdInitStructure);

  217.   errorstatus=CmdResp7Error();      //等待R7響應(yīng)

  218.   if(errorstatus==SD_OK)         //R7響應(yīng)正常
  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;//發(fā)送CMD55,短響應(yīng)
  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);  //發(fā)送CMD55,短響應(yīng)  

  230.   errorstatus=CmdResp1Error(SD_CMD_APP_CMD);     //等待R1響應(yīng)   

  231. if(errorstatus==SD_OK)//SD2.0/SD 1.1,否則為MMC卡
  232. {                  
  233.   //SD卡,發(fā)送ACMD41 SD_APP_OP_COND,參數(shù)為:0x80100000
  234.   while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
  235.   {                 
  236.     SDIO_CmdInitStructure.SDIO_Argument = 0x00;//發(fā)送CMD55,短響應(yīng)
  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);   //發(fā)送CMD55,短響應(yīng)  
  242.    
  243.    errorstatus=CmdResp1Error(SD_CMD_APP_CMD);    //等待R1響應(yīng)  
  244.    
  245.     if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤
  246.       //acmd41,命令參數(shù)由支持的電壓范圍及HCS位組成,HCS位置一來區(qū)分卡是SDSc還是sdhc
  247.       SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDType; //發(fā)送ACMD41,短響應(yīng)
  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響應(yīng)   
  255.    
  256.     if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤
  257.    response=SDIO->RESP1;;          //得到響應(yīng)
  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卡,發(fā)送CMD1 SDIO_SEND_OP_COND,參數(shù)為:0x80FF8000
  273.   while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
  274.   {                        
  275.    SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_MMC;//發(fā)送CMD1,短響應(yīng)   
  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響應(yīng)   
  283.    
  284.     if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  285.    response=SDIO->RESP1;;          //得到響應(yīng)
  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. //返回值:錯(cuò)誤代碼;(0,無錯(cuò)誤)
  300. SD_Error SD_PowerOFF(void)
  301. {

  302.   SDIO_SetPowerState(SDIO_PowerState_OFF);//SDIO電源關(guān)閉,時(shí)鐘停止
  303.   return SD_OK;   
  304. }   
  305. //初始化所有的卡,并讓卡進(jìn)入就緒狀態(tài)
  306. //返回值:錯(cuò)誤代碼
  307. SD_Error SD_InitializeCards(void)
  308. {
  309.   SD_Error errorstatus=SD_OK;
  310. u16 rca = 0x01;

  311.   if (SDIO_GetPowerState() == SDIO_PowerState_OFF) //檢查電源狀態(tài),確保為上電狀態(tài)
  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;//發(fā)送CMD2,取得CID,長(zhǎng)響應(yīng)
  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);//發(fā)送CMD2,取得CID,長(zhǎng)響應(yīng)
  324.   
  325.   errorstatus=CmdResp2Error();      //等待R2響應(yīng)
  326.   
  327.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤   
  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;//發(fā)送CMD3,短響應(yīng)
  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); //發(fā)送CMD3,短響應(yīng)
  342.   
  343.   errorstatus=CmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);//等待R6響應(yīng)
  344.   
  345.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤      
  346. }   
  347.     if (SDIO_MULTIMEDIA_CARD==CardType)
  348.     {
  349.     SDIO_CmdInitStructure.SDIO_Argument = (u32)(rca<<16);//發(fā)送CMD3,短響應(yīng)
  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); //發(fā)送CMD3,短響應(yīng)  
  355.    
  356.       errorstatus=CmdResp2Error();      //等待R2響應(yīng)   
  357.    
  358.     if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  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);//發(fā)送CMD9+卡RCA,取得CSD,長(zhǎng)響應(yīng)
  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響應(yīng)   
  372.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤      
  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:卡信息存儲(chǔ)區(qū)
  383. //返回值:錯(cuò)誤狀態(tài)
  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結(jié)構(gòu)
  392. cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2; //2.0協(xié)議還沒定義這部分(為保留),應(yīng)該是后續(xù)協(xié)議定義的
  393. cardinfo->SD_csd.Reserved1=tmp&0x03;   //2個(gè)保留位  
  394. tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);   //第1個(gè)字節(jié)
  395. cardinfo->SD_csd.TAAC=tmp;         //數(shù)據(jù)讀時(shí)間1
  396. tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);     //第2個(gè)字節(jié)
  397. cardinfo->SD_csd.NSAC=tmp;        //數(shù)據(jù)讀時(shí)間2
  398. tmp=(u8)(CSD_Tab[0]&0x000000FF);    //第3個(gè)字節(jié)
  399. cardinfo->SD_csd.MaxBusClkFrec=tmp;      //傳輸速度   
  400. tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24);   //第4個(gè)字節(jié)
  401. cardinfo->SD_csd.CardComdClasses=tmp<<4;     //卡指令類高四位
  402. tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16);    //第5個(gè)字節(jié)
  403. cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;//卡指令類低四位
  404. cardinfo->SD_csd.RdBlockLen=tmp&0x0F;      //最大讀取數(shù)據(jù)長(zhǎng)度
  405. tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8);   //第6個(gè)字節(jié)
  406. cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7; //允許分塊讀
  407. cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6; //寫塊錯(cuò)位
  408. cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5; //讀塊錯(cuò)位
  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))//標(biāo)準(zhǔn)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個(gè)字節(jié)
  415.   cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
  416.    tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);  //第8個(gè)字節(jié)
  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個(gè)字節(jié)
  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個(gè)字節(jié)
  425.   cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
  426.    cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);//計(jì)算卡容量
  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個(gè)字節(jié)
  433.   cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;//C_SIZE
  434.    tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);  //第8個(gè)字節(jié)
  435.    cardinfo->SD_csd.DeviceSize|=(tmp<<8);
  436.    tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16); //第9個(gè)字節(jié)
  437.    cardinfo->SD_csd.DeviceSize|=(tmp);
  438.    tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);  //第10個(gè)字節(jié)
  439.    cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;//計(jì)算卡容量
  440.   cardinfo->CardBlockSize=512;    //塊大小固定為512字節(jié)
  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個(gè)字節(jié)
  445. cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
  446. cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
  447.   tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24);  //第12個(gè)字節(jié)
  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個(gè)字節(jié)
  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個(gè)字節(jié)
  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個(gè)字節(jié)
  465. cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
  466. cardinfo->SD_csd.Reserved4=1;   
  467. tmp=(u8)((CID_Tab[0]&0xFF000000)>>24);  //第0個(gè)字節(jié)
  468. cardinfo->SD_cid.ManufacturerID=tmp;      
  469. tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16);  //第1個(gè)字節(jié)
  470. cardinfo->SD_cid.OEM_AppliID=tmp<<8;   
  471. tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8);  //第2個(gè)字節(jié)
  472. cardinfo->SD_cid.OEM_AppliID|=tmp;     
  473. tmp=(u8)(CID_Tab[0]&0x000000FF);   //第3個(gè)字節(jié)
  474. cardinfo->SD_cid.ProdName1=tmp<<24;      
  475. tmp=(u8)((CID_Tab[1]&0xFF000000)>>24);   //第4個(gè)字節(jié)
  476. cardinfo->SD_cid.ProdName1|=tmp<<16;   
  477. tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16);     //第5個(gè)字節(jié)
  478. cardinfo->SD_cid.ProdName1|=tmp<<8;   
  479. tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8);  //第6個(gè)字節(jié)
  480. cardinfo->SD_cid.ProdName1|=tmp;     
  481. tmp=(u8)(CID_Tab[1]&0x000000FF);     //第7個(gè)字節(jié)
  482. cardinfo->SD_cid.ProdName2=tmp;     
  483. tmp=(u8)((CID_Tab[2]&0xFF000000)>>24);   //第8個(gè)字節(jié)
  484. cardinfo->SD_cid.ProdRev=tmp;   
  485. tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16);  //第9個(gè)字節(jié)
  486. cardinfo->SD_cid.ProdSN=tmp<<24;   
  487. tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8);   //第10個(gè)字節(jié)
  488. cardinfo->SD_cid.ProdSN|=tmp<<16;   
  489. tmp=(u8)(CID_Tab[2]&0x000000FF);      //第11個(gè)字節(jié)
  490. cardinfo->SD_cid.ProdSN|=tmp<<8;     
  491. tmp=(u8)((CID_Tab[3]&0xFF000000)>>24);   //第12個(gè)字節(jié)
  492. cardinfo->SD_cid.ProdSN|=tmp;        
  493. tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16);   //第13個(gè)字節(jié)
  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個(gè)字節(jié)
  497. cardinfo->SD_cid.ManufactDate|=tmp;      
  498. tmp=(u8)(CID_Tab[3]&0x000000FF);   //第15個(gè)字節(jié)
  499. cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
  500. cardinfo->SD_cid.Reserved2=1;  
  501. return errorstatus;
  502. }
  503. //設(shè)置SDIO總線寬度(MMC卡不支持4bit模式)
  504. //wmode:位寬模式.0,1位數(shù)據(jù)寬度;1,4位數(shù)據(jù)寬度;2,8位數(shù)據(jù)寬度
  505. //返回值:SD卡錯(cuò)誤狀態(tài)
  506. //設(shè)置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 (默認(rèn))
  510. //返回值:SD卡錯(cuò)誤狀態(tài)

  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);  //清除之前的位寬設(shè)置   
  532.     SDIO->CLKCR|=WideMode;//1位/4位總線寬度
  533.     SDIO->CLKCR|=0<<14;   //不開啟硬件流控制
  534.    }
  535.   }  
  536. }
  537. return errorstatus;
  538. }
  539. //設(shè)置SD卡工作模式
  540. //Mode:
  541. //返回值:錯(cuò)誤狀態(tài)
  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. //發(fā)送CMD7,選擇相對(duì)地址(rca)為addr的卡,取消其他卡.如果為0,則都不選擇.
  551. //addr:卡的RCA地址
  552. SD_Error SD_SelectDeselect(u32 addr)
  553. {
  554.   SDIO_CmdInitStructure.SDIO_Argument =  addr;//發(fā)送CMD7,選擇卡,短響應(yīng)
  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);//發(fā)送CMD7,選擇卡,短響應(yīng)

  560.   return CmdResp1Error(SD_CMD_SEL_DESEL_CARD);   
  561. }
  562. //SD卡讀取一個(gè)塊
  563. //buf:讀數(shù)據(jù)緩存區(qū)(必須4字節(jié)對(duì)齊!!)
  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;//轉(zhuǎn)換為u32指針
  571. u32 timeout=SDIO_DATATIMEOUT;   
  572.   if(NULL==buf)
  573.   return SD_INVALID_PARAMETER;
  574.   SDIO->DCTRL=0x0; //數(shù)據(jù)控制寄存器清零(關(guān)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狀態(tài)機(jī)配置
  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);//發(fā)送CMD16+設(shè)置數(shù)據(jù)長(zhǎng)度為blksize,短響應(yīng)
  600.   
  601.   
  602.   errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1響應(yīng)
  603.   
  604.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤
  605.   
  606. }else return SD_INVALID_PARAMETER;     

  607.    SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4 ;//清除DPSM狀態(tài)機(jī)配置
  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);//發(fā)送CMD17+從addr地址出讀取數(shù)據(jù),短響應(yīng)

  620. errorstatus=CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);//等待R1響應(yīng)   
  621. if(errorstatus!=SD_OK)return errorstatus;     //響應(yīng)錯(cuò)誤  
  622.   if(DeviceMode==SD_POLLING_MODE)      //查詢模式,輪詢數(shù)據(jù)  
  623. {
  624.    INTX_DISABLE();//關(guān)閉總中斷(POLLING模式,嚴(yán)禁中斷打斷SDIO讀寫操作!!!)
  625.   while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//無上溢/CRC/超時(shí)/完成(標(biāo)志)/起始位錯(cuò)誤
  626.   {
  627.    if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)      //接收區(qū)半滿,表示至少存了8個(gè)字
  628.    {
  629.     for(count=0;count<8;count++)   //循環(huán)讀取數(shù)據(jù)
  630.     {
  631.      *(tempbuff+count)=SDIO->FIFO;
  632.     }
  633.     tempbuff+=8;  
  634.     timeout=0X7FFFFF;  //讀數(shù)據(jù)溢出時(shí)間
  635.    }else  //處理超時(shí)
  636.    {
  637.     if(timeout==0)return SD_DATA_TIMEOUT;
  638.     timeout--;
  639.    }
  640.   }
  641.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //數(shù)據(jù)超時(shí)錯(cuò)誤
  642.   {            
  643.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清錯(cuò)誤標(biāo)志
  644.    return SD_DATA_TIMEOUT;
  645.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //數(shù)據(jù)塊CRC錯(cuò)誤
  646.   {
  647.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  648.    return SD_DATA_CRC_FAIL;     
  649.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢錯(cuò)誤
  650.   {
  651.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清錯(cuò)誤標(biāo)志
  652.    return SD_RX_OVERRUN;   
  653.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位錯(cuò)誤
  654.   {
  655.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清錯(cuò)誤標(biāo)志
  656.    return SD_START_BIT_ERR;   
  657.   }   
  658.   while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) //FIFO里面,還存在可用數(shù)據(jù)
  659.   {
  660.    *tempbuff=SDIO->FIFO; //循環(huán)讀取數(shù)據(jù)
  661.    tempbuff++;
  662.   }
  663.   INTX_ENABLE();//開啟總中斷
  664.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  665.   
  666. }else if(DeviceMode==SD_DMA_MODE)
  667. {
  668.    TransferError=SD_OK;
  669.   StopCondition=0;   //單塊讀,不需要發(fā)送停止傳輸指令
  670.   TransferEnd=0;    //傳輸結(jié)束標(biāo)置位,在中斷服務(wù)置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;//超時(shí)
  676.   if(TransferError!=SD_OK)errorstatus=TransferError;  
  677.     }   
  678.   return errorstatus;
  679. }
  680. //SD卡讀取多個(gè)塊
  681. //buf:讀數(shù)據(jù)緩存區(qū)
  682. //addr:讀取地址
  683. //blksize:塊大小
  684. //nblks:要讀取的塊數(shù)
  685. //返回值:錯(cuò)誤狀態(tài)
  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;//轉(zhuǎn)換為u32指針

  694.   SDIO->DCTRL=0x0;  //數(shù)據(jù)控制寄存器清零(關(guān)DMA)   
  695. if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
  696. {
  697.   blksize=512;
  698.   addr>>=9;
  699. }  

  700.    SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;//清除DPSM狀態(tài)機(jī)配置
  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;//發(fā)送CMD16+設(shè)置數(shù)據(jù)長(zhǎng)度為blksize,短響應(yīng)
  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響應(yīng)  
  720.   
  721.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  722.   
  723. }else return SD_INVALID_PARAMETER;   

  724. if(nblks>1)           //多塊讀  
  725. {            
  726.      if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;//判斷是否超過最大接收長(zhǎng)度
  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;//發(fā)送CMD18+從addr地址出讀取數(shù)據(jù),短響應(yīng)
  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響應(yīng)
  743.   
  744.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  745.   
  746.    if(DeviceMode==SD_POLLING_MODE)
  747.   {
  748.    INTX_DISABLE();//關(guān)閉總中斷(POLLING模式,嚴(yán)禁中斷打斷SDIO讀寫操作!!!)
  749.    while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<8)|(1<<9))))//無上溢/CRC/超時(shí)/完成(標(biāo)志)/起始位錯(cuò)誤
  750.    {
  751.     if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)      //接收區(qū)半滿,表示至少存了8個(gè)字
  752.     {
  753.      for(count=0;count<8;count++)   //循環(huán)讀取數(shù)據(jù)
  754.      {
  755.       *(tempbuff+count)=SDIO->FIFO;
  756.      }
  757.      tempbuff+=8;  
  758.      timeout=0X7FFFFF;  //讀數(shù)據(jù)溢出時(shí)間
  759.     }else  //處理超時(shí)
  760.     {
  761.      if(timeout==0)return SD_DATA_TIMEOUT;
  762.      timeout--;
  763.     }
  764.    }  
  765.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //數(shù)據(jù)超時(shí)錯(cuò)誤
  766.   {            
  767.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清錯(cuò)誤標(biāo)志
  768.    return SD_DATA_TIMEOUT;
  769.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //數(shù)據(jù)塊CRC錯(cuò)誤
  770.   {
  771.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  772.    return SD_DATA_CRC_FAIL;     
  773.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢錯(cuò)誤
  774.   {
  775.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清錯(cuò)誤標(biāo)志
  776.    return SD_RX_OVERRUN;   
  777.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位錯(cuò)誤
  778.   {
  779.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清錯(cuò)誤標(biāo)志
  780.    return SD_START_BIT_ERR;   
  781.   }   
  782.      
  783.   while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) //FIFO里面,還存在可用數(shù)據(jù)
  784.   {
  785.    *tempbuff=SDIO->FIFO; //循環(huán)讀取數(shù)據(jù)
  786.    tempbuff++;
  787.   }
  788.     if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)  //接收結(jié)束
  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;//發(fā)送CMD12+結(jié)束傳輸
  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響應(yīng)   
  800.      
  801.      if(errorstatus!=SD_OK)return errorstatus;  
  802.     }
  803.     }
  804.    INTX_ENABLE();//開啟總中斷
  805.     SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  806.    }else if(DeviceMode==SD_DMA_MODE)
  807.   {
  808.       TransferError=SD_OK;
  809.    StopCondition=1;   //多塊讀,需要發(fā)送停止傳輸指令
  810.    TransferEnd=0;    //傳輸結(jié)束標(biāo)置位,在中斷服務(wù)置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;//超時(shí)
  816.    while((TransferEnd==0)&&(TransferError==SD_OK));
  817.    if(TransferError!=SD_OK)errorstatus=TransferError;   
  818.   }   
  819.    }
  820. return errorstatus;
  821. }                        
  822. //SD卡寫1個(gè)塊
  823. //buf:數(shù)據(jù)緩存區(qū)
  824. //addr:寫地址
  825. //blksize:塊大小   
  826. //返回值:錯(cuò)誤狀態(tài)
  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;      //總長(zhǎng)度(字節(jié))

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

  835.   if(buf==NULL)return SD_INVALID_PARAMETER;//參數(shù)錯(cuò)誤  

  836.   SDIO->DCTRL=0x0;       //數(shù)據(jù)控制寄存器清零(關(guān)DMA)

  837. SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ;//清除DPSM狀態(tài)機(jī)配置
  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;//發(fā)送CMD16+設(shè)置數(shù)據(jù)長(zhǎng)度為blksize,短響應(yīng)  
  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響應(yīng)  
  862.   
  863.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  864.   
  865. }else return SD_INVALID_PARAMETER;

  866.    SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//發(fā)送CMD13,查詢卡的狀態(tài),短響應(yīng)  
  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響應(yīng)  

  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;//發(fā)送CMD13,查詢卡的狀態(tài),短響應(yīng)
  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響應(yīng)   
  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;//發(fā)送CMD24,寫單塊指令,短響應(yīng)  
  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響應(yīng)  

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

  902. StopCondition=0;         //單塊寫,不需要發(fā)送停止傳輸指令
  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();//關(guān)閉總中斷(POLLING模式,嚴(yán)禁中斷打斷SDIO讀寫操作!!!)
  914.   while(!(SDIO->STA&((1<<10)|(1<<4)|(1<<1)|(1<<3)|(1<<9))))//數(shù)據(jù)塊發(fā)送成功/下溢/CRC/超時(shí)/起始位錯(cuò)誤
  915.   {
  916.    if(SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)       //發(fā)送區(qū)半空,表示至少存了8個(gè)字
  917.    {
  918.     if((tlen-bytestransferred)<SD_HALFFIFOBYTES)//不夠32字節(jié)了
  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; //寫數(shù)據(jù)溢出時(shí)間
  936.    }else
  937.    {
  938.     if(timeout==0)return SD_DATA_TIMEOUT;
  939.     timeout--;
  940.    }
  941.   }
  942.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //數(shù)據(jù)超時(shí)錯(cuò)誤
  943.   {            
  944.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清錯(cuò)誤標(biāo)志
  945.    return SD_DATA_TIMEOUT;
  946.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //數(shù)據(jù)塊CRC錯(cuò)誤
  947.   {
  948.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  949.    return SD_DATA_CRC_FAIL;     
  950.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)  //接收fifo下溢錯(cuò)誤
  951.   {
  952.     SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);  //清錯(cuò)誤標(biāo)志
  953.    return SD_TX_UNDERRUN;   
  954.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位錯(cuò)誤
  955.   {
  956.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清錯(cuò)誤標(biāo)志
  957.    return SD_START_BIT_ERR;   
  958.   }   
  959.       
  960.   INTX_ENABLE();//開啟總中斷
  961.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記  
  962. }else if(DeviceMode==SD_DMA_MODE)
  963. {
  964.      TransferError=SD_OK;
  965.   StopCondition=0;   //單塊寫,不需要發(fā)送停止傳輸指令
  966.   TransferEnd=0;    //傳輸結(jié)束標(biāo)置位,在中斷服務(wù)置1
  967.   SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9); //配置產(chǎn)生數(shù)據(jù)接收完成中斷
  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卡,可以解決寫入死機(jī)的問題
  974.    return SD_DATA_TIMEOUT;   //超時(shí)  
  975.    }
  976.   timeout=SDIO_DATATIMEOUT;
  977.   while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
  978.    if(timeout==0)return SD_DATA_TIMEOUT;   //超時(shí)  
  979.     if(TransferError!=SD_OK)return TransferError;
  980.   }  
  981.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  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卡寫多個(gè)塊
  990. //buf:數(shù)據(jù)緩存區(qū)
  991. //addr:寫地址
  992. //blksize:塊大小
  993. //nblks:要寫入的塊數(shù)
  994. //返回值:錯(cuò)誤狀態(tài)               
  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;    //總長(zhǎng)度(字節(jié))
  1002. u32 *tempbuff = (u32*)buf;  
  1003.   if(buf==NULL)return SD_INVALID_PARAMETER; //參數(shù)錯(cuò)誤  
  1004.   SDIO->DCTRL=0x0;       //數(shù)據(jù)控制寄存器清零(關(guān)DMA)   

  1005. SDIO_DataInitStructure.SDIO_DataBlockSize= 0; ; //清除DPSM狀態(tài)機(jī)配置
  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; //發(fā)送CMD16+設(shè)置數(shù)據(jù)長(zhǎng)度為blksize,短響應(yīng)
  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響應(yīng)  
  1030.   
  1031.   if(errorstatus!=SD_OK)return errorstatus;    //響應(yīng)錯(cuò)誤  
  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;  //發(fā)送ACMD55,短響應(yīng)  
  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響應(yīng)
  1048.    
  1049.    if(errorstatus!=SD_OK)return errorstatus;     
  1050.    
  1051.     SDIO_CmdInitStructure.SDIO_Argument =nblks;  //發(fā)送CMD23,設(shè)置塊數(shù)量,短響應(yīng)   
  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響應(yīng)
  1059.    
  1060.    if(errorstatus!=SD_OK)return errorstatus;  
  1061.       
  1062.   }
  1063.     SDIO_CmdInitStructure.SDIO_Argument =addr; //發(fā)送CMD25,多塊寫指令,短響應(yīng)   
  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響應(yīng)        

  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();//關(guān)閉總中斷(POLLING模式,嚴(yán)禁中斷打斷SDIO讀寫操作!!!)
  1083.    while(!(SDIO->STA&((1<<4)|(1<<1)|(1<<8)|(1<<3)|(1<<9))))//下溢/CRC/數(shù)據(jù)結(jié)束/超時(shí)/起始位錯(cuò)誤
  1084.    {
  1085.     if(SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)       //發(fā)送區(qū)半空,表示至少存了8字(32字節(jié))
  1086.     {   
  1087.      if((tlen-bytestransferred)<SD_HALFFIFOBYTES)//不夠32字節(jié)了
  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           //發(fā)送區(qū)半空,可以發(fā)送至少8字(32字節(jié))數(shù)據(jù)
  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; //寫數(shù)據(jù)溢出時(shí)間
  1104.     }else
  1105.     {
  1106.      if(timeout==0)return SD_DATA_TIMEOUT;
  1107.      timeout--;
  1108.     }
  1109.    }
  1110.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //數(shù)據(jù)超時(shí)錯(cuò)誤
  1111.   {            
  1112.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清錯(cuò)誤標(biāo)志
  1113.    return SD_DATA_TIMEOUT;
  1114.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //數(shù)據(jù)塊CRC錯(cuò)誤
  1115.   {
  1116.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  1117.    return SD_DATA_CRC_FAIL;     
  1118.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)  //接收fifo下溢錯(cuò)誤
  1119.   {
  1120.     SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);  //清錯(cuò)誤標(biāo)志
  1121.    return SD_TX_UNDERRUN;   
  1122.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位錯(cuò)誤
  1123.   {
  1124.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清錯(cuò)誤標(biāo)志
  1125.    return SD_START_BIT_ERR;   
  1126.   }   
  1127.                     
  1128.    if(SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)  //發(fā)送結(jié)束
  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;//發(fā)送CMD12+結(jié)束傳輸   
  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響應(yīng)   
  1140.      if(errorstatus!=SD_OK)return errorstatus;  
  1141.     }
  1142.    }
  1143.    INTX_ENABLE();//開啟總中斷
  1144.     SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1145.      }else if(DeviceMode==SD_DMA_MODE)
  1146.   {
  1147.      TransferError=SD_OK;
  1148.    StopCondition=1;   //多塊寫,需要發(fā)送停止傳輸指令
  1149.    TransferEnd=0;    //傳輸結(jié)束標(biāo)置位,在中斷服務(wù)置1
  1150.    SDIO->MASK|=(1<<1)|(1<<3)|(1<<8)|(1<<4)|(1<<9); //配置產(chǎn)生數(shù)據(jù)接收完成中斷
  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)          //超時(shí)
  1156.    {           
  1157.       SD_Init();       //重新初始化SD卡,可以解決寫入死機(jī)的問題
  1158.      return SD_DATA_TIMEOUT;   //超時(shí)  
  1159.     }
  1160.    timeout=SDIO_DATATIMEOUT;
  1161.    while((TransferEnd==0)&&(TransferError==SD_OK)&&timeout)timeout--;
  1162.     if(timeout==0)return SD_DATA_TIMEOUT;   //超時(shí)  
  1163.     if(TransferError!=SD_OK)return TransferError;  
  1164.   }
  1165.    }
  1166.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  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中斷服務(wù)函數(shù)   
  1175. void SDIO_IRQHandler(void)
  1176. {           
  1177.   SD_ProcessIRQSrc();//處理所有SDIO相關(guān)中斷
  1178. }                     
  1179. //SDIO中斷處理函數(shù)
  1180. //處理SDIO傳輸過程中的各種中斷事務(wù)
  1181. //返回值:錯(cuò)誤代碼
  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;//發(fā)送CMD12+結(jié)束傳輸   
  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;//清除完成中斷標(biāo)記
  1198.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1199.    TransferEnd = 1;
  1200.   return(TransferError);
  1201. }
  1202.   if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)//數(shù)據(jù)CRC錯(cuò)誤
  1203. {
  1204.   SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  1205.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1206.      TransferError = SD_DATA_CRC_FAIL;
  1207.      return(SD_DATA_CRC_FAIL);
  1208. }
  1209.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)//數(shù)據(jù)超時(shí)錯(cuò)誤
  1210. {
  1211.   SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);     //清中斷標(biāo)志
  1212.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1213.      TransferError = SD_DATA_TIMEOUT;
  1214.      return(SD_DATA_TIMEOUT);
  1215. }
  1216.    if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)//FIFO上溢錯(cuò)誤
  1217. {
  1218.   SDIO_ClearFlag(SDIO_FLAG_RXOVERR);     //清中斷標(biāo)志
  1219.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1220.      TransferError = SD_RX_OVERRUN;
  1221.      return(SD_RX_OVERRUN);
  1222. }
  1223.     if(SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)//FIFO下溢錯(cuò)誤
  1224. {
  1225.   SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);     //清中斷標(biāo)志
  1226.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1227.      TransferError = SD_TX_UNDERRUN;
  1228.      return(SD_TX_UNDERRUN);
  1229. }
  1230. if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)//起始位錯(cuò)誤
  1231. {
  1232.   SDIO_ClearFlag(SDIO_FLAG_STBITERR);    //清中斷標(biāo)志
  1233.   SDIO->MASK&=~((1<<1)|(1<<3)|(1<<8)|(1<<14)|(1<<15)|(1<<4)|(1<<5)|(1<<9));//關(guān)閉相關(guān)中斷
  1234.      TransferError = SD_START_BIT_ERR;
  1235.      return(SD_START_BIT_ERR);
  1236. }
  1237. return(SD_OK);
  1238. }
  1239.   
  1240. //檢查CMD0的執(zhí)行狀態(tài)
  1241. //返回值:sd卡錯(cuò)誤碼
  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; //命令已發(fā)送(無需響應(yīng))  
  1249. }     
  1250. if(timeout==0)return SD_CMD_RSP_TIMEOUT;  
  1251. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1252. return errorstatus;
  1253. }  
  1254. //檢查R7響應(yīng)的錯(cuò)誤狀態(tài)
  1255. //返回值:sd卡錯(cuò)誤碼
  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錯(cuò)誤/命令響應(yīng)超時(shí)/已經(jīng)收到響應(yīng)(CRC校驗(yàn)成功)
  1265. }
  1266.   if((timeout==0)||(status&(1<<2))) //響應(yīng)超時(shí)
  1267. {                        
  1268.   errorstatus=SD_CMD_RSP_TIMEOUT; //當(dāng)前卡不是2.0兼容卡,或者不支持設(shè)定的電壓范圍
  1269.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);    //清除命令響應(yīng)超時(shí)標(biāo)志
  1270.   return errorstatus;
  1271. }  
  1272. if(status&1<<6)      //成功接收到響應(yīng)
  1273. {           
  1274.   errorstatus=SD_OK;
  1275.   SDIO_ClearFlag(SDIO_FLAG_CMDREND);     //清除響應(yīng)標(biāo)志
  1276.   }
  1277. return errorstatus;
  1278. }   
  1279. //檢查R1響應(yīng)的錯(cuò)誤狀態(tài)
  1280. //cmd:當(dāng)前命令
  1281. //返回值:sd卡錯(cuò)誤碼
  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錯(cuò)誤/命令響應(yīng)超時(shí)/已經(jīng)收到響應(yīng)(CRC校驗(yàn)成功)
  1289. }
  1290. if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //響應(yīng)超時(shí)
  1291. {                        
  1292.    SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);     //清除命令響應(yīng)超時(shí)標(biāo)志
  1293.   return SD_CMD_RSP_TIMEOUT;
  1294. }
  1295.   if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)     //CRC錯(cuò)誤
  1296. {                        
  1297.    SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);     //清除標(biāo)志
  1298.   return SD_CMD_CRC_FAIL;
  1299. }  
  1300. if(SDIO->RESPCMD!=cmd)return SD_ILLEGAL_CMD;//命令不匹配
  1301.   SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1302. return (SD_Error)(SDIO->RESP1&SD_OCR_ERRORBITS);//返回卡響應(yīng)
  1303. }
  1304. //檢查R3響應(yīng)的錯(cuò)誤狀態(tài)
  1305. //返回值:錯(cuò)誤狀態(tài)
  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錯(cuò)誤/命令響應(yīng)超時(shí)/已經(jīng)收到響應(yīng)(CRC校驗(yàn)成功)
  1313. }
  1314.   if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //響應(yīng)超時(shí)
  1315. {            
  1316.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令響應(yīng)超時(shí)標(biāo)志
  1317.   return SD_CMD_RSP_TIMEOUT;
  1318. }  
  1319.    SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1320.   return SD_OK;         
  1321. }
  1322. //檢查R2響應(yīng)的錯(cuò)誤狀態(tài)
  1323. //返回值:錯(cuò)誤狀態(tài)
  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錯(cuò)誤/命令響應(yīng)超時(shí)/已經(jīng)收到響應(yīng)(CRC校驗(yàn)成功)
  1333. }
  1334.    if((timeout==0)||(status&(1<<2))) //響應(yīng)超時(shí)
  1335. {                        
  1336.   errorstatus=SD_CMD_RSP_TIMEOUT;
  1337.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令響應(yīng)超時(shí)標(biāo)志
  1338.   return errorstatus;
  1339. }  
  1340. if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)      //CRC錯(cuò)誤
  1341. {           
  1342.   errorstatus=SD_CMD_CRC_FAIL;
  1343.   SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);  //清除響應(yīng)標(biāo)志
  1344.   }
  1345. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1346.   return errorstatus;               
  1347. }
  1348. //檢查R6響應(yīng)的錯(cuò)誤狀態(tài)
  1349. //cmd:之前發(fā)送的命令
  1350. //prca:卡返回的RCA地址
  1351. //返回值:錯(cuò)誤狀態(tài)
  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錯(cuò)誤/命令響應(yīng)超時(shí)/已經(jīng)收到響應(yīng)(CRC校驗(yàn)成功)
  1361. }
  1362. if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)     //響應(yīng)超時(shí)
  1363. {                        
  1364.    SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除命令響應(yīng)超時(shí)標(biāo)志
  1365.   return SD_CMD_RSP_TIMEOUT;
  1366. }   
  1367. if(SDIO_GetFlagStatus(SDIO_FLAG_CCRCFAIL) != RESET)      //CRC錯(cuò)誤
  1368. {           
  1369.   SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL);     //清除響應(yīng)標(biāo)志
  1370.    return SD_CMD_CRC_FAIL;
  1371. }
  1372. if(SDIO->RESPCMD!=cmd)    //判斷是否響應(yīng)cmd命令
  1373. {
  1374.    return SD_ILLEGAL_CMD;   
  1375. }     
  1376. SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1377. rspr1=SDIO->RESP1;     //得到響應(yīng)   
  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. //返回值:錯(cuò)誤狀態(tài)
  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狀態(tài)      
  1399.   errorstatus=FindSCR(RCA,scr);      //得到SCR寄存器數(shù)據(jù)
  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;//發(fā)送CMD55+RCA,短響應(yīng)
  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;//發(fā)送ACMD6,短響應(yīng),參數(shù):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;    //不支持寬總線設(shè)置   
  1425. }               
  1426. //檢查卡是否正在執(zhí)行寫操作
  1427. //pstatus:當(dāng)前狀態(tài).
  1428. //返回值:錯(cuò)誤代碼
  1429. SD_Error IsCardProgramming(u8 *pstatus)
  1430. {
  1431.   vu32 respR1 = 0, status = 0;  
  1432.   
  1433.   SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16; //卡相對(duì)地址參數(shù)
  1434.   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;//發(fā)送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檢測(cè)失敗
  1443. {  
  1444.    SDIO_ClearFlag(SDIO_FLAG_CCRCFAIL); //清除錯(cuò)誤標(biāo)記
  1445.   return SD_CMD_CRC_FAIL;
  1446. }
  1447.     if(SDIO_GetFlagStatus(SDIO_FLAG_CTIMEOUT) != RESET)   //命令超時(shí)
  1448. {
  1449.   SDIO_ClearFlag(SDIO_FLAG_CTIMEOUT);   //清除錯(cuò)誤標(biāo)記
  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);//清除所有標(biāo)記
  1454. respR1=SDIO->RESP1;
  1455. *pstatus=(u8)((respR1>>9)&0x0000000F);
  1456. return SD_OK;
  1457. }
  1458. //讀取當(dāng)前卡狀態(tài)
  1459. //pcardstatus:卡狀態(tài)
  1460. //返回值:錯(cuò)誤代碼
  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;//發(fā)送CMD13,短響應(yīng)   
  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); //查詢響應(yīng)狀態(tài)
  1476. if(errorstatus!=SD_OK)return errorstatus;
  1477. *pcardstatus=SDIO->RESP1;//讀取響應(yīng)值
  1478. return errorstatus;
  1479. }
  1480. //返回SD卡的狀態(tài)
  1481. //返回值:SD卡狀態(tài)
  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:卡相對(duì)地址
  1490. //pscr:數(shù)據(jù)緩存區(qū)(存儲(chǔ)SCR內(nèi)容)
  1491. //返回值:錯(cuò)誤狀態(tài)     
  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;  //發(fā)送CMD16,短響應(yīng),設(shè)置Block Size為8字節(jié)
  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;//發(fā)送CMD55,短響應(yīng)  
  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個(gè)字節(jié)長(zhǎng)度,block為8字節(jié),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; //發(fā)送ACMD51,短響應(yīng),參數(shù)為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數(shù)據(jù)可用
  1531.   {
  1532.    *(tempscr+index)=SDIO->FIFO; //讀取FIFO內(nèi)容
  1533.    index++;
  1534.    if(index>=2)break;
  1535.   }
  1536. }
  1537.   if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)  //數(shù)據(jù)超時(shí)錯(cuò)誤
  1538.   {            
  1539.     SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);  //清錯(cuò)誤標(biāo)志
  1540.    return SD_DATA_TIMEOUT;
  1541.    }else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //數(shù)據(jù)塊CRC錯(cuò)誤
  1542.   {
  1543.     SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);    //清錯(cuò)誤標(biāo)志
  1544.    return SD_DATA_CRC_FAIL;     
  1545.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)  //接收fifo上溢錯(cuò)誤
  1546.   {
  1547.     SDIO_ClearFlag(SDIO_FLAG_RXOVERR);  //清錯(cuò)誤標(biāo)志
  1548.    return SD_RX_OVERRUN;   
  1549.   }else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)  //接收起始位錯(cuò)誤
  1550.   {
  1551.     SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清錯(cuò)誤標(biāo)志
  1552.    return SD_START_BIT_ERR;   
  1553.   }  
  1554.    SDIO_ClearFlag(SDIO_STATIC_FLAGS);//清除所有標(biāo)記
  1555. //把數(shù)據(jù)順序按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為底的指數(shù).
  1561. //NumberOfBytes:字節(jié)數(shù).
  1562. //返回值:以2為底的指數(shù)值
  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:存儲(chǔ)器地址
  1575. //bufsize:傳輸數(shù)據(jù)量
  1576. //dir:方向;DMA_DIR_MemoryToPeripheral  存儲(chǔ)器-->SDIO(寫數(shù)據(jù));DMA_DIR_PeripheralToMemory SDIO-->存儲(chǔ)器(讀數(shù)據(jù));
  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上的所有中斷標(biāo)志


  1583.   DMA_InitStructure.DMA_Channel = DMA_Channel_4;  //通道選擇
  1584.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SDIO->FIFO;//DMA外設(shè)地址
  1585.   DMA_InitStructure.DMA_Memory0BaseAddr = (u32)mbuf;//DMA 存儲(chǔ)器0地址
  1586.   DMA_InitStructure.DMA_DIR = dir;//存儲(chǔ)器到外設(shè)模式
  1587.   DMA_InitStructure.DMA_BufferSize = 0;//數(shù)據(jù)傳輸量
  1588.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設(shè)非增量模式
  1589.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲(chǔ)器增量模式
  1590.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外設(shè)數(shù)據(jù)長(zhǎng)度:32位
  1591.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//存儲(chǔ)器數(shù)據(jù)長(zhǎng)度:32位
  1592.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
  1593.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//最高優(yōu)先級(jí)
  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;//外設(shè)突發(fā)4次傳輸
  1597.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;//存儲(chǔ)器突發(fā)4次傳輸
  1598.   DMA_Init(DMA2_Stream3, &DMA_InitStructure);//初始化DMA Stream
  1599. DMA_FlowControllerConfig(DMA2_Stream3,DMA_FlowCtrl_Peripheral);//外設(shè)流控制
  1600.   
  1601.   DMA_Cmd(DMA2_Stream3 ,ENABLE);//開啟DMA傳輸  
  1602. }   

  1603. //讀SD卡
  1604. //buf:讀數(shù)據(jù)緩存區(qū)
  1605. //sector:扇區(qū)地址
  1606. //cnt:扇區(qū)個(gè)數(shù)
  1607. //返回值:錯(cuò)誤狀態(tài);0,正常;其他,錯(cuò)誤代碼;           
  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);//單個(gè)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);     //單個(gè)sector的讀操作
  1625.   else sta=SD_ReadMultiBlocks(buf,lsector,512,cnt);//多個(gè)sector  
  1626. }
  1627. return sta;
  1628. }
  1629. //寫SD卡
  1630. //buf:寫數(shù)據(jù)緩存區(qū)
  1631. //sector:扇區(qū)地址
  1632. //cnt:扇區(qū)個(gè)數(shù)
  1633. //返回值:錯(cuò)誤狀態(tài);0,正常;其他,錯(cuò)誤代碼;
  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);//單個(gè)sector的寫操作
  1646.    buf+=512;
  1647.   }
  1648. }else
  1649. {
  1650.   if(cnt==1)sta=SD_WriteBlock(buf,lsector,512);     //單個(gè)sector的寫操作
  1651.   else sta=SD_WriteMultiBlocks(buf,lsector,512,cnt); //多個(gè)sector  
  1652. }
  1653. return sta;
  1654. }
復(fù)制代碼

代碼下載: 6-ADC采集+文件系統(tǒng).7z (829.79 KB, 下載次數(shù): 76)

評(píng)分

參與人數(shù) 1黑幣 +30 收起 理由
admin + 30 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:114007 發(fā)表于 2023-9-19 14:24 | 只看該作者
下載之后直接編譯報(bào)錯(cuò)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲天堂一区二区 | 久久草在线视频 | 国产精品婷婷 | 精品国产乱码一区二区三 | 国产黄色小视频 | 国产二区视频 | 国产9 9在线 | 中文 | 日韩精品一区二区三区中文在线 | 成人欧美一区二区三区视频xxx | 在线免费看毛片 | 日日噜噜噜夜夜爽爽狠狠视频97 | 国产精品99久久久久久www | 欧美中文在线 | www.伊人.com| www.黄色片视频 | 亚洲欧洲视频 | 视频一区二区在线观看 | 久久1区 | 秋霞av国产精品一区 | 天天爱爱网 | 久久久久久久久久久久91 | 九九综合| 中文字幕在线观看www | 四虎永久免费在线 | 亚洲97| 国产高清免费在线 | 国产成人免费视频网站视频社区 | 成人精品免费视频 | 国产福利视频 | 欧美日韩一区二区在线观看 | 午夜免费福利影院 | 天堂av中文 | 久草综合在线视频 | av在线播放一区二区 | 亚洲成人中文字幕 | 久久国产精品一区二区三区 | 午夜爽爽爽男女免费观看影院 | 欧美精品1区| 欧美成人一区二区三区片免费 | 国产欧美日韩视频 | 国产sm主人调教女m视频 |