原创 SD卡底层SPI操作源码+ZLG-SD源码包

2009-3-13 22:45 4403 4 6 分类: 通信

https://static.assets-stash.eet-china.com/album/old-resources/2009/3/13/87669dea-fc53-4cba-8d0d-e1fc25c795ff.rar


 


#include"lpc214x.h"
#include "head.h"         //定义一些数据结构


#define SD_Disable() IO0SET |= 1 << 20 //SD Chip Select Pin is P0.7
#define SD_Enable() IO0CLR |= 1 << 20


INT8U CMD[]={0x40, 0x00, 0x00, 0x00, 0x00, 0x95};



INT8U SPI_RW(INT8U data)
{
SSPDR = data;
while((SSPSR & 0x01) == 0);    
return(SSPDR);
}


void spi_init (void)
{


   INT32U i;


   /* SSEL is GPIO, output set to high. */
   IODIR0 |= 1<<20;
   IOSET0   = 1<<20;
   /* SCK1, MISO1, MOSI1 are SSP pins. */
   PINSEL1 = (PINSEL1 & ~0x000003FC) | 0x000000A8;


   /* Enable SPI in Master Mode, CPOL="1", CPHA="1" (Clock low-active). */
   SSPCR0 = 0x00C7;
   SSPCR1 = 0x0002;
   SSPCPSR = 0x7E;


   /* Send SPI Command with card not selected at 400 KBit. */
   for (i = 0; i < 16; i++) {
      SPI_RW (0xFF);
   }


   /* Enable SSP auto select. */
}




INT8U Write_Command_SD(INT8U *CMD)
{
    INT8U i = 0, response = 1, retry = 0;

    SD_Disable();
    SPI_RW(0xff);
    SD_Enable();
    for(i = 0; i < 0x06; i++)
    {
    SPI_RW(*CMD++);
    }
   
    SPI_RW(0xff);
   
    do
    {
    response = SPI_RW(0xff);
        retry++;
    }
    while((response== 0xff) && (retry < 100));
    return(response);
}



INT8U SD_write_sector(INT32U Number_Sector, INT8U* Buffer)
{
    INT8U response,response_1,retry;
    INT16U i;
    //Command 24 is a writing blocks command for SD/SD-Card.
    INT8U CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x02,0x00,0xFF};   //设定读取块大小
retry = 0;
SSPCPSR = 0x7E;
    do
    { //Retry 100 times to send command.
    response = Write_Command_SD(CMD_SET_BLOCKLEN);
       if(++retry >= 100)
        return(1); //block read Error!
    }
    while(response != 0);


SPI_RW(0XFF);
   
  
    Number_Sector <<= 9; //addr = addr * 512
        


    CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
    CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
    CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
    CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
    //Send Command CMD24 to SD/SD-Card (Write 1 Block/512 Bytes)
    retry = 0;
    do
    { //Retry 100 times to send command.
       response = Write_Command_SD(CMD);
       if(++retry >= 100)
       {
           return(1); //send commamd Error!
       }
    }
    while(response != 0);
   

//   for(i = 0; i < 20; i++)
       SPI_RW(0xff);
        
    //Send Start Byte to SD/SD-Card
    SPI_RW(0xfe);
  
    SSPCPSR = 0x04;   
    //Now send real data Bolck (512Bytes) to SD/SD-Card
    for(i = 0; i < 512; i++)
       SPI_RW(* Buffer++); //send 512 bytes to Card

    //CRC-Byte
    SPI_RW(0xFF); //Dummy CRC
    SPI_RW(0xFF); //CRC Code
//    retry="0";
   
do
{
    response="SPI"_RW(0xFF);//Read Response
}
while(response==0xff);

    do
{
      response_1=SPI_RW(0xFF);
}
while(response_1!=0xFF);
    SD_Disable();
SPI_RW(0xff);
    if ((response&0x1f)!=0x05) return(1);


    return(0);


}


INT8U SD_Read_Block(INT8U *CMD, INT8U *Buffer, INT16U Bytes)
{
    INT16U i;
    INT8U retry,response;
    INT16U Block_Len=0;
    INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x00,0x00,0xFF};
    SSPCPSR = 0x7E;
    if(Bytes != Block_Len)
    {
        CMD_SET_BLOCKLEN[3] = (INT8U)((Bytes & 0x0000FF00) >> 8 );
    CMD_SET_BLOCKLEN[4] = (INT8U)((Bytes & 0x000000FF) >> 0 );
   
    retry = 0;
    do
    { //Retry 100 times to send command.
       response = Write_Command_SD(CMD_SET_BLOCKLEN);
        if(++retry >= 100)
           return(1); //block read Error!
    }
    while(response != 0);
    Block_Len = Bytes;
    }
    //Send reads a block Command CMD to SD/SD-Card
    retry = 0;
    do
    {
    response = Write_Command_SD(CMD);
        if(++retry >= 100)
        return(1); //block read Error!
    }
    while(response != 0);
                        
    //Read Start Byte form SD/SD-Card (FEh/Start Byte)
