📄 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 + -