程序函数分析
(一),初始化函数
SD_Error SD_Init(void) { /*重置SD_Error状态*/ SD_Error errorstatus = SD_OK; /* SDIO 外设底层引脚初始化*/ GPIO_Configuration(); /*对SDIO的所有寄存器进行复位*/ SDIO_DeInit(); /*上电并进行卡识别流程,确认卡的操作电压 */ errorstatus = SD_PowerON(); /*如果上电,识别不成功,返回“响应超时”错误*/ if (errorstatus != SD_OK) { /*!< CMD Response TimeOut (wait for CMDSENT flag) */ return(errorstatus); } /*卡识别成功,进行卡初始化 */ errorstatus = SD_InitializeCards(); if (errorstatus != SD_OK) //失败返回 { /*!< CMD Response TimeOut (wait for CMDSENT flag) */ return(errorstatus); } /* 配置SDIO外设 *上电识别,卡初始化都完成后,进入数据传输模式,提高读写速度 * 速度若超过24M要进入bypass */ /* SDIOCLK = HCLK, SDIO_CK = HCLK/(2 + SDIO_TRANSFER_CLK_DIV) */ SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; /*上升沿采集数据*/ SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; /* 时钟频率若超过24M,要开启此模式*/ SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; /* 若开启此功能,在总线空闲时关闭sd_clk时钟 */ SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; /* 暂时配置成1bit模式 */ SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; /*硬件流,若开启,在FIFO不能进行发送和接受数据时,数据传输暂停*/ SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_Init(&SDIO_InitStructure); if (errorstatus == SD_OK) { /* 用来读取csd/cid寄存器*/ errorstatus = SD_GetCardInfo(&SDCardInfo); } if (errorstatus == SD_OK) { /* 通过cmd7,rca选择要操作的卡 */ errorstatus = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16)); } if (errorstatus == SD_OK) { /* 最后为了提高读写,开启4bits模式*/ errorstatus = SD_EnableWideBusOperation(SDIO_BusWide_4b); } return(errorstatus); }
解析:
流程图
1.往SD卡传数据量大,会占用很大的CPU资源,为了防止他一直占用CPU资源,我们用DMA来处理数据,这个速度也很快;
2.对于SD_PowerON()当中CMD*是对应寄存器中的命令,
CMD0: 没有返回响应
我们的板子上往往只接了一个卡,但SDIO总线可以并联许多个卡
3.SDIO支持的端口电压是2.6-3.8左右,发送CMD8来确定卡的供电电压是不是在这个范围,以及来判断卡的类型,是2.0的还是,,,
4.PWR UP位:确定好电压后,SD卡里面的寄存器PWR UP就会至1,表示电压已经确定好了,HCS位:0,标准的卡(小于2GB)1,大容量的卡(2-32GB) 32GB-2T的暂时没考虑