⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdopration.c

📁 SPI模式下
💻 C
字号:
/*--------------------------------------------------------*/

#include "AT91SAM7X256.h"
#include "Board.h"
#include "mytype.h"
#include "integer.h"
#include "function.h"    //用来声明各个外部函数
int error_flag=0;
int sdd_buf[512];
static uint8 spircvbyte;

void SSPI_Clk400k(void)
{	
	/* 设置SPI时钟为300k,小于400k */
        uint32 reg;
	reg = AT91C_BASE_SPI0->SPI_CSR[3];
	reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (DWORD) 0xa0<< 8 ); 
	AT91C_BASE_SPI0->SPI_CSR[3] = reg;        
}

/*--------------------------------------------------------*/

MMC_Disable()
{
  AT91C_BASE_PIOA->PIO_SODR=PIN_CS_CARD_NEI; 
}

MMC_Enable()
{
  AT91C_BASE_PIOA->PIO_CODR=PIN_CS_CARD_NEI;
}

Read_Byte_MMC()
{
  while( !( AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
  while( !( AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF ) )// wait for char
  spircvbyte=AT91C_BASE_SPI0->SPI_RDR;
  return (uint8)(spircvbyte);
}



 Write_Byte_MMC(uint8 DATA)
{
  while( !( AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
  AT91C_BASE_SPI0->SPI_TDR = (uint32)( DATA )+(unsigned int)(0x07<<16);
  //AT91C_BASE_SPI0->SPI_TDR = DATA;
  while( !( AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
  spircvbyte=AT91C_BASE_SPI0->SPI_RDR;    //读一字节
  return (uint8)spircvbyte;
}
  


 unsigned char Write_Command_MMC(unsigned char *CMD) { 
 uint8 temp1 = 0xff;
 //int retry2 = 0;
 //Write_Byte_MMC(0xff);
 //MMC_Disable();
// delays(1);
  for(int i = 0; i < 0x06; i++)
    {
     temp1=Write_Byte_MMC(*CMD++);
    }
  return temp1;
}

/*----------------------------------------------------------------*/
void InitSPI_Hard(void)
{
  AT91C_BASE_SPI0->SPI_CR=0x80; //复位SPI
  delays(20);
  AT91C_BASE_SPI0->SPI_MR=(AT91C_SPI_MSTR|AT91C_SPI_PS_VARIABLE|AT91C_SPI_MODFDIS|AT91C_SPI_DLYBCS);
  //AT91C_BASE_SPI0->SPI_MR=0x01070001;
  
  //AT91C_BASE_SPI0->SPI_CSR[0]=AT91C_SPI_CPOL+AT91C_SPI_BITS_8+((MCK/1000000)<<8);//buadrate=10M
  //AT91C_BASE_SPI0->SPI_CSR[1]=AT91C_SPI_CPOL+AT91C_SPI_BITS_8+((MCK/1000000)<<8);//buadrate=10M
  //AT91C_BASE_SPI0->SPI_CSR[2]=AT91C_SPI_CPOL+AT91C_SPI_BITS_8+((MCK/1000000)<<8);//buadrate=10M
  AT91C_BASE_SPI0->SPI_CSR[3]=AT91C_SPI_NCPHA+AT91C_SPI_BITS_8+((MCK/4000000)<<8);//buadrate=4M
  AT91C_BASE_PIOA->PIO_PDR=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK;    //分配给外设A					/* MOSI 引脚置低   set MOSI to zero */
  AT91C_BASE_PIOA->PIO_ASR=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK;
  AT91C_BASE_PIOA->PIO_PPUER=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK;
  SSPI_Clk400k();
  AT91C_BASE_SPI0->SPI_CR=0x01; //启动SPI
  delays(120);
 
}

/*------------------------------------------------------------------*/
void InitSPI_Soft(void)
{
  uint8 retry=0,temp=0xff;
  int wait=0;
  unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95}; 

  MMC_Disable(); 
  delays(20);  
  for(int i=0;i<15;i++)         //写74个高电平
   {
    Write_Byte_MMC(0xff); 
   }

  
  MMC_Enable();
  delays(20); 
  Write_Command_MMC(CMD);  //发送CMD0复位 
  for(int i=0;i<50;i++)   //等待响应
   {
    temp=Write_Byte_MMC(0xff);
    if(temp!=0xff) break;
   }
 //已经收到响应0x01
  
    Write_Byte_MMC(0xff); 
  
  CMD[0]=0x41;                   
  CMD[5]=0xff;    
  for(int j=0;j<100;j++)
  {
     Write_Command_MMC(CMD);  //发送CMD1击活SD
     for(int i=0;i<20;i++)   //等待响应
      {
       temp=Write_Byte_MMC(0xff);
       if(temp==0x00)
         {
          wait=1;
          //AT91C_BASE_PIOA->PIO_CODR=PIN_BACKLED_OE;
          break;
         }
      }
     if(wait==1)break;
  }
 //已经收到响应0x00
  MMC_Disable();
  return;
}
 

/*--------------------------------------------------*/ 
void InitSPI(void)
{
  InitSPI_Hard();
  InitSPI_Soft();
}

/*------------------------------------------------------*/
void SD_Restart(void)      //上电和引脚清0初始化
{ 
        AT91C_BASE_PMC->PMC_PCER=(AT91C_ID_SPI0<<2);  

	AT91C_BASE_PIOB->PIO_PER=PIN_SD1_PWR_CTRL;
	AT91C_BASE_PIOB->PIO_OER=PIN_SD1_PWR_CTRL;
	AT91C_BASE_PIOB->PIO_SODR=PIN_SD1_PWR_CTRL;	//断电
        
	AT91C_BASE_PIOA->PIO_PER=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK|PIN_CS_CARD_NEI;   //SCK,MOSI,MISO,CS置0
	AT91C_BASE_PIOA->PIO_OER=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK|PIN_CS_CARD_NEI;
	AT91C_BASE_PIOA->PIO_CODR=PIN_SPI0_MISO|PIN_SPI0_MOSI|PIN_SPI0_SCK|PIN_CS_CARD_NEI;	 
        delays(40);
        AT91C_BASE_PIOB->PIO_CODR=PIN_SD1_PWR_CTRL;    //上电
}


/*----------------------------------------------------*/ 

//***************************************************
void SD_read_block_toOLED(unsigned long addr,unsigned char Buffer) 
{
        int response=0;
        int tempp=0xff;
        int retryy = 0;
  	unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xff};
	addr = addr << 9; //addr = addr * 512
	CMD[1] = ((addr & 0xFF000000) >>24 );
	CMD[2] = ((addr & 0x00FF0000) >>16 );
	CMD[3] = ((addr & 0x0000FF00) >>8 );
  MMC_Enable();  
  //delays(1);
  for(int j=0;j<80000;j++)
  {
     Write_Command_MMC(CMD);  //发送CMD17
     for(int i=0;i<20;i++)   //等待响应
      {
       tempp=Write_Byte_MMC(0xff);
       if(tempp==0xfe)
         {
          response=1;
          break;
         }
      }
     if(response==1)break;
  }

       for(int j=0;j<512;j++)
          {
           Buffer=Write_Byte_MMC(0xff);
           WriteOLEDData(Buffer>>2);
          }
        
       Write_Byte_MMC(0xff);
       Write_Byte_MMC(0xff);     
       MMC_Disable();
       return;
}      
 

//***************************************************       
ReadSD_Writeoled(uint8 x1,uint8 y1,uint8 width,uint8 hight)
{
  unsigned char Buffer_Data;
  unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xff};
  OLEDCsLow();
  WriteOLEDCmd(0x15);WriteOLEDData(x1);WriteOLEDData(x1+width-1);
  WriteOLEDCmd(0x75);WriteOLEDData(y1);WriteOLEDData(y1+hight-1);
  OLEDCsHigh();
  OLEDCsLow();
  WriteOLEDCmd(0x5c);
  Write_Command_MMC(CMD);
  
  for(int i=256;i<376;i++)
    {
     SD_read_block_toOLED(i,Buffer_Data);//每块512字节,共读取120块,61440字节
     }
 OLEDCsHigh();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -