<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          自編基于51單片機(jī)的sD卡程序

          作者: 時(shí)間:2012-08-10 來源:網(wǎng)絡(luò) 收藏
          #includereg52.h>#includeintrins.h>#define uint unsigned int#define uchar unsigned char//錯(cuò)誤碼定義//#define cmd0_error 0x01#define cmd1_error 0x02#define write_error 0x03#define read_error 0x04/*位定義*/sbit so=P1^0; //定義主機(jī)接收位sbit clk=P1^1;    //定義時(shí)鐘位sbit si=P1^2; //定義主機(jī)發(fā)送數(shù)據(jù)位sbit cs=P1^3; //定義片選位uchar xdata shuju[512]={0};     //定義數(shù)據(jù)緩沖數(shù)組uchar flag_time;         //定義標(biāo)志時(shí)間,因?yàn)楫?dāng)sd卡進(jìn)行時(shí)需要降低//通信速度,所以通過該標(biāo)志來寫1來降低速度void delay(uint x)       //通信延時(shí)函數(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卡一個(gè)字節(jié)數(shù)據(jù)//uchar read_sd()      {uchar i,temp=0;so=1;          //一定要先將其置1否則會(huì)出現(xiàn)錯(cuò)誤//因?yàn)槿绻戎?單片機(jī)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時(shí)命令寫入成功//當(dāng)temp==0xff時(shí)為真且沒發(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ù)位時(shí)最少寫入74個(gè)時(shí)鐘周期{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);           //補(bǔ)償8個(gè)時(shí)鐘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);           //補(bǔ)償8個(gè)時(shí)鐘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卡操作一次性只能寫一個(gè)扇區(qū)也就是512個(gè)字節(jié)//所以這里通過將長(zhǎng)整型地址左移九位來將地址乘上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);               //判斷命令是否寫入成功成功時(shí)返回0x00for(i=0;i20;i++)     //補(bǔ)充若干時(shí)鐘{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é)奇偶校驗(yàn)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);           //補(bǔ)償8 個(gè)時(shí)鐘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);               //補(bǔ)償8個(gè)時(shí)鐘while(read_sd()!=0xfe);      //一直讀取等待0xfefor(i=0;i512;i++){buffer[i]=read_sd();}write_sd(0xff);           //兩字節(jié)奇偶校驗(yàn)位write_sd(0xff);cs=1;write_sd(0xff);           //補(bǔ)償8個(gè)時(shí)鐘return 0;}/*在P0上接八個(gè)發(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ù)組用來存儲(chǔ)從sd卡讀取到的數(shù)據(jù)}         duqushanqu(1,shuju);     //讀取扇區(qū)數(shù)據(jù)while(1){for(i=0;i512;i++){P0=shuju[i];      //顯示扇區(qū)數(shù)據(jù)delay1(200);}}}


          評(píng)論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();