|
分享一個51單片機做的SD卡讀卡器仿真帶源程序,一個簡單的MMC卡存儲器應用。下面是電路原理圖:
可以看到虛擬窗口的結果出來了.
單片機SD卡讀卡器設計的源程序如下:
- #include <AT89X52.H>
- #define F_OSC 11059200//晶振平率Hz
- #define F_BAUD 9600
- #define RELOAD 256-F_OSC/12/32/F_BAUD
- #define CR 0x0D //回車
- //定義SD卡需要的4根信號線
- sbit SD_CLK = P1^4;
- sbit SD_DI = P1^6;
- sbit SD_DO = P1^5;
- sbit SD_CS = P1^7;
- unsigned char xdata DATA[512];
- //定義512字節緩沖區,注意需要使用 xdata關鍵字
- //===========================================================
- //寫一字節到SD卡,模擬SPI總線方式
- void SdWrite(unsigned char n)
- {
- unsigned char i;
-
- for(i=8;i;i--)
- {
- SD_CLK=0;
- SD_DI=(n&0x80);
- n<<=1;
- SD_CLK=1;
- }
- SD_DI=1;
- }
- //===========================================================
- //從SD卡讀一字節,模擬SPI總線方式
- unsigned char SdRead()
- {
- unsigned char n,i;
- for(i=8;i;i--)
- {
- SD_CLK=0;
- SD_CLK=1;
- n<<=1;
- if(SD_DO) n|=1;
-
- }
- return n;
- }
- //============================================================
- //檢測SD卡的響應
- unsigned char SdResponse()
- {
- unsigned char i=0,response;
-
- while(i<=8)
- {
- response = SdRead();
- if(response==0x00)
- break;
- if(response==0x01)
- break;
- i++;
- }
- return response;
- }
- //================================================================
- //發命令到SD卡
- void SdCommand(unsigned char command, unsigned long argument, unsigned char CRC)
- {
- SdWrite(command|0x40);
- SdWrite(((unsigned char *)&argument)[0]);
- SdWrite(((unsigned char *)&argument)[1]);
- SdWrite(((unsigned char *)&argument)[2]);
- SdWrite(((unsigned char *)&argument)[3]);
- SdWrite(CRC);
- }
- //================================================================
- //初始化SD卡
- unsigned char SdInit(void)
- {
- int delay=0, trials=0;
- unsigned char i;
- unsigned char response=0x01;
-
- SD_CS=1;
- for(i=0;i<=9;i++)
- SdWrite(0xff);
- SD_CS=0;
-
- //Send Command 0 to put MMC in SPI mode
- SdCommand(0x00,0,0x95);
-
-
- response=SdResponse();
-
- if(response!=0x01)
- {
- return 0;
- }
- while(response==0x01)
- {
- SD_CS=1;
- SdWrite(0xff);
- SD_CS=0;
- SdCommand(0x01,0x00ffc000,0xff);
- response=SdResponse();
- }
- SD_CS=1;
- SdWrite(0xff);
- return 1;
- }
- //================================================================
- //往SD卡指定地址寫數據,一次最多512字節
- unsigned char SdWriteBlock(unsigned char *Block, unsigned long address,int len)
- {
- unsigned int count;
- unsigned char dataResp;
- //Block size is 512 bytes exactly
- //First Lower SS
-
- SD_CS=0;
- //Then send write command
- SdCommand(0x18,address,0xff);
-
- if(SdResponse()==00)
- {
- SdWrite(0xff);
- SdWrite(0xff);
- SdWrite(0xff);
- //command was a success - now send data
- //start with DATA TOKEN = 0xFE
- SdWrite(0xfe);
- //now send data
- for(count=0;count<len;count++) SdWrite(*Block++);
-
- for(;count<512;count++) SdWrite(0);
- //data block sent - now send checksum
- SdWrite(0xff); //兩字節CRC校驗, 為0XFFFF 表示不考慮CRC
- SdWrite(0xff);
- //Now read in the DATA RESPONSE token
- dataResp=SdRead();
- //Following the DATA RESPONSE token
- //are a number of BUSY bytes
- //a zero byte indicates the MMC is busy
-
- while(SdRead()==0);
-
- dataResp=dataResp&0x0f; //mask the high byte of the DATA RESPONSE token
- SD_CS=1;
- SdWrite(0xff);
- if(dataResp==0x0b)
- {
- //printf("DATA WAS NOT ACCEPTED BY CARD -- CRC ERROR\n");
- return 0;
- }
- if(dataResp==0x05)
- return 1;
-
- //printf("Invalid data Response token.\n");
- return 0;
- }
- //printf("Command 0x18 (Write) was not received by the MMC.\n");
- return 0;
- }
- //=======================================================================
- //從SD卡指定地址讀取數據,一次最多512字節
- unsigned char SdReadBlock(unsigned char *Block, unsigned long address,int len)
- {
- unsigned int count;
- //Block size is 512 bytes exactly
- //First Lower SS
-
- //printf("MMC_read_block\n");
-
- SD_CS=0;
- //Then send write command
- SdCommand(0x11,address,0xff);
- if(SdResponse()==00)
- {
- //command was a success - now send data
- //start with DATA TOKEN = 0xFE
- while(SdRead()!=0xfe);
-
- for(count=0;count<len;count++) *Block++=SdRead();
-
- for(;count<512;count++) SdRead();
-
- //data block sent - now send checksum
- SdRead();
- SdRead();
- //Now read in the DATA RESPONSE token
- SD_CS=1;
- SdRead();
- return 1;
- }
- //printf("Command 0x11 (Read) was not received by the MMC.\n");
- return 0;
- }
- /*******************************************
- 串口初始化
- *******************************************/
- void UART()
- {
- SCON=0x40;//工作與方式1不允許接受
- TMOD=0x20;//定時器1工作與方式2自動重裝模式
- TH1=RELOAD;
- TR1=1;
- TI=0;
- }
- //通過串口發送一個字符串
- void Sen_String(unsigned char *string)
- {
- while(*string!='\0')
- {
- if(*string=='\n')
- {
- SBUF=CR;
- }
- else
- {
- SBUF=*string;
- }
- while(TI==0);
- TI=0;
- string++;
- }
- }
- void main()
- {
- UART();
- while(!SdInit()); //等待SD卡初始化完成
- SdWriteBlock("THIS IS A TEST!",0x000000,15);//寫入字符串,然后讀出進行檢驗
- SdReadBlock(DATA,0x000000,15);
- Sen_String(DATA); //發出數據
- while(1)
- {
- }
- }
復制代碼
單片機SD卡讀卡器仿真工程文件及其他完整資料下載:
http://www.zg4o1577.cn/bbs/dpj-54940-1.html
|
|