简介
花了很长时间才得到读写存储卡(大多数教程都很完整,但不容易理解)。我希望我的代码经验能对你有所帮助
0的运行分析与实施。整个过程
1,存储卡
2加电后的初始化,如何读写
和实现
1。上电后存储卡初始化向MicroSD卡发送至少74个时钟信号
,发送CDM0 (x041)复位
发送CMD1,使MicroSD卡进入spi模式
2。如何读写
您需要知道的是如何执行SPI通信来完成上述任务
3。下面是具体的过程//首先看看我们的函数
char SD _ Init(void);//初始化函数
charwritesectordomiccross(long addr,char * buff);//写一个扇区512位
charreadsectionfrom cross(长扇区,char *缓冲区);//读取扇区
以下是主函数中的部分//定义读取缓冲区
外部字符微数据缓冲区[512];
void microsd test()
{
//这是初始化存储卡后的读写测试。如果不成功,从读写序列号
//writesectionomicross(2,“你好,我找到我了!!!”);
delay _ ms(200);
ReadSectorfromMicroSD(2,MicroDDatAbuff);
//printf(" MicroSoft读取的是:%s!!!!\n\n ",MicrosdatAbuff);
}
int main()
{
char arr[100]= { 0 },键=-1;
int x=0,y = 0;
SPI 2 _ Init();
UART _ init(115200);
delay _ init();
SD _ Init();
微米测试();
printf(“已读:%s”,MicrosdatAbuff);
while(1);
}
//以下是MicroSD
#定义MicroSD _ CS _ setgpio _ set bits(GPIO b,GPIO _ Pin _ 0)
#定义MicroSD _ CS _ RESET GPIO _ RESET Bits(GPIOB,GPIO _ Pin _ 0)
char MicrosdatAbuff[512]= { 0 }的初始化和读写功能。//一个扇区的大小是
charsentcomandomomicross(char cmd,intdata,char CRC)
{
charresult = 0,times = 0;
微米标准_ CS _ SET//禁止SD卡选择同步时钟
SPI 1 _ read write byte(0x ff);
MicroSD _ CS _ RESET;//开始传输
SPI 1 _读写字节(cmd);
for(乘以= 0;时间<。4 .times ++)
{
SPI 1 _ ReadWriteByte((数据> 0。>;24)和。0x ff);
数据& lt<。= 8;
}
SPI1 _读写字节(CRC);
SPI 1 _读写字节(0x ff);//八个时钟
次= 0;
do{ //读取后8位
result = SPI 1 _ read write byte(0x ff);
次++;
}
while((结果= = 0x ff)amp;&(《泰晤士报》。200));
返回结果;
}
//初始化不太稳定,这意味着传输的数据可能不太稳定
charsd _ init(void)
{
chari,temp = 0;
//char CMD[] = {0x40,0x00,0x00,0x00,0x 95 };
int retry = 0;
GPIO _ InitTypeDef GPIO _ InitStructure;
RCC _ APB2PeriochLockCmd(RCC _ APB2Perioh _ GPIOB,启用);//PORTB时钟使能
gpio _ initstructure . gpio _ pin = gpio _ pin _ 0;
GPIO_InitStructure。GPIO _模式= GPIO _模式_输出_工艺程序;//PB0
GPIO _ InitStructure。GPIO _速度= GPIO _速度_ 50兆赫;
GPIO _ Init(GPIOB & amp;GPIO _ InitStructure);//初始化gpio b 0
gpio _ set bit(gpio b,gpio _ pin _ 0);
//初始化SPI 1
SPI 1 _ Init();
微标准_ CS _ SET
//发送至少74个时钟信号。填写
for(I = 0;i<。0x2f。i++) { SPI1 _读写字节(0x ff);}
//为了成功写入CMD0,在此写入
DO
{
Temp = Sentcommandomicross(0x 40,0,0x95) 200次;
retry++;
if(重试>。800)
{ //超过200倍
//CMD0错误!返回(INIT _ CMD 0 _ ERROR);
printf(“初始化MicroSD CMD0错误!!!后退:%d\n\n ",temp);
返回0;
}
}
while(temp!= 0x 01);//响应01h,停止写入
printf(“成功重置microsd!!!次数:%d\n\n ",重试);
//向SD卡发送cmd 1
重试= 0;
do{
//为了成功写入CMD1,写入
temp = sentcomandomomicross(0x 41,0,0xff) 100次;
retry++;
if(重试>。800)
{
//超过100倍
printf(“init 1 microsd cmd 1错误!!!后退:%d\n\n ",temp);
返回0;
}
}
while(temp!= 0x 00);//响应00h停止写入
微米_ CS _ SET//无效的切片选择
printf(“init micro SD sentcmd 1!!!次数:%d\n\n ",重试);
//取代更快的SPI速率
SPI1 _ setspeed (SPI _波特率预分频器_ 4);
返回0;
}
char WriteSectortomCrosd(长地址,char * buff)
{
int tmp,重试;
无符号int I;
addr = addr <。<。9;//addr = addr * 512
//写命令24到SD卡
重试= 0;
do{ //为获得可靠的写入,写入
tmp = sentcomanddomicross(0x 58,addr,0xff) 100次;
retry++;
if(重试>。800)
{
printf(“写CMD58错误!!!\ n \ r ");
7年1月;//发送命令出错!
}
}
while(tmp!= 0);在写入
for(I = 0;i<。100;i++)
{
SPI 1 _读写字节(0x ff);
}
//写开始字节
SPI 1 _ read write byte(0x Fe);
// 512字节现在可以写入
for(I = 0;i<。512;i++)
{
SPI 1 _读写字节(*缓冲);
buff++;
}
//crc-Byte spi模式仅需要发送前两个命令,并且下面的crc自动不检查
SPI1 _读写字节(0xFF);//伪循环冗余校验
SPI 1 _读写字节(0xFF);//循环冗余码
tmp = SPI1 _读写字节(0x ff);//读取响应
if((tmp & amp;0x1F)!=0x05) //不接受写入的512字节
{
microsd _ cs _ set;
printf(“MicroSD不接受写入数据\ n \ r”);
7年1月;//错误!
}
//等待直到SD卡不忙
//因为在数据被接受后,SD卡正在将数据
(SPI1 _ READ WRITE BYTE(0xFF))编程到存储阵列中!= 0x ff);
//禁止写SD卡。
微米标准_ CS _ SET
返回0;
}
char ReadSector FromMicroSD(长扇区,char *缓冲区)
{
int重试;
//命令16
int次= 0;
//无符号字符CMD[] = {0x51,0x00,0x00,0x00,0x ff };
无符号字符温度;
//从逻辑块地址到字节地址的地址转换
扇区=扇区< & lt9;//扇区=扇区* 512
//写命令16到SD卡
重试= 0;
do{ //确保写命令总共被写100次
temp = sentcomanddomicross(0x 51,扇区,0x ff);
retry++;
if(重试>。800)
{
printf(“从MicroSD读取扇区失败!!\ n \ r ");
7年1月;//块写入错误!
}
}
while(temp!= 0);
//从MMC/SD卡中读取起始字节(FeH/起始字节)
//现在数据准备好了,您可以将其读出。
while(SPI1 _读写字节(0xff)!= 0x Fe);
for(乘以= 0;时间<。512;times++)
{
MicroSDDataBuff[时间]= SPI1 _读写字节(0x ff);禁止
}
// SD卡读取完成
Microsd _ CS _ SET;
返回0;如果我使用stm32f103c8t6的核心板,
}
驱动器MicroSD卡可能会更好。互联网上的信息有点混乱。如果你想要具体的keil项目,请留下你的联系信息,我会发给你。
另外,下面的项目将在这里使用MicroSD驱动程序,然后建立一个文件系统,所以这里仍然是关键,还有一些深坑要挖。