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

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

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

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2012年01月08日   【字體:
#include<reg52.h>

#include<intrins.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í)需要降低

//通信速度,所以通過(guò)該標(biāo)志來(lái)寫(xiě)1來(lái)降低速度

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

{

    while(x--)

    _nop_();

}

void delay1(uint a)     

{

    uint i,j;

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

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

}

//寫(xiě)一字節(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)  //用來(lái)判斷是否處于初始化,如果是降低通信速度

        delay(10);

        _nop_();   //用來(lái)讓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)楦唠娖?
    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卡寫(xiě)命令//

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));

    //判斷命令是否寫(xiě)入成功,當(dāng)讀取到so不為0xff時(shí)命令寫(xiě)入成功

    //當(dāng)temp==0xff時(shí)為真且沒(méi)發(fā)送100次為真繼續(xù)執(zhí)行

    //但是又不能無(wú)限制等待所以讓命令寫(xiě)入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ù)位時(shí)最少寫(xiě)入74個(gè)時(shí)鐘周期

    {

        write_sd(0xff);

    }  

    cs=0;

    time=0;//打開(kāi)片選

    do

    {

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

        time++;

        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;

}

//寫(xiě)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卡操作一次性只能寫(xiě)一個(gè)扇區(qū)也就是512個(gè)字節(jié)

    //所以這里通過(guò)將長(zhǎng)整型地址左移九位來(lái)將地址乘上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);       //寫(xiě)入寫(xiě)扇區(qū)命令

        time++;

        if(time==100)

        {

            return(write_error);

        }

    }

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

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

    {

        write_sd(0xff);

    }

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

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

    {

        write_sd(buffer[i]);

    }

    write_sd(0xff);  

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

 

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

    if((temp&0x1f)!=0x05)        //如果返回值是 xxx00101 說(shuō)明數(shù)據(jù)已經(jīng)被寫(xiě)入

    {

        cs=1;

        return(write_error);

    }

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

    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=add<<9;

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

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

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

    cs=0;                          //打開(kāi)片選

    do

    {

        temp=write_cmd(table);       //寫(xiě)命令

        time++;

        if(time==100)

        {

            return read_error;

        }

    }

    while(temp!=0);

    write_sd(0xff);               //補(bǔ)償8個(gè)時(shí)鐘

    while(read_sd()!=0xfe);      //一直讀取等待0xfe

    for(i=0;i<512;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ā)光二極管用來(lái)顯示讀取到的數(shù)據(jù)

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

寫(xiě)入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ù)組里面寫(xiě)入數(shù)據(jù)

    }

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

    {

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

    }

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

    {

        shuju[i]=0;           //清零數(shù)據(jù)數(shù)組用來(lái)存儲(chǔ)從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)文章

主站蜘蛛池模板: 久久精品在线播放 | 日韩精品成人一区二区三区视频 | 免费av观看 | 亚洲免费在线 | 美女毛片免费看 | 精品久久国产 | 自拍在线 | 在线91 | 亚洲欧美综合精品另类天天更新 | 成人永久免费视频 | 亚洲品质自拍视频网站 | 欧美影院久久 | 超碰最新在线 | 99久久久国产精品 | 亚洲av一级毛片 | 国产精品福利视频 | 黑人巨大精品欧美黑白配亚洲 | 婷婷激情综合 | 99久久精品国产一区二区三区 | 男女羞羞网站 | 国产精品毛片 | 成人高潮片免费视频欧美 | 岛国视频 | 97人人澡人人爽91综合色 | 免费在线日韩 | 一区二区三区电影在线观看 | 免费黄视频网站 | 无毛av| 日韩欧美在线视频 | 国产精品久久视频 | www97影院 | 久久com| 国产精品国产三级国产aⅴ中文 | 国产精品久久久久久久久免费高清 | 国产女人第一次做爰毛片 | 日韩视频在线免费观看 | 亚洲综合小视频 | 亚洲成人激情在线观看 | 狠狠的操 | 日韩视频在线一区二区 | 免费黄色的视频 |