新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 自編基于51單片機的sD卡程序

自編基于51單片機的sD卡程序

作者: 時間:2012-08-10 來源:網(wǎng)絡(luò) 收藏
#includereg52.h>#includeintrins.h>#define uint unsigned int#define uchar unsigned char//錯誤碼定義//#define cmd0_error 0x01#define cmd1_error 0x02#define write_error 0x03#define read_error 0x04/*位定義*/sbit so=P1^0; //定義主機接收位sbit clk=P1^1;    //定義時鐘位sbit si=P1^2; //定義主機發(fā)送數(shù)據(jù)位sbit cs=P1^3; //定義片選位uchar xdata shuju[512]={0};     //定義數(shù)據(jù)緩沖數(shù)組uchar flag_time;         //定義標(biāo)志時間,因為當(dāng)sd卡進(jìn)行時需要降低//通信速度,所以通過該標(biāo)志來寫1來降低速度void delay(uint x)       //通信延時函數(shù){while(x--)_nop_();}void delay1(uint a)     {uint i,j;for(i=0;ia;i++)for(j=0;j120;j++);}//寫一字節(jié)數(shù)據(jù)//void write_sd(uchar date)  {uchar i;CY=0;clk=1;for(i=0;i8;i++){clk=0;date=date1;si=CY;if(flag_time==1)  //用來判斷是否處于,如果是降低通信速度delay(10);_nop_();   //用來讓io口數(shù)據(jù)更穩(wěn)定,也可以省略clk=1;_nop_();if(flag_time==1)delay(10);}}//讀取sd卡一個字節(jié)數(shù)據(jù)//uchar read_sd()      {uchar i,temp=0;so=1;          //一定要先將其置1否則會出現(xiàn)錯誤//因為如果先置0單片機io口寄存器相應(yīng)位電平為低當(dāng)//當(dāng)接收到高電平后可能sd卡電平不足使其io變?yōu)楦唠娖絚lk=1;for(i=0;i8;i++){clk=0;if(flag_time==1)delay(10);temp=1;temp=temp|so;_nop_();clk=1;_nop_();if(flag_time==1)delay(10);}return temp;}//向sd卡寫命令//uchar write_cmd(uchar *cmd){uchar i,time,temp;  si=1;for(i=0;i6;i++)  //發(fā)送六字節(jié)命令{write_sd(cmd[i]);}time=0;do{  temp=read_sd();time++;}while((temp==0xff)(time100));//判斷命令是否寫入成功,當(dāng)讀取到so不為0xff時命令寫入成功//當(dāng)temp==0xff時為真且沒發(fā)送100次為真繼續(xù)執(zhí)行//但是又不能無限制等待所以讓命令寫入100次結(jié)束return temp;      //返回讀取的數(shù)據(jù)}//復(fù)位函數(shù)//uchar sd_reset(){uchar i,temp=0xff,time;uchar table[]={0x40,0x00,0x00,0x00,0x00,0x95};flag_time=1;cs=1;for(i=0;i0x0f;i++)      //復(fù)位時最少寫入74個時鐘周期{write_sd(0xff);}  cs=0;time=0;//打開片選do{temp=write_cmd(table);   //寫入cmd0time++;if(time==100)return(cmd0_error);}while(temp!=0x01);       //等待命令CMD0的響應(yīng)cs=1;                  //關(guān)閉片選write_sd(0xff);           //補償8個時鐘return 0;}//函數(shù)此函數(shù)決定SD卡的工作模式 選擇SPI還是SD模式//uchar sd_init(){uchar time=0,temp=0xff;uchar table[]={0x41,0x00,0x00,0x00,0x00,0xff};       //命令碼flag_time=1;cs=0;time=0;do{temp=write_cmd(table);time++;if(time==100)return 0x02;}while(temp!=0x00);       //等待命令CMD1響應(yīng)flag_time=0;cs=1;write_sd(0xff);           //補償8個時鐘return 0;}//寫sd卡扇區(qū)//uchar xie_sd_shanqu(unsigned long int add,uchar *buffer){uchar temp,time;uint i;uchar table[]={0x58,0x00,0x00,0x00,0x00,0xff};add=add9;       //add=add*512//由于sd卡操作一次性只能寫一個扇區(qū)也就是512個字節(jié)//所以這里通過將長整型地址左移九位來將地址乘上512//用于地址操作table[1]=((add0xff000000)>>24);table[2]=((add0x00ff0000)>>16);table[3]=((add0x0000ff00)>>8);cs=0;time=0;do{temp=write_cmd(table);       //寫入寫扇區(qū)命令time++;if(time==100){return(write_error);}}while(temp!=0x00);               //判斷命令是否寫入成功成功時返回0x00for(i=0;i20;i++)     //補充若干時鐘{write_sd(0xff);}write_sd(0xfe);       //寫入開始字節(jié)0xfe,后面要寫入512字節(jié)數(shù)據(jù)for(i=0;i512;i++){write_sd(buffer[i]);}write_sd(0xff);  write_sd(0xff);           //兩字節(jié)奇偶校驗temp=read_sd();           //讀取返回值if((temp0x1f)!=0x05)        //如果返回值是 xxx00101 說明數(shù)據(jù)已經(jīng)被寫入{cs=1;return(write_error);}while(read_sd()!=0xff);          //等待sd卡不忙 數(shù)據(jù)寫入成功cs=1;                  //關(guān)閉片選write_sd(0xff);           //補償8 個時鐘return 0;}//讀取sd卡扇區(qū)//uchar duqushanqu(unsigned long add,uchar *buffer){uchar temp,time=0;uint i;uchar  table[]={0x51,0x00,0x00,0x00,0x00,0xff};add=add9;table[1]=((add0xff000000)>>24);table[2]=((add0x00ff0000)>>16);table[3]=((add0x0000ff00)>>8);cs=0;                          //打開片選do{temp=write_cmd(table);       //寫命令time++;if(time==100){return read_error;}}while(temp!=0);write_sd(0xff);               //補償8個時鐘while(read_sd()!=0xfe);      //一直讀取等待0xfefor(i=0;i512;i++){buffer[i]=read_sd();}write_sd(0xff);           //兩字節(jié)奇偶校驗位write_sd(0xff);cs=1;write_sd(0xff);           //補償8個時鐘return 0;}/*在P0上接八個發(fā)光二極管用來顯示讀取到的數(shù)據(jù)首先在數(shù)組(shuju)里面放入i用于顯示,再將其寫入SD卡扇區(qū),然后在讀取出SD卡里的數(shù)據(jù)*/void main(){uint i=0;P2=0x00;P0=0xff;sd_reset();  sd_init();     ///初始化sd卡for(i=0;i512;i++){shuju[i]=i;           //向數(shù)據(jù)數(shù)組里面寫入數(shù)據(jù)}for(i=0;i512;i++){xie_sd_shanqu(1,shuju);      //將數(shù)據(jù)數(shù)組里面的數(shù)據(jù)寫入sd卡}for(i=0;i2;i++){shuju[i]=0;           //清零數(shù)據(jù)數(shù)組用來存儲從sd卡讀取到的數(shù)據(jù)}         duqushanqu(1,shuju);     //讀取扇區(qū)數(shù)據(jù)while(1){for(i=0;i512;i++){P0=shuju[i];      //顯示扇區(qū)數(shù)據(jù)delay1(200);}}}


關(guān)鍵詞: 51單片機 sD卡程序 初始化

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