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

📄 sd.i

📁 ATmega16读写SD卡程序
💻 I
字号:
// CodeVisionAVR C Compiler
// (C) 1998-2001 Pavel Haiduc, HP InfoTech S.R.L.

// I/O registers definitions for the ATmega16


#pragma used+
sfrb TWBR=0;
sfrb TWSR=1;
sfrb TWAR=2;
sfrb TWDR=3;
sfrb ADCL=4;
sfrb ADCH=5;
sfrw ADCW=4;      // 16 bit access
sfrb ADCSRA=6;
sfrb ADMUX=7;
sfrb ACSR=8;
sfrb UBRRL=9;
sfrb UCSRB=0xa;
sfrb UCSRA=0xb;
sfrb UDR=0xc;
sfrb SPCR=0xd;
sfrb SPSR=0xe;
sfrb SPDR=0xf;
sfrb PIND=0x10;
sfrb DDRD=0x11;
sfrb PORTD=0x12;
sfrb PINC=0x13;
sfrb DDRC=0x14;
sfrb PORTC=0x15;
sfrb PINB=0x16;
sfrb DDRB=0x17;
sfrb PORTB=0x18;
sfrb PINA=0x19;
sfrb DDRA=0x1a;
sfrb PORTA=0x1b;
sfrb EECR=0x1c;
sfrb EEDR=0x1d;
sfrb EEARL=0x1e;
sfrb EEARH=0x1f;
sfrw EEAR=0x1e;   // 16 bit access
sfrb UBRRH=0x20;
sfrb UCSRC=0X20;
sfrb WDTCR=0x21;
sfrb ASSR=0x22;
sfrb OCR2=0x23;
sfrb TCNT2=0x24;
sfrb TCCR2=0x25;
sfrb ICR1L=0x26;
sfrb ICR1H=0x27;
sfrb OCR1BL=0x28;
sfrb OCR1BH=0x29;
sfrw OCR1B=0x28;  // 16 bit access
sfrb OCR1AL=0x2a;
sfrb OCR1AH=0x2b;
sfrw OCR1A=0x2a;  // 16 bit access
sfrb TCNT1L=0x2c;
sfrb TCNT1H=0x2d;
sfrw TCNT1=0x2c;  // 16 bit access
sfrb TCCR1B=0x2e;
sfrb TCCR1A=0x2f;
sfrb SFIOR=0x30;
sfrb OSCCAL=0x31;
sfrb OCDR=0x31;
sfrb TCNT0=0x32;
sfrb TCCR0=0x33;
sfrb MCUCSR=0x34;
sfrb MCUCR=0x35;
sfrb TWCR=0x36;
sfrb SPMCR=0x37;
sfrb TIFR=0x38;
sfrb TIMSK=0x39;
sfrb GIFR=0x3a;
sfrb GICR=0x3b;
sfrb OCR0=0X3c;
sfrb SPL=0x3d;
sfrb SPH=0x3e;
sfrb SREG=0x3f;
#pragma used-

// Interrupt vectors definitions


// Needed by the power management functions (sleep.h)
#asm
	#ifndef __SLEEP_DEFINED__
	#define __SLEEP_DEFINED__
	.EQU __se_bit=0x40
	.EQU __sm_mask=0xB0
	.EQU __sm_powerdown=0x20
	.EQU __sm_powersave=0x30
	.EQU __sm_standby=0xA0
	.EQU __sm_ext_standby=0xB0
	.EQU __sm_adc_noise_red=0x10
	.SET power_ctrl_reg=mcucr
	#endif
#endasm


void SPI_Init();
unsigned char SD_Write_Command(unsigned char *cmd);
unsigned char SD_Init(void);
unsigned char SD_Read_Block(unsigned long address,unsigned char *pbuf);
unsigned char SD_Write_Block(unsigned long address,unsigned char *pbuf);
/*
  CodeVisionAVR C Compiler
  (C) 1998-2004 Pavel Haiduc, HP InfoTech S.R.L.

  Prototype for SPI access function */
  

#pragma used+
unsigned char spi(unsigned char data);
#pragma used-

#pragma library spi.lib

// CodeVisionAVR C Compiler
// (C) 1998-2000 Pavel Haiduc, HP InfoTech S.R.L.


#pragma used+

void delay_us(unsigned int n);
void delay_ms(unsigned int n);

#pragma used-

