打印

大家帮我看看SPI的SD卡初始化。

[复制链接]
2721|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kyzb001|  楼主 | 2010-11-20 11:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kyzb001 于 2010-11-20 11:55 编辑

#include <stdio.h>
#include "NUC1xx.h"
#include "DrvSPI.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "DrvUART.h"
static void pfnSDCARD_Delay(uint32_t nCount)
{
         uint32_t i;
         for(i=nCount;i>0;i--)
                   __NOP();
}

void UARTSPI_INIT()
{
       STR_UART_T sParam;
       UNLOCKREG();
       /* Set UART Pin */
       DrvGPIO_InitFunction(E_FUNC_UART0);
       /* UART Setting */
       sParam.u32BaudRate   = 115200;
       sParam.u8cDataBits   = DRVUART_DATABITS_8;
       sParam.u8cStopBits   = DRVUART_STOPBITS_1;
       sParam.u8cParity   = DRVUART_PARITY_NONE;
       sParam.u8cRxTriggerLevel= DRVUART_FIFO_1BYTES;
       DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0);
       DrvUART_Open(UART_PORT0,&sParam);

       DrvSYS_SetOscCtrl(E_SYS_XTL12M,1);
       SYSCLK->CLKSEL0.HCLK_S=0;
       SYSCLK->CLKDIV.HCLK_N=0;
       if(DrvSPI_Open(eDRVSPI_PORT0,eDRVSPI_MASTER,eDRVSPI_TYPE1,32,FALSE)==E_SUCCESS)
                   printf("\nOpen SPI0 is Success.\n");

       DrvSYS_SetIPClock(E_SYS_SPI0_CLK,1);//设置时钟
       DrvGPIO_InitFunction(E_FUNC_SPI0); // enable SPI funztion and pin
   
       DrvSPI_Open(eDRVSPI_PORT0,eDRVSPI_MASTER,eDRVSPI_TYPE1,8,FALSE);//打开SPI0
       DrvSPI_DisableAutoSS(eDRVSPI_PORT0); //关闭自动片选
       DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT0, eDRVSPI_ACTIVE_LOW_FALLING);//设置模式
       DrvSPI_SetEndian(eDRVSPI_PORT0, eDRVSPI_MSB_FIRST);   //MSB传输
       DrvSPI_SetClockFreq(eDRVSPI_PORT0,300000,300000); //设确定时钟
       pfnSDCARD_Delay(0x20000);  //延时
   
       //DrvSPI_SetClockFreq(eDRVSPI_PORT0,12000000,12000000);
}
uint32_t SPI_WriteByte(uint32_t val)
{
       uint32_t auSendSPIData[2];
       uint32_t auReadSPIData[2];
       auSendSPIData[0]=val;
       auSendSPIData[1]=val;

       if(DrvSPI_BurstWrite(eDRVSPI_PORT0,&auSendSPIData[0])==FALSE)
              printf("\n\nWrite Data is fail\n\n");
       while(DrvSPI_IsBusy(eDRVSPI_PORT0));
       DrvSPI_DumpRxRegister(eDRVSPI_PORT0,&auReadSPIData[0],1);
      
       return auReadSPIData[0];
}
int32_t SD_SendCommand(uint32_t cmd,uint32_t arg)
{
       int32_t R1 = 0;
       int32_t Retry   = 0;

       DrvSPI_ClrSS(eDRVSPI_PORT0,eDRVSPI_SS0);

       DrvSPI_SetBitLength(eDRVSPI_PORT0,8);
       SPI_WriteByte(cmd|0x40);   //分别写入命令

       DrvSPI_SetBitLength(eDRVSPI_PORT0,24);
       SPI_WriteByte(arg);      //数据段第4字节
      
       DrvSPI_SetBitLength(eDRVSPI_PORT0,16);
       SPI_WriteByte(arg);      //数据段第3字节
       DrvSPI_SetBitLength(eDRVSPI_PORT0,8);
       SPI_WriteByte(arg);       //数据段第2字节
       SPI_WriteByte(arg);          //数据段第1字节
       if(cmd==0)
               SPI_WriteByte(0x95);         //CRC效验和
       else
               SPI_WriteByte(0xff);
       R1=SPI_WriteByte(0xff);  
       while((R1=SPI_WriteByte(0xff))==0xffffffff)//等待响应
       {
                printf(" %d ",R1);
                if(Retry++ > 200)
                {
                printf("\n\nCommand Write is time out\n\n");
                          break;//超时退出
                }
       }
       printf("Command : 0x%x ",R1);  
       DrvSPI_SetSS(eDRVSPI_PORT0,eDRVSPI_SS0);
        return R1;
}
uint32_t SD_RESET()
{
        uint32_t  i;
        uint32_t  Retry;            //重复次数
        uint32_t  R1=0;              

        DrvSYS_Delay(10000);
        Retry=0;
        do
       {
              for(i=0;i<10;i++)
              SPI_WriteByte(0xff);  //发送74和命令周期
      
              R1 = SD_SendCommand(0,0);//发CMD0命令
              Retry++;
              if(Retry>20)
              {
                     printf("11 Time is out ");
                     return 1;   //超时退出
               }
         }while(R1 != 0x01);      //等待IDLE命令返回

/*      Retry = 0;                    
         DrvSPI_ClrSS(eDRVSPI_PORT0,eDRVSPI_SS0);
         do
         {
                  for(i=0;i<100;i++)
                  SPI_WriteByte(0xff);
                  R1 = SD_SendCommand(1, 0);         //发Active命令
                  Retry++;
                  if(Retry>254)
                 {
                         printf("22 Time is out ");
                         return 1;            //超时退出      
                 }
         }while(R1==0);
*/
         return 0;   
}
int32_t main()
{
           uint32_t R1=1;
           UARTSPI_INIT();
           SD_RESET();
           if(R1)
           {
                  printf("Init is Fail");  
            }
            else
           printf("Init is success");
           while(1){ }
}


[/code]要求一点都不高,发个0  能返回和0x01,SD卡进入SPI模式就行。关于NUC1xx的SPI真是一头雾水啊!

相关帖子

沙发
hotpower| | 2010-11-20 13:27 | 只看该作者
俺也想知道,没搭硬件。
华邦有自带的两个sd卡的例程,应该用它先调试,通过后再简化。

使用特权

评论回复
板凳
kyzb001|  楼主 | 2010-11-20 14:25 | 只看该作者
华邦的例子是SPI2的。100,64脚的只有2个SPI    所以我改成SPI0的。结果显示初始化不能完成。

使用特权

评论回复
地板
kyzb001|  楼主 | 2010-11-20 15:24 | 只看该作者
DSTATUS disk_initialize (
        BYTE drv                /* Physical drive nmuber */
)
{
        DSTATUS sta;
        GPIOD->PMD.PMD12=1;
        GPIOD->DOUT&=0xEFFF;

        while((GPIOD->PIN&0x2000)!=0);

这个是例子中  打开SDCARD之前的设置。   不理解啊

使用特权

评论回复
5
hotpower| | 2010-11-20 15:46 | 只看该作者
PD.12=0打开PMOS管给SD卡供电PD.13=0有SD卡插入,无卡死循环

使用特权

评论回复
6
hotpower| | 2010-11-20 16:31 | 只看该作者
如果只接了四线,可以屏蔽这些语句

使用特权

评论回复
7
kyzb001|  楼主 | 2010-11-21 09:03 | 只看该作者
早上调了10分钟波形没出,一看示波器没接地。:funk:

使用特权

评论回复
8
hotpower| | 2010-11-22 17:59 | 只看该作者
晕,好像片选反了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

624

帖子

1

粉丝