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

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

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

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間: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; //定義主機發(fā)送數(shù)據(jù)位

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

uchar xdata shuju[512]={0};     //定義數(shù)據(jù)緩沖數(shù)組

uchar flag_time;         

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

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

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

{

    while(x--)

    _nop_();

}

void delay1(uint a)     

{

    uint i,j;

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

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

}

//寫一字節(jié)數(shù)據(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口數(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)楦唠娖?
    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++)  //發(fā)送六字節(jié)命令

    {

        write_sd(cmd[i]);

    }

    time=0;

    do

    {  

        temp=read_sd();

        time++;

    }

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

    //判斷命令是否寫入成功,當(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;i<0x0f;i++)      //復(fù)位時最少寫入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的響應(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=add<<9;       //add=add*512

    //由于sd卡操作一次性只能寫一個扇區(qū)也就是512個字節(jié)

    //所以這里通過將長整型地址左移九位來將地址乘上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);       //寫入寫扇區(qū)命令

        time++;

        if(time==100)

        {

            return(write_error);

        }

    }

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

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

    {

        write_sd(0xff);

    }

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

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

    {

        write_sd(buffer[i]);

    }

    write_sd(0xff);  

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

 

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

    if((temp&0x1f)!=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=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);           //兩字節(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;i<512;i++)

    {

        shuju[i]=i;           //向數(shù)據(jù)數(shù)組里面寫入數(shù)據(jù)

    }

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

    {

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

    }

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

    {

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

    }         

    duqushanqu(1,shuju);     //讀取扇區(qū)數(shù)據(jù)

    while(1)

    {

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

        {

            P0=shuju[i];      //顯示扇區(qū)數(shù)據(jù)

            delay1(200);

        }

    }

}
關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 国产精品一区二区欧美 | 久久精品国产久精国产 | 国产精品美女久久久久久久网站 | 亚洲精品综合一区二区 | 91视频在线看 | 9色网站 | 午夜精品一区二区三区在线观看 | 一区二区高清 | 秋霞电影一区二区 | 日本激情视频网 | 国产精品视频免费观看 | 国产精品成人一区二区三区 | 久久久久黑人 | 成年人在线观看视频 | 日韩性在线 | 99精品国产一区二区三区 | 国产高清一区二区三区 | 久久综合av | 欧美精品一区二区在线观看 | 欧美黄色片在线观看 | 91精品国产麻豆 | 国产精品成av人在线视午夜片 | 日韩精品一区二区三区中文在线 | 成人在线免费av | 九九免费视频 | 国产精品一区二区视频 | 亚洲在线日韩 | 国产亚洲成av人片在线观看桃 | 国产精品亚洲精品日韩已方 | 久久久久久亚洲精品 | av中文在线播放 | 久久久91精品国产一区二区三区 | 亚洲一区二区免费看 | 精品日韩 | 韩国久久 | 国产精品久久久久久福利一牛影视 | japan21xxxxhd美女 日本欧美国产在线 | 黄色网址在线免费观看 | www.日韩高清 | 91久久精品一区二区二区 | 欧美日在线 |