void SPI_Init()
{
    DDRB.4=1;  //SS
    DDRB.5=1;  //MOSI
    DDRB.6=0;  //MISO
    DDRB.7=1;  //SCK 
    
    PORTB.4   =1;
    // SPI initialization
    // SPI Type: Master
    // SPI Clock Rate: 115.200 kHz
    // SPI Clock Phase: Cycle Half
    // SPI Clock Polarity: Low
    // SPI Data Order: MSB First
    SPCR=0x52;
    SPSR=0x00;
} 
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//****************************************************************************
unsigned char SD_Write_Command(unsigned char *cmd)
{
    unsigned char i=0,k=0;
	  unsigned char temp=0XFF;
    PORTB.4   =1;		   			/* 片选无效 */
  	spi(0XFF);				/* 发送8个时钟 */
  	PORTB.4   =0;		   			/* 片选有效 */

  	for(i=0; i<6; i++)
  	{
  	    spi(*(cmd++));		/* 发送命令 */   
  	}
  	while(temp==0XFF)
  	{
  	    temp = spi(0XFF);  /* 等待回复 */
  		  if(k++>200)             /* 超时返回 */
  		  {
  		      return temp;
  		  }
    }
    return temp;
}
//****************************************************************************
//SD卡初始化(SPI-MODE)
//****************************************************************************
unsigned char SD_Init(void)
{ 
    unsigned int timeout;
	  unsigned char i=0;
    unsigned char cmd[]={0x40,0x00,0x00,0x00,0x00,0x95};  
	  delay_ms(500);
	/* 发送一定数量的时钟脉冲 */
    for(i=0;i<0x10;i++) 
    {
        spi(0XFF);
    }
	/* 发送CMD0 */
	  if(SD_Write_Command(cmd)!=0X01)
	      return 0;
	/* 发送CMD1 */
	  cmd[0]=0X41;
	  cmd[5]=0XFF;
	  while(SD_Write_Command(cmd)!=0X00)
	  {
	      if(timeout++>0XFFFE)     /* 等待初始化完成 */
            return 0;            /* 容量大的MMC卡需要用比较长时间 */
	  }
	  SPSR=0x01;   				 /*  提高MCU SPI速度 */
    return 1;
} 
//****************************************************************************
//从SD卡读一个扇区 
//long address --SD卡地址
//*P--存储缓冲
//Return 0 if no Error.
//****************************************************************************
unsigned char SD_Read_Block(unsigned long address,unsigned char *pbuf)
{ 
    unsigned int i;

    unsigned char cmd[]={0x40,0x00,0x00,0x00,0x00,0xff};  
    cmd[0]=0X40+17;			 /* READ SINGLE BLOCK */
	  address=address<<9;         /* address*512,取512的整数倍 */
	  cmd[1]=(address>>24);
	  cmd[2]=(address>>16);
	  cmd[3]=(address>>8);
	  cmd[4]=(address>>0);
	  if(SD_Write_Command(cmd)!=0X00)     /* 发送CMD17 */
	      return 0;               /* 读取失败 */
    while(spi(0XFF)!=0XFE)
	  {
	     #asm("nop");			 /* 等待数据接受开始,受到0XFE表示开始 */
	  }
	  for(i=0;i<512;i++)          /* 读取数据 */
	  {
	     pbuf[i]=spi(0XFF);
	  }
	 spi(0XFF);			 /* 取走CRC字节 */
	 spi(0XFF);
	 return 1; 
}
//***************************************************************************
//SD卡写一个扇区 
//long address --SD卡地址
//*P--存储缓冲
// Return 0 if no Error.
//***************************************************************************
unsigned char SD_Write_Block(unsigned long address,unsigned char *pbuf)
{
    unsigned int i;
    unsigned char temp;
    unsigned char cmd[]={0x40,0x00,0x00,0x00,0x00,0xff};  
	  cmd[0]=0x40+24;              /* WRITE SINGLE BLOCK */
	  address=address<<9;          /* address*512,取512的整数倍 */
	  cmd[1]=(address>>24);
	  cmd[2]=(address>>16);
	  cmd[3]=(address>>8);
	  cmd[4]=(address>>0);
	  if(SD_Write_Command(cmd)!=0X00)     /* 发送CMD24 */
	      return 0;               /* 写入失败 */
	  spi(0XFF);             /* 发送填冲字节 */
	  spi(0XFE);             /* 发送数据开始标志0XFE */
	  for(i=0;i<512;i++)          /* 写入数据 */
	  {
	     spi(pbuf[i]);
	  }
	  spi(0XFF);			 /* 写入CRC字节 */
	  spi(0XFF);
	  temp=spi(0XFF);		 /* 读取XXX0 0101字节 */
	  temp=temp&0X1F;
	  if(temp!=0X05)
	      return 0; 				 /* 写入失败 */
	  while(spi(0XFF)==0X00)
	  {
	     #asm("nop");			 /* BUSY等待 */
	  }
	  return 1;
}

⌨️ 快捷键说明

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