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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > avr的SD卡基本讀寫程序(二)

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

          作者: 時(shí)間:2016-11-13 來源:網(wǎng)絡(luò) 收藏
          SD卡讀寫子程序

          硬件平臺(tái):atmega8L最小系統(tǒng)
          硬spi(sd卡的初始化采用了io口模擬時(shí)序,因?yàn)樵趯?shí)驗(yàn)中發(fā)現(xiàn)要使用較低的速率才能穩(wěn)定的初始化)
          軟件開發(fā)平臺(tái):ICC-AVR version 6.31a
          硬件配置:atmega8L 內(nèi)部8m時(shí)鐘
          sandisk 128m sd卡

          幾個(gè)基本的子程序及其介紹:

          1.io口模擬spi,實(shí)現(xiàn)數(shù)據(jù)發(fā)送,在初始化時(shí)使用
          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,實(shí)現(xiàn)數(shù)據(jù)讀取,在初始化時(shí)使用
          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.ex-cimer.com/article/201611/316551.htm


          3.io口模擬spi,實(shí)現(xiàn)指令發(fā)送及讀響應(yīng),在初始化時(shí)使用
          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讀數(shù)據(jù)
          unsigned char Read_Byte_SD(void)
          {
          char Byte;
          //SD_Enable();
          SPDR=0xff;
          while(!(SPSR&(1<Byte=SPDR;
          return(Byte);
          }

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

          6.硬spi寫指令及讀響應(yīng)
          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.設(shè)置每次讀的字節(jié)數(shù)
          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;
          /////////////////
          }



          關(guān)鍵詞: avrSD卡讀寫程

          評(píng)論


          技術(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); })();