📄 sd.c
字号:
{
SPI_MasterTransmit(p[i]);
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
擦除某页将缓存数据写进该页函数 操作码0x83 0x86
格式:操作码+3字节地址码(2无效位+12页地址+10无效位)
结束标志:CS管脚置高 注意该函数调用以后需要一定时间将数据写入芯片,要延时40ms,此时可向另一buffer写
但在8脚封装芯片上没有RDY/BUSY管脚(指示内部操作完成),但可以用软件方法检测状态
-----------------------------------------------------------*/
void Buffer_to_Main_erase (unsigned int pageaddr,unsigned char buffer)
{ // pageaddr 为页地址,buffer为buffer选择,1为buffer1,同理
unsigned long j;
j= (((unsigned long)pageaddr)<<10)&0x3ffc00 ;
SD_CS_PIN=0;
if (buffer == 1)
SPI_MasterTransmit(0x83);//操作码
else
SPI_MasterTransmit(0x86);//操作码
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
将缓存数据写进该页函数 操作码0x88 0x89
格式:操作码+3字节地址码(2无效位+12页地址+10无效位)
结束标志:CS管脚置高 注意该函数调用之前需要对操作页面进行擦除操作以后需要一定
时间将数据写入芯片,要延时6ms 即本函数要配合擦除函数
-----------------------------------------------------------*/
void Buffer_to_Main (unsigned int pageaddr,unsigned char buffer)
{ // pageaddr 为页地址,buffer为buffer选择,1为buffer1,同理
unsigned long j;
j= (((unsigned long)pageaddr)<<10)&0x3ffc00;
SD_CS_PIN=0;
if (buffer == 1)
SPI_MasterTransmit(0x88);//操作码
else
SPI_MasterTransmit(0x89);//操作码
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
页擦除函数 操作码0x81
格式:操作码+3字节地址码(2无效位+12页地址+10无效位)
结束标志:CS管脚置高 延时35ms
-----------------------------------------------------------*/
void Page_Erase (unsigned int pageaddr)
{ // pageaddr 为页地址
unsigned long j;
j= (((unsigned long)pageaddr)<<10)&0x3ffc00;
SD_CS_PIN=0;
SPI_MasterTransmit(0x81);//操作码
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
扇区擦除函数 每扇区 操作码0x7C
格式:操作码+3字节地址码(3无效位+9扇区地址+12无效位(适于0a、0b扇区1~15是4扇区地址+17无效位))
结束标志:CS管脚置高 延时5s
-----------------------------------------------------------*/
void Sector_Erase (unsigned int Sector,unsigned char Sector0)
{ // Sector 为扇区地址 Sector0为0扇区a,b部分选择
SD_CS_PIN=0;
SPI_MasterTransmit(0x7c);//操作码
if (Sector>0)
{
SPI_MasterTransmit((unsigned char)(Sector<<1)&0x1e);//地址
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
}
else
{
SPI_MasterTransmit(0x00);//地址
SPI_MasterTransmit((unsigned char)(Sector0<<4)&0x10);
SPI_MasterTransmit(0x00);
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
块擦除函数 每块8页 操作码0x50
格式:操作码+3字节地址码(3无效位+9块地址+12无效位)
结束标志:CS管脚置高 延时100ms
-----------------------------------------------------------*/
void Block_Erase (unsigned int blockaddr)
{ // blockaddr 为块地址
SD_CS_PIN=0;
SPI_MasterTransmit(0x50);//操作码
SPI_MasterTransmit((unsigned char)(blockaddr>>4));//地址
SPI_MasterTransmit((unsigned char)(blockaddr<<4)&0xf0);
SPI_MasterTransmit(0x00);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
全盘擦除函数 每扇区 操作码0xC7、94、80、9A
结束标志:CS管脚置高 延时ns
-----------------------------------------------------------*/
void Chip_Erase (void)
{ // Sector 为扇区地址
SD_CS_PIN=0;
SPI_MasterTransmit(0xc7);//操作码
SPI_MasterTransmit(0x94);
SPI_MasterTransmit(0x80);
SPI_MasterTransmit(0x9a);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
带缓存写页函数 操作码0x82 0x85
格式:操作码+3字节地址码(12页址+10页内地址(528byte))
结束标志:CS管脚置高 要延时40ms
-----------------------------------------------------------*/
void Page_Through_Buffer (unsigned char *p,unsigned int pageaddr,unsigned int byteaddr,unsigned char buffer)
{ // pageaddr 为页地址,byteaddr为从页中那个字节开始写,buffer为buffer选择,1为buffer1,同理
unsigned int i;
unsigned long j;
j= ((((unsigned long)pageaddr)<<10)&0x3ffc00)|(((unsigned long)byteaddr)&0x3ff);
SD_CS_PIN=0;
if (buffer == 1)
SPI_MasterTransmit(0x82);//操作码
else
SPI_MasterTransmit(0x85);//操作码
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
for (i=0;i<528;i++)
{
SPI_MasterTransmit(p[i]);
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
页数据读入缓存函数 操作码0x53 0x55
格式:操作码+3字节地址码(12页址+10页内地址(528byte))
结束标志:CS管脚置高 要延时400us
-----------------------------------------------------------*/
void Page_to_Buffer (unsigned int pageaddr,unsigned char buffer)
{ // pageaddr 为页地址,buffer为buffer选择,1为buffer1,同理
unsigned long j;
j= (((unsigned long)pageaddr)<<10)&0x3ffc00;
SD_CS_PIN=0;
if (buffer == 1)
SPI_MasterTransmit(0x53);//操作码
else
SPI_MasterTransmit(0x55);//操作码
SPI_MasterTransmit((unsigned char)(j>>16));//地址
SPI_MasterTransmit((unsigned char)(j>> 8));
SPI_MasterTransmit((unsigned char) j);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
软件写保护 操作码0x3D、2A、7F、A9
结束标志:CS管脚置高 延时18s
-----------------------------------------------------------*/
void Enable_Sector_Protection (void)
{
SD_CS_PIN=0;
SPI_MasterTransmit(0x3d);//操作码
SPI_MasterTransmit(0x2a);
SPI_MasterTransmit(0x7f);
SPI_MasterTransmit(0xa9);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
解除软件写保护 操作码0x3D、2A、7F、9A
结束标志:CS管脚置高 延时ns
-----------------------------------------------------------*/
void Disenable_Sector_Protection (void)
{
SD_CS_PIN=0;
SPI_MasterTransmit(0x3d);//操作码
SPI_MasterTransmit(0x2a);
SPI_MasterTransmit(0x7f);
SPI_MasterTransmit(0x9a);
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
/*-----------------------------------------------------------
读取厂商和设备信息 操作码:0x9F
格式:操作码
返回:0x1F (ATMEL) ID信息(2字节) 0x00
-----------------------------------------------------------*/
void ManufacturerDevice_read (unsigned char *p)
{
unsigned int i;
SD_CS_PIN=0;
SPI_MasterTransmit(0x9f);
for (i=0;i<4;i++)
{
p[i] = SPI_MasterReceive();
}
SD_CS_PIN=1;
while(!(Status_Register_Read ()&0x80));//检测忙状态确保内部时序完成
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -