新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > avr的SD卡基本讀寫程序(二)

        avr的SD卡基本讀寫程序(二)

        作者: 時間:2016-11-13 來源:網絡 收藏
        SD卡讀寫子程序

        硬件平臺:atmega8L最小系統
        硬spi(sd卡的初始化采用了io口模擬時序,因為在實驗中發現要使用較低的速率才能穩定的初始化)
        軟件開發平臺:ICC-AVR version 6.31a
        硬件配置:atmega8L 內部8m時鐘
        sandisk 128m sd卡

        幾個基本的子程序及其介紹:

        1.io口模擬spi,實現數據發送,在初始化時使用
        void iodatatransfer(unsigned char iodata)
        {
        unsigned char num,b;
        num=0x80;
        for (b=0;b<0x08;b++)
        {
        WDR();//feed the dog
        //SD_Write|=(1< SD_Write&=~(1< if(iodata&num)
        SD_Write|=(1< else
        SD_Write&=~(1< delay_4ms();//4ms
        WDR();//feed the dog
        //SD_Write&=~(1< SD_Write|=(1< delay_4ms();//4ms
        if(num>0x01)
        num=num>>1;
        }
        }

        2.io口模擬spi,實現數據讀取,在初始化時使用
        unsigned char iodataread(void)
        {
        unsigned char data,temp,b;
        data=0;
        temp=0;
        for (b=0;b<0x08;b++)
        {
        WDR();//feed the dog
        SD_Write&=~(1<delay_4ms();//4ms
        WDR();//feed the dog

        SD_Write|=(1<temp=SD_READ;
        temp&=0x10;//to maintain the pb.4 bit(data_in)
        WDR();//feed the dog
        if(temp)
        {
        data|=0x01;
        }
        if(b<7)
        {
        data=data<<1;//
        }
        delay_4ms();//4ms
        WDR();//feed the dog
        }
        return data;
        }

        本文引用地址:http://www.104case.com/article/201611/316551.htm


        3.io口模擬spi,實現指令發送及讀響應,在初始化時使用
        unsigned char iocmd(unsigned char *cmd)
        {
        unsigned temp,a,timeout;
        temp=0xff;
        timeout=0;
        // Raise chip select -----/ss=1
        SD_Disable();
        WDR();//feed the dog

        // Send an 8 bit pulse
        iodatatransfer(0xff);
        WDR();//feed the dog
        // Lower chip select
        SD_Enable();
        for(a=0;a<6;a++)
        {
        iodatatransfer(*cmd++);
        WDR();
        //transfer cmd in io_mode
        }
        while(temp==0xff)//
        {
        WDR();//feed the dog
        temp=iodataread();
        if(timeout++>100)
        {
        break;
        }
        }
        WDR();//feed the dog
        return(temp);//the respone of the byte_write_operation
        }

        4.硬spi讀數據
        unsigned char Read_Byte_SD(void)
        {
        char Byte;
        //SD_Enable();
        SPDR=0xff;
        while(!(SPSR&(1<Byte=SPDR;
        return(Byte);
        }

        5.硬spi寫數據
        void Write_Byte_SD(char Byte)
        {
        //SD_Enable();
        SPDR=Byte;
        while(!(SPSR&(1<}

        6.硬spi寫指令及讀響應
        unsigned char Write_Command_SD(char *CMD)
        {
        unsigned char a;
        unsigned char tmp=0xff;
        unsigned char Timeout=0;
        // Raise chip select -----/ss=1
        SD_Disable();
        // Send an 8 bit pulse
        Write_Byte_SD(0xFF);

        // Lower chip select
        SD_Enable();
        //Send the 6 byte command
        for(a=0;a<0x06;a++)
        {
        Write_Byte_SD(*CMD++);
        }
        //Wait for the response
        while(tmp==0xff)//
        {
        tmp=Read_Byte_SD();
        if(Timeout++>100)
        {
        break;
        }
        }
        //for some reason we need to delay here
        //delay_1ms();
        return(tmp);//the respone of the byte_write_operation
        }

        7.初始化
        unsigned char SDInit(void)
        {
        unsigned char a,b,retry,erroetoken;
        unsigned char CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
        // Set certain pins to inputs and others to outputs
        // Only SPI_DI (data in) is an input
        //SD_Direction_REG==ddrb
        SD_Direction_REG&=~(1<SD_Direction_REG|=(1<SD_Direction_REG|=(1<SD_Direction_REG|=(1<//SD_Direction_REG|=(1<SD_Disable();
        //We need to wait for the SD_Direction_REG to be ready
        for(a=0;a<200;a++)
        {
        WDR();//feed the dog
        nop();
        nop();
        };
        delay_1ms();

        SD_Disable();//
        iodatatransfer(0xff);
        WDR();//feed the dog
        //return 0;///////////

        retry=0;
        SD_Enable();
        while((erroetoken=iocmd(CMD))!=0x01)//
        {
        WDR();
        //serial(erroetoken);
        if(retry++>200)
        { //fail and return
        return 1;
        }
        }
        //return 0;///////////

        //Send the 2nd command
        retry=0;
        CMD[0]=0x41;
        CMD[5]=0xFF;
        while(erroetoken=iocmd(CMD)!=0x00)
        {
        WDR();
        if (retry++>200)
        {
        return 2;
        }
        }

        //Set the SPI bus to full speed
        SPCR=0x50;
        SPSR|=0x01;
        //Raise Chip Select
        SD_Disable();
        return 0;
        }

        8.設置每次讀的字節數
        char SD_set_length(unsigned int length)
        {
        unsigned char retry;
        //Command to set the block length;
        char CMD[]={0x50,0x00,0x00,0x00,0x00,0xFF}; //cmd16

        CMD[3]=((length&0xFF00)>>8);//
        CMD[4]= (length&0x00FF);
        while(Write_Command_SD(CMD)!=0)//
        {
        WDR();
        if (retry++>200)
        {
        return 1;
        }
        }
        SD_Disable();
        return 0;
        }

        9.write 512 bytes to a given sector from a Byte_byte_long Buffer
        unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer,unsigned int Bytes)
        {
        unsigned int a;
        unsigned char retry,temp;
        //Command to read a block;
        char CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};//cmd24
        CMD[1]=((addr&0xFF000000)>>24);
        CMD[2]=((addr&0x00FF0000)>>16);
        CMD[3]=((addr&0x0000FF00)>>8);
        CMD[4]=(addr&0x000000FF);
        //Send the write command

        while(Write_Command_SD(CMD)!=0)
        {
        if (retry++>50)
        {
        return 1;
        }
        }
        //Send the start byte
        Write_Byte_SD(0xfe);
        //Read off all the bytes in the block
        for(a=0;a{
        Write_Byte_SD(*Buffer++);
        }
        while((temp=Read_Byte_SD())&0x10);
        //serial(temp);//according to p101 of datasheet
        if((temp&0x0f)!=0x05)
        return 2;
        //Read CRC byte
        while(SD_READ&0x10);//detect if data_in pb.4 is still busy(high)

        // Set SD_Chip_Select to high
        SD_Disable();
        //SEI(); //re-enable interrupts
        return 0;

        }

        unsigned char SD_read_sector(unsigned long addr,unsigned char *Buffer,unsigned int Bytes)
        {

        unsigned int a;
        unsigned char retry;
        //Command to read a block;
        char CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17
        //CLI(); //disable all interrupts
        //addr = addr << 9; //addr = addr * 512
        CMD[1]=((addr&0xFF000000)>>24);
        CMD[2]=((addr&0x00FF0000)>>16);
        CMD[3]=((addr&0x0000FF00)>>8);
        CMD[4]=(addr&0x000000FF);
        //Send the read command

        while(Write_Command_SD(CMD)!=0)
        {
        WDR();//feed the dog
        if (retry++>200)
        {
        return 1;
        }
        }
        //Send the start byte
        while(Read_Byte_SD()!=0xfe)
        {
        WDR();//feed the dog
        }
        //Read off all the bytes in the block
        for(a=0;a{
        WDR();//feed the dog
        *Buffer=Read_Byte_SD();
        //serial(*Buffer);
        Buffer++;
        }
        //Read CRC byte
        Read_Byte_SD();
        Read_Byte_SD();

        // Set SD_Chip_Select to high
        SD_Disable();
        //SEI(); //re-enable interrupts
        return 0;
        }
        /*
        //read xx bytes no matter of misalignment!!
        */
        unsigned char read_antimisaliment(unsigned long addr_temp,unsigned char *p_buffer, unsigned int length)
        {
        unsigned int _length=0x0000;
        SD_Enable();
        while(SD_read_sector(addr_temp,p_buffer,length))
        {
        SD_Enable();//
        length-=0x0001;//to find a suuitable length to avoid misalignment
        _length+=0x0001;// _length+length==xx
        SD_set_length(length);
        }
        ///
        if(_length==0x0000)
        {
        return 0;
        }
        ///
        addr_temp+=length;
        SD_Enable();//
        SD_set_length(_length);
        SD_Enable();//
        while(SD_read_sector(addr_temp,p_buffer,_length))
        {
        SD_Enable();
        }
        SD_Enable();//
        SD_set_length(length+_length);//to read the rest bytes of the xx bytes
        return 0;
        /////////////////
        }



        關鍵詞: avrSD卡讀寫程

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 自治县| 嘉黎县| 芒康县| 丰宁| 介休市| 榆中县| 天台县| 双桥区| 巨鹿县| 本溪市| 晋江市| 云浮市| 微山县| 博罗县| 沂水县| 长沙县| 湘乡市| 石门县| 荔浦县| 周宁县| 安吉县| 弋阳县| 沈丘县| 台安县| 静安区| 商水县| 全南县| 鄂托克旗| 石景山区| 秦安县| 泰宁县| 玛纳斯县| 山丹县| 武安市| 绵阳市| 壶关县| 连城县| 都昌县| 德兴市| 罗田县| 鹤壁市|