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

📄 sd.c~

📁 ATmega16读写SD卡程序
💻 C~
字号:
#include "SD.h"
#include <spi.h> 
#include <delay.h>
void SPI_Init()
{
    DDRB.4=1;  //SS
    DDRB.5=1;  //MOSI
    DDRB.6=0;  //MISO
    DDRB.7=1;  //SCK 
    
    SD_CS=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;
    SD_CS=1;		   			/* 片选无效 */
  	spi(0XFF);				/* 发送8个时钟 */
  	SD_CS=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 + -