//    while(SPI_RW(0xff) != 0xfe) ;
    retry="0";
    for(i=0;i<1000;i++)
{
     response="SPI"_RW(0xff);
   retry++;
   if(response==0xfe)
   i="1000";
   if(retry==1000)
   return(1);
}

SSPCPSR = 0x04;   
    //Write blocks(normal 512Bytes) to SD/SD-Card
    for(i = 0; i < Bytes; i++)
    *Buffer++ = SPI_RW(0xff);
   
    //CRC-Byte
    SPI_RW(0xff);//CRC - Byte
    SPI_RW(0xff);//CRC - Byte
        
    SD_Disable();
    return(0);
}



SD_INIT()
{
   INT8U retry, response;
   INT16U i;


   spi_init();
   SD_Enable();


   for(i=0;i<250;i++)
__asm
{
NOP
}
for(i = 0; i < 0x0f; i++)
{
SPI_RW(0xff);
}      
//Send Command CMD0 to SD/SD Card
retry = 0;
do
{ //retry 200 times to send CMD0 command
   
    response = Write_Command_SD(CMD);    //CMD0   响应为01
    retry++;
}
while((response != 1) && (retry < 200));


   retry="0";
   do
   {
        CMD[0]=0x77;
        CMD[5]=0x55;
        Write_Command_SD(CMD);                   //CMD55 响应为01
        CMD[0]=0X69;
        response="Write"_Command_SD(CMD);      //ACMD41   响应为00  
   retry++;
   }
   while((response!=0)&&(retry<200)) ;
// return(response);
}



void SD_WRITE(INT8U* Buffer,INT32U Number_Sector)
{
   INT8U retry, response;
   retry="0";
do
{
      response="SD"_write_sector(Number_Sector,Buffer);
   retry++;
   }
   while((response!=0x00)&&(retry<20)) ;
}


void SD_READ(INT8U *Buffer, INT16U Bytes,INT32U Number_Sector)
{
   INT8U response,retry;
   INT8U CMD[]={0X51,0X00,0X00,0X00,0X00,0XFF};
   Number_Sector=Number_Sector<<9;
   CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
   CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
   CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
   CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
   retry="0";
   do
   {
      response="SD"_Read_Block(CMD,Buffer,Bytes);
   retry++;
   }
   while((response!=0)&&(retry<100));
}

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户222464 2010-4-23 19:57

好东西,,谢谢分享。。

用户547952 2010-3-25 22:39

谢谢
相关推荐阅读
用户522854 2011-08-16 16:10
template c++
http://www.codeguru.com/forum/archive/index.php/t-333284.htmlhttp://www.codeguru.com/forum/archive/i...
用户522854 2011-07-06 20:55
Linux下的Source Insight+Ubuntu 10.04使用Wine安装Source I
Linux下的Source Insighthttp://rogerer.javaeye.com/blog/755346    在网上看到一朋友写了一篇推荐Linux下代码阅读工具Source ...
用户522854 2011-07-05 18:28
转]atoi、atof、_itoa、_itow 函数使用
http://www.cnblogs.com/heaad/archive/2009/08/10/1542511.htmlatoi、atof、itoa、itow函数是windows平台下实现字符串与数值...
用户522854 2011-07-05 18:25
【转】嵌入式经典面试题
嵌入式经典面试题(转)   C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息,此外,撇开面...
用户522854 2011-07-05 16:13
U-boot中TFTP 解释
http://www.cnblogs.com/heaad/archive/2009/08/10/1542538.html一、      概述      U-boot中的TFTP用于发送较小的文件。下层...
用户522854 2011-07-05 15:44
Linux驱动模块初始教程:一步一步,从helloworld到insmod->printk!!!
http://hi.baidu.com/ctgukuang/blog/item/5ee388924593c099a877a4ef.html【1】有必要查询下Linux内核# uname -r2.6.2...
EE直播间
更多
我要评论
2
4
关闭 站长推荐上一条 /3 下一条