STM32之SD卡驅動(dòng)
44.3 軟件設計
打開(kāi)上一章的工程,首先在HARDWARE文件夾下新建一個(gè)SD的文件夾。然后新建一個(gè)MMC_SD.C和MMC_SD.H的文件保存在SD文件夾下,并將這個(gè)文件夾加入頭文件包含路徑。
打開(kāi)MMC_SD.C文件,在該文件里面,我們輸入與SD卡相關(guān)的操作代碼,這里由于篇幅限制,我們不貼出所有代碼,僅介紹兩個(gè)最重要的函數,第一個(gè)是SD_Initialize函數,該函數源碼如下:
//初始化SD卡
u8 SD_Initialize(void)
{ u8 r1; // 存放SD卡的返回值 u16 retry; // 用來(lái)進(jìn)行超時(shí)計數 u8 buf[4]; u16 i; SD_SPI_Init(); //初始化IO SD_SPI_SpeedLow(); //設置到低速模式 for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//發(fā)送最少74個(gè)脈沖 retry=20; do { r1=SD_SendCmd(CMD0,0,0x95);//進(jìn)入IDLE狀態(tài) }while((r1!=0X01) && retry--); SD_Type=0;//默認無(wú)卡 if(r1==0X01) { if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0 { for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到R7相應值 if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V { retry=0XFFFE; do { SD_SendCmd(CMD55,0,0X01); //發(fā)送CMD55 r1=SD_SendCmd(CMD41,0x40000000,0X01);//發(fā)送CMD41 }while(r1&&retry--); if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//鑒別SD2.0卡版本開(kāi)始 { for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到OCR值 if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //檢查CCS else SD_Type=SD_TYPE_V2; } } }else//SD V1.x/ MMC V3 { SD_SendCmd(CMD55,0,0X01); //發(fā)送CMD55 r1=SD_SendCmd(CMD41,0,0X01); //發(fā)送CMD41 if(r1<=1) { SD_Type=SD_TYPE_V1; retry=0XFFFE; do //等待退出IDLE模式 { SD_SendCmd(CMD55,0,0X01); //發(fā)送CMD55 r1=SD_SendCmd(CMD41,0,0X01);//發(fā)送CMD41 }while(r1&&retry--); }else//MMC卡不支持CMD55+CMD41識別 { SD_Type=SD_TYPE_MMC;//MMC V3 retry=0XFFFE; do //等待退出IDLE模式 { r1=SD_SendCmd(CMD1,0,0X01);//發(fā)送CMD1 }while(r1&&retry--); } if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;
//錯誤的卡 } } SD_DisSelect();//取消片選 SD_SPI_SpeedHigh();//高速 if(SD_Type)return 0; else if(r1)return r1; return 0xaa;//其他錯誤
}
該函數先設置與SD相關(guān)的IO口及SPI初始化,然后發(fā)送CMD0,進(jìn)入IDLE狀態(tài),并設置SD卡為SPI模式通信,然后判斷SD卡類(lèi)型,完成SD卡的初始化,注意該函數調用的SD_SPI_Init等函數,實(shí)際是對SPI2的相關(guān)函數進(jìn)行了一層封裝,方便移植。另外一個(gè)要介紹的函數是SD_ReadDisk,該函數用于從SD卡讀取一個(gè)扇區的數據(這里一般為512字節),該函數代碼如下:
//讀SD卡
//buf:數據緩存區
//sector:扇區
//cnt:扇區數
//返回值:0,ok;其他,失敗.
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
{ u8 r1; if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//轉換為字節地址 if(cnt==1) { r1=SD_SendCmd(CMD17,sector,0X01); //讀命令 if(r1==0) r1=SD_RecvData(buf,512); //命令發(fā)送成功,接收512個(gè)字節 }else { r1=SD_SendCmd(CMD18,sector,0X01);//連續讀命令 do { r1=SD_RecvData(buf,512);//接收512個(gè)字節 buf+=512; }while(--cnt && r1==0); SD_SendCmd(CMD12,0,0X01); //發(fā)送停止命令 } SD_DisSelect();//取消片選 return r1;//
}
此函數先發(fā)送CMD17命令,然后讀取一個(gè)扇區的數據,詳細見(jiàn)代碼,這里我們就不多介紹了。保存MMC_SD.C文件,并加入到HARDWARE組下,然后打開(kāi)MMC_SD.H,在該文件里面輸入如下代碼:
#ifndef _MMC_SD_H_
#define _MMC_SD_H_
#include "sys.h"
#include
// SD卡類(lèi)型定義
#define SD_TYPE_ERR 0X00
#define SD_TYPE_MMC 0X01
#define SD_TYPE_V1 0X02
#define SD_TYPE_V2 0X04
#define SD_TYPE_V2HC 0X06
// SD卡指令表
#define CMD0 0 //卡復位
#define CMD1 1
#define CMD8 8 //命令8 ,SEND_IF_COND
#define CMD9 9 //命令9 ,讀CSD數據
#define CMD10 10 //命令10,讀CID數據
#define CMD12 12 //命令12,停止數據傳輸
#define CMD16 16 //命令16,設置SectorSize 應返回0x00
#define CMD17 17 //命令17,讀sector
#define CMD18 18 //命令18,讀Multi sector
#define CMD23 23 //命令23,設置多sector寫(xiě)入前預先擦除N個(gè)block
#define CMD24 24 //命令24,寫(xiě)sector
#define CMD25 25 //命令25,寫(xiě)Multi sector
#define CMD41 41 //命令41,應返回0x00
#define CMD55 55 //命令55,應返回0x01
#define CMD58 58 //命令58,讀OCR信息
#define CMD59 59 //命令59,使能/禁止CRC,應返回0x00
//數據寫(xiě)入回應字意義
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
//SD卡回應標記字
#define MSD_RESPONSE_NO_ERROR 0x00
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
//這部分應根據具體的連線(xiàn)來(lái)修改!
//戰艦STM32開(kāi)發(fā)板使用的是PD2作為SD卡的CS腳.
#define SD_CS PDout(2) //SD卡片選引腳 extern u8 SD_Type;//SD卡的類(lèi)型
//函數申明區
u8 SD_SPI_ReadWriteByte(u8 data);
void SD_SPI_SpeedLow(void);
void SD_SPI_SpeedHigh(void);
u8 SD_WaitReady(void); //等待SD卡準備
u8 SD_GetResponse(u8 Response); //獲得相應
u8 SD_Initialize(void); //初始化
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt); //讀塊
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt); //寫(xiě)塊
u32 SD_GetSectorCount(void); //讀扇區數
u8 SD_GetCID(u8 *cid_data); //讀SD卡CID
u8 SD_GetCSD(u8 *csd_data); //讀SD卡CSD
#endif
該部分代碼主要是一些命令的宏定義以及函數聲明,在這里我們設定了SD卡的CS管腳為PD2。保存MMC_SD.H,就可以在主函數里面編寫(xiě)我們的應用代碼了,打開(kāi)test.c文件,在該文件中修改main函數如下:
int main(void)
{ u8 key; u8 t=0; u8 *buf; u32 sd_size; Stm32_Clock_Init(9); //系統時(shí)鐘設置 uart_init(72,9600); //串口初始化為9600 delay_init(72); //延時(shí)初始化 LED_Init(); //初始化與LED連接的硬件接口 LCD_Init(); //初始化LCD usmart_dev.init(72); //初始化USMART KEY_Init(); //按鍵初始化 FSMC_SRAM_Init(); //初始化外部SRAM mem_init(SRAMIN); //初始化內部?jì)却娉?wbr /> POINT_COLOR=RED;//設置字體為紅色 LCD_ShowString(60,50,200,16,16,"WarShip STM32"); LCD_ShowString(60,70,200,16,16,"SD CARD TEST"); LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(60,110,200,16,16,"2012/9/17"); LCD_ShowString(60,130,200,16,16,"KEY0:Read Sector 0"); while(SD_Initialize())//檢測不到SD卡 { LCD_ShowString(60,150,200,16,16,"SD Card Error!"); delay_ms(500); LCD_ShowString(60,150,200,16,16,"Please Check! "); delay_ms(500); LED0=!LED0;//DS0閃爍 } POINT_COLOR=BLUE;//設置字體為藍色 //檢測SD卡成功 LCD_ShowString(60,150,200,16,16,"SD Card OK "); LCD_ShowString(60,170,200,16,16,"SD Card Size: MB"); sd_size=SD_GetSectorCount();//得到扇區數 LCD_ShowNum(164,170,sd_size>>11,5,16);//顯示SD卡容量(MB) while(1) { key=KEY_Scan(0); if(key==KEY_RIGHT)//KEY0按下了 { buf=mymalloc(0,512); //在內部?jì)却娉?,申?12字節內存 if(SD_ReadDisk(buf,0,1)==0) //讀取0扇區的內容 { LCD_ShowString(60,190,200,16,16,"USART1 Sending Data..."); printf("SECTOR 0 DATA:"); for(sd_size=0;sd_size<512;sd_size++)printf("%x ",buf[sd_size]);
//打印0扇區數據 printf("DATA ENDED"); LCD_ShowString(60,190,200,16,16,"USART1 Send Data Over!"); } myfree(0,buf); //釋放內存 } t++; delay_ms(10); if(t==20) { LED0=!LED0; t=0; } }
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
關(guān)鍵詞:
STM32SD卡驅
相關(guān)推薦
技術(shù)專(zhuān)區
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線(xiàn)
- 開(kāi)關(guān)電源
- 單片機
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開(kāi)發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機控制
- 藍牙
- PLC
- PWM
- 汽車(chē)電子
- 轉換器
- 電源管理
- 信號放大器
評論