久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

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

作者:佚名   來源:本站原創   點擊數:  更新時間:2012年01月08日   【字體:
#include<reg52.h>

#include<intrins.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; //定義主機發送數據位

sbit cs=P1^3; //定義片選位

uchar xdata shuju[512]={0};     //定義數據緩沖數組

uchar flag_time;         

//定義標志時間,因為當sd卡進行初始化時需要降低

//通信速度,所以通過該標志來寫1來降低速度

void delay(uint x)       //通信延時函數

{

    while(x--)

    _nop_();

}

void delay1(uint a)     

{

    uint i,j;

    for(i=0;i<a;i++)

        for(j=0;j<120;j++);

}

//寫一字節數據//

void write_sd(uchar date)  

{

    uchar i;

    CY=0;

    clk=1;

    for(i=0;i<8;i++)

    {

        clk=0;

        date=date<<1;

        si=CY;

        if(flag_time==1)  //用來判斷是否處于初始化,如果是降低通信速度

        delay(10);

        _nop_();   //用來讓io口數據更穩定,也可以省略

        clk=1;

        _nop_();

        if(flag_time==1)

        delay(10);

    }

}

//讀取sd卡一個字節數據//

uchar read_sd()      

{

    uchar i,temp=0;

    so=1;          //一定要先將其置1否則會出現錯誤

    //因為如果先置0單片機io口寄存器相應位電平為低當

    //當接收到高電平后可能sd卡電平不足使其io變為高電平

    clk=1;

    for(i=0;i<8;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;i<6;i++)  //發送六字節命令

    {

        write_sd(cmd[i]);

    }

    time=0;

    do

    {  

        temp=read_sd();

        time++;

    }

    while((temp==0xff)&&(time<100));

    //判斷命令是否寫入成功,當讀取到so不為0xff時命令寫入成功

    //當temp==0xff時為真且沒發送100次為真繼續執行

    //但是又不能無限制等待所以讓命令寫入100次結束

    return temp;      //返回讀取的數據

}

//復位函數//

uchar sd_reset()

{

    uchar i,temp=0xff,time;

    uchar table[]={0x40,0x00,0x00,0x00,0x00,0x95};

    flag_time=1;

    cs=1;

    for(i=0;i<0x0f;i++)      //復位時最少寫入74個時鐘周期

    {

        write_sd(0xff);

    }  

    cs=0;

    time=0;//打開片選

    do

    {

        temp=write_cmd(table);   //寫入cmd0

        time++;

        if(time==100)

        return(cmd0_error);

    }

    while(temp!=0x01);       //等待命令CMD0的響應

    cs=1;                  //關閉片選

    write_sd(0xff);           //補償8個時鐘

    return 0;

}

//初始化函數此函數決定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響應

    flag_time=0;

    cs=1;

    write_sd(0xff);           //補償8個時鐘

    return 0;

}

//寫sd卡扇區//

uchar xie_sd_shanqu(unsigned long int add,uchar *buffer)

{

    uchar temp,time;

    uint i;

    uchar table[]={0x58,0x00,0x00,0x00,0x00,0xff};

    add=add<<9;       //add=add*512

    //由于sd卡操作一次性只能寫一個扇區也就是512個字節

    //所以這里通過將長整型地址左移九位來將地址乘上512

    //用于地址操作

    table[1]=((add&0xff000000)>>24);

    table[2]=((add&0x00ff0000)>>16);

    table[3]=((add&0x0000ff00)>>8);

    cs=0;

    time=0;

    do

    {

        temp=write_cmd(table);       //寫入寫扇區命令

        time++;

        if(time==100)

        {

            return(write_error);

        }

    }

    while(temp!=0x00);               //判斷命令是否寫入成功成功時返回0x00

    for(i=0;i<20;i++)     //補充若干時鐘

    {

        write_sd(0xff);

    }

    write_sd(0xfe);       //寫入開始字節0xfe,后面要寫入512字節數據

    for(i=0;i<512;i++)

    {

        write_sd(buffer[i]);

    }

    write_sd(0xff);  

    write_sd(0xff);           //兩字節奇偶校驗

 

    temp=read_sd();           //讀取返回值

    if((temp&0x1f)!=0x05)        //如果返回值是 xxx00101 說明數據已經被寫入

    {

        cs=1;

        return(write_error);

    }

    while(read_sd()!=0xff);          //等待sd卡不忙 數據寫入成功

    cs=1;                  //關閉片選

    write_sd(0xff);           //補償8 個時鐘

    return 0;

}

//讀取sd卡扇區//

uchar duqushanqu(unsigned long add,uchar *buffer)

{

    uchar temp,time=0;

    uint i;

    uchar  table[]={0x51,0x00,0x00,0x00,0x00,0xff};

    add=add<<9;

    table[1]=((add&0xff000000)>>24);

    table[2]=((add&0x00ff0000)>>16);

    table[3]=((add&0x0000ff00)>>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);      //一直讀取等待0xfe

    for(i=0;i<512;i++)

    {

        buffer[i]=read_sd();

    }

    write_sd(0xff);           //兩字節奇偶校驗位

    write_sd(0xff);

    cs=1;

    write_sd(0xff);           //補償8個時鐘

    return 0;

}

/*在P0上接八個發光二極管用來顯示讀取到的數據

首先在數組(shuju)里面放入i用于顯示,再將其

寫入SD卡扇區,然后在讀取出SD卡里的數據*/

void main()

{

    uint i=0;

    P2=0x00;

    P0=0xff;

    sd_reset();  

    sd_init();     ///初始化sd卡

    for(i=0;i<512;i++)

    {

        shuju[i]=i;           //向數據數組里面寫入數據

    }

    for(i=0;i<512;i++)

    {

        xie_sd_shanqu(1,shuju);      //將數據數組里面的數據寫入sd卡

    }

    for(i=0;i<2;i++)

    {

        shuju[i]=0;           //清零數據數組用來存儲從sd卡讀取到的數據

    }         

    duqushanqu(1,shuju);     //讀取扇區數據

    while(1)

    {

        for(i=0;i<512;i++)

        {

            P0=shuju[i];      //顯示扇區數據

            delay1(200);

        }

    }

}
關閉窗口

相關文章

主站蜘蛛池模板: 福利色导航 | 欧美一级欧美三级在线观看 | 免费网站国产 | 毛片免费视频 | 国产精品久久毛片av大全日韩 | www.youjizz.com日韩| 欧美日韩视频在线播放 | 欧美精品久久久久久久久久 | 久久久亚洲一区 | 久久国产三级 | 精品久久久久久久久久久久久久久久久 | 性高湖久久久久久久久aaaaa | 久久精品亚洲一区二区三区浴池 | 亚洲高清视频在线观看 | 国产精品爱久久久久久久 | 一级毛片色一级 | 亚洲手机在线 | 亚洲欧美另类在线观看 | 激情六月丁香 | 日本免费视频在线观看 | 久久免费观看视频 | 狠狠干美女 | 欧美区精品 | 国产精品国产精品国产专区不蜜 | 精品一区国产 | 中文字幕视频免费 | 日韩中文一区二区三区 | 国产99视频精品免视看9 | 欧美日韩亚洲国产综合 | 国产亚洲二区 | 国产精品免费播放 | 久久久久中文字幕 | 亚洲精品美女视频 | 国产日韩一区二区三区 | 国产成人免费视频网站高清观看视频 | 日本又色又爽又黄又高潮 | 国产传媒在线观看 | 6080亚洲精品一区二区 | 美女福利网站 | 国产精品精品视频一区二区三区 | 在线不卡av |