在对Micro SD卡的读写过程中,我发现我只能对SD卡一个扇区的前256字节进行读写,小于256字节时读写正常,大于256字节在写入时会变成规律重复的一段数据,且在后256字节的数据无法读出。
该SD卡为某宝5元1张的2G普通SD卡,文件系统现格式化为FAT16(该卡默认),在电脑上正常使用。
读取用的单片机为STC89C52RC
写入512字节0x77
写入300字节0xA5
大家看看这是什么原因?
主要代码如下(不是我写的,但我看了下对比了其他人写的感觉也没啥问题啊)
#include "public.h"
#include "SD.h"
#include "port.h"
//定义512字节数据缓冲区
u8 xdata BUFFER_DATA[1024]={0};
//使用位操作加快SPI读写速度
u8 bdata Byte_data;
sbit Byte_data7=Byte_data^7;
sbit Byte_data6=Byte_data^6;
sbit Byte_data5=Byte_data^5;
sbit Byte_data4=Byte_data^4;
sbit Byte_data3=Byte_data^3;
sbit Byte_data2=Byte_data^2;
sbit Byte_data1=Byte_data^1;
sbit Byte_data0=Byte_data^0;
//SPI写入一个字节(字节数据)
void SPI_write_Byte(u8 Byte)
{
SPI_MOSI=1;
Byte_data=Byte;
SPI_CLK=0;SPI_MOSI=Byte_data7;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data6;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data5;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data4;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data3;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data2;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data1;SPI_CLK=1;
SPI_CLK=0;SPI_MOSI=Byte_data0;SPI_CLK=1;
SPI_MOSI=1;
}
//SPI读取一个字节(返回值为数据)
u8 SPI_read_Byte()
{
SPI_MISO=1;
SPI_CLK=0;Byte_data7=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data6=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data5=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data4=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data3=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data2=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data1=SPI_MISO;SPI_CLK=1;
SPI_CLK=0;Byte_data0=SPI_MISO;SPI_CLK=1;
SPI_MISO=1;
return Byte_data;
}
//检测SD卡的响应
u8 SD_response()
{
u8 i;
u8 response;
for(i=0;i<9;++i)
{
response=SPI_read_Byte();
if((response==0x00)||(response==0x01)) break;
}
return response;
}
//MCU向SD卡写入命令
void MCU_write_SD_command(u8 command,u32 argument,u8 CRC)
{
SPI_write_Byte(command|0x40);
SPI_write_Byte(((u8 *)&argument)[0]);
SPI_write_Byte(((u8 *)&argument)[1]);
SPI_write_Byte(((u8 *)&argument)[2]);
SPI_write_Byte(((u8 *)&argument)[3]);
SPI_write_Byte(CRC);
}
//SD卡初始化
u8 SD_init()
{
u8 i;
u8 response=0x01;
SD_CS=1;
for(i=0;i<10;++i) SPI_write_Byte(0xFF);
SD_CS=0;
MCU_write_SD_command(0x00,0x00000000,0x95);//发送命令0将MMC置于SPI模式
response=SD_response();
if(response!=0x01) return 0;
while(response)
{
SD_CS=1;
SPI_write_Byte(0xFF);
SD_CS=0;
MCU_write_SD_command(0x01,0x00FFC000,0xFF);
response=SD_response();
}
SD_CS=1;
SPI_write_Byte(0xFF);
return 1;
}
//MCU向SD卡写入数据,一次最多512字节(扇区,数据长度(最大为512,建议填512))
u8 MCU_write_SD_512Byte(u32 block,u16 data_length)
{
u16 i;
u8 *block_data_pointer;//扇区数据指针
u8 dataResp;
block_data_pointer=BUFFER_DATA;//指针指向缓冲数据
SD_CS=0;
MCU_write_SD_command(0x18,512*block,0xFF);//发送写入命令
if(!SD_response())
{
SPI_write_Byte(0xFF);
SPI_write_Byte(0xFF);
SPI_write_Byte(0xFF);
//命令成功-现在MCU向SD卡写入数据
SPI_write_Byte(0xFE);//数据将在发送0xFE后开始写入
//现在MCU向SD卡写入数据
for(i=0;i<data_length;++i)
{
SPI_write_Byte(*block_data_pointer);
++block_data_pointer;
}
for(;i<512;++i) SPI_write_Byte(0x00);
//数据块发送-现在发送校验和
SPI_write_Byte(0xFF);//两字节CRC校验,为0XFFFF,不考虑CRC
SPI_write_Byte(0xFF);
dataResp=SPI_read_Byte();//现在读取数据响应
//在数据响应之后是一个繁忙的字节数,一个零字节表示MMC忙
while(!SPI_read_Byte());
dataResp=dataResp&0x0F; //屏蔽数据响应令牌的高字节
SD_CS=1;
SPI_write_Byte(0xFF);
if(dataResp==0x0B) return 0;//数据不被CARD接受
if(dataResp==0x05) return 1;//无效的数据响应
return 0;
}
//写入命令0x18没有被MMC接收
return 0;
}
//MCU向SD卡读取数据,一次最多512字节(扇区,数据长度(最大为512,建议填512))
u8 MCU_read_SD_512Byte(u32 block,u16 data_length)
{
u16 i;
u8 *block_data_pointer;//扇区数据指针
block_data_pointer=BUFFER_DATA;//指针指向缓冲数据
SD_CS=0;
MCU_write_SD_command(0x11,512*block,0xFF);//然后发送写命令
if(!SD_response())
{
while(SPI_read_Byte()!=0xFE);//发送命令成功,现在发送数据,数据在接收0xFE之后
for(i=0;i<data_length;++i)
{
*block_data_pointer=SPI_read_Byte();
++block_data_pointer;
}
for(;i<512;++i) SPI_read_Byte();
//数据块发送-现在发送校验和
SPI_read_Byte();
SPI_read_Byte();
//现在读入数据响应
SD_CS=1;
SPI_read_Byte();
return 1;
}
//读命令0x11没有被MMC的接收
return 0;
}