打印

NUC1xx的SD卡的读写(初始化)

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

#include <stdio.h>
#include "NUC1xx.h"
#include "DrvSPI.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "DrvUART.h"

void UARTSPI_INIT()
{
   STR_UART_T param;
   
/* Unlock the protected registers */
UNLOCKREG();
/* Enable the 12MHz oscillator oscillation */
DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);

/* Waiting for 12M Xtal stable */
DrvSYS_Delay(5000);

/* HCLK clock source. 0: external 12MHz; 7:internal 22MHz RC oscillator */
DrvSYS_SelectHCLKSource(0);
LOCKREG();
DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK clock source / (HCLK_N + 1) */
DrvGPIO_InitFunction(E_FUNC_UART0);

/* Select UART Clock Source From 12MHz */
DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0);

param.u32BaudRate        = 115200;
param.u8cDataBits        = DRVUART_DATABITS_8;
param.u8cStopBits        = DRVUART_STOPBITS_1;
param.u8cParity          = DRVUART_PARITY_NONE;
param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;
param.u8TimeOut          = 0;
DrvUART_Open(UART_PORT0, &param);

DrvSYS_SetIPClock(E_SYS_SPI0_CLK,1); //打开时钟
    DrvGPIO_InitFunction(E_FUNC_SPI0); // 使能 IO口的 SPI 功能  
   
     //CLKP = 0; 串行为空闲状态
     // TX_NEG = 1;  数据在串行时钟的负边沿传输
     // RX_NEG = 0;  数据在串行时钟的正边沿锁存
     //一次传输的长度为8为,设置为主模式
DrvSPI_Open(eDRVSPI_PORT0,eDRVSPI_MASTER,eDRVSPI_TYPE1,8, FALSE);
                 
DrvSPI_DisableAutoSS(eDRVSPI_PORT0); //关闭SPI0的自动CS功能
SPI0->SSR.SS_LVL = 0 ;// 选择信号的低电平触发输出
SPI0->CNTRL.LSB = 0;;//设置MSB传输
DrvSPI_SetClockFreq(eDRVSPI_PORT0,100000,100000); //设置频率
    DrvSYS_Delay(0x20000);     //延时
printf("\nOpen UART success\n");
}
uint32_t SPI_WriteByte(uint32_t val)
{
uint32_t auSendSPIData[2];
uint32_t auReadSPIData[2];
auSendSPIData[0]=val;
auSendSPIData[1]=val;

if(DrvSPI_SingleWrite(eDRVSPI_PORT0,&auSendSPIData[0])==FALSE)
  printf("\n\nWrite Data is fail\n\n");
while(DrvSPI_IsBusy(eDRVSPI_PORT0));
DrvSPI_DumpRxRegister(eDRVSPI_PORT0,auReadSPIData,1);
// printf("\n--- %x --- \n",auReadSPIData[0]);
return auReadSPIData[0];
}
uint32_t SD_SendCommand(uint8_t cmd,uint32_t arg,uint8_t crc)
{
uint32_t r1;
  uint32_t Retry=0;      //重复操作次数
DrvSPI_SetSS(eDRVSPI_PORT0, eDRVSPI_SS0);
SPI_WriteByte(0xff);  
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);

  DrvSPI_ClrSS(eDRVSPI_PORT0, eDRVSPI_SS0);                        //使能片选信号

  SPI_WriteByte(cmd | 0x40);   //分别写入命令
  SPI_WriteByte(arg>>24);      //数据段第4字节
  SPI_WriteByte(arg>>16);      //数据段第3字节
  SPI_WriteByte(arg>>8);       //数据段第2字节
  SPI_WriteByte(arg);          //数据段第1字节
  SPI_WriteByte(crc);         //CRC效验和

  while((r1 = SPI_WriteByte(0xff)) == 0xff)//等待响应
    if(Retry++ > 200)
     break;//超时退出     
     
  DrvSPI_SetSS(eDRVSPI_PORT0, eDRVSPI_SS0);                        //清除片选信号
SPI_WriteByte(0xff);
return r1;                   //返回状态值

}
void MMC_FLASH_Init()
{
uint32_t Counter = 0;
uint32_t r1=0;

for(Counter = 0 ; Counter < 0xf00; Counter++);//延时等待SD卡上电
for(Counter = 0 ; Counter < 10; Counter++)  SPI_WriteByte(0xff);  //输入74个脉冲等待SD卡初始化
do
{
  r1 = SD_SendCommand(0,0,0x95);        //发idle命令
  printf("\nR1: %x ",r1);
}while(r1!=0x01);
}
int32_t main()
{
// uint32_t R1=1;
UARTSPI_INIT();
MMC_FLASH_Init();
while(1){}
}
代码如上:
接受波形:

发送波形



我就是想初始化一下  上电后..发送CMD0  接受个0X01    请问下是不是我的SPI设置错误,还是我的发送命令步骤有问题。

相关帖子

沙发
hotpower| | 2010-11-22 17:49 | 只看该作者
片选信号刚好反了!
DrvSPI_SetSS是CS有效即CS=0
反之CS=1

使用特权

评论回复
板凳
kyzb001|  楼主 | 2010-11-22 19:17 | 只看该作者
[img][/img] 我这个原理图 没问题吧
我换了
继续输出ff

使用特权

评论回复
地板
kyzb001|  楼主 | 2010-11-22 19:55 | 只看该作者
找到了 Ok的   
前三个都是我的帖子。 嘎嘎!

使用特权

评论回复
5
hotpower| | 2010-11-22 19:57 | 只看该作者
什么问题?

使用特权

评论回复
6
kyzb001|  楼主 | 2010-11-23 07:52 | 只看该作者
找到   sd卡的数据手册。

使用特权

评论回复
7
hotpower| | 2010-11-24 06:35 | 只看该作者
sd卡例程好用吗?我问过代理,说“肯定是对的,否则会丢人的”

使用特权

评论回复
8
kyzb001|  楼主 | 2010-11-24 07:53 | 只看该作者
我也相信是对的, 只是到我这里不知道什么原因就不能初始化了。

使用特权

评论回复
9
kyzb001|  楼主 | 2010-11-24 13:10 | 只看该作者
目前用例程 遇到一样的问题, 发送COM1  返回的是1   发送CMD55  返回1   发送ACMD41 返回1。

使用特权

评论回复
10
kyzb001|  楼主 | 2010-11-24 13:26 | 只看该作者
不知道是RP好还是什么的,突然open success了。  发现了原因。

使用特权

评论回复
11
kyzb001|  楼主 | 2010-11-24 13:36 | 只看该作者
我以前都是直接把卡放在卡槽里面,通过电源的开关(我用的是外接电源)控制板子的电源。  那样能正常的发送接受CMD0,但是不能正常的发送和接受CMD1,  如果我先把电源关了,在把卡插上,在开电源,就能正常的打开SD卡了。具体的电路连接我还不知道,为什么我吧电源开关关了,板子还通电。 要等我们硬件工程师回来才晓得。    真是幸运,不然要一直在程序中纠结死。

使用特权

评论回复
12
kyzb001|  楼主 | 2010-11-24 13:44 | 只看该作者
等不及他回来,所以我自己就那了个 电压表测了。 结果,电源控制开关 能正常控制整个板子的电压,出了串口提供的电压,测得在SD卡VDD上位1.8v  不足影响sd卡,为了方便测量 ,我吧卡槽卡紧(之前为了方便拿出,故没卡紧),突然发现变回之前的状态了,难道问题出在卡槽上。 检测去 .................。

使用特权

评论回复
13
kyzb001|  楼主 | 2010-11-24 13:54 | 只看该作者
问题解决了: 卡槽出问题了。

使用特权

评论回复
14
hotpower| | 2010-11-24 16:24 | 只看该作者
晕!

使用特权

评论回复
15
hotpower| | 2010-11-26 06:42 | 只看该作者
进展如何?

使用特权

评论回复
16
hotpower| | 2010-12-26 01:56 | 只看该作者
农会发放棉裤一条以资鼓励

艳照是美得

使用特权

评论回复
17
sky9218| | 2011-2-7 13:24 | 只看该作者
咱还没能弄通,因板载的只有SPI0,找不到相关SPI0读写SD卡的例程,而哪个V1.03的BSP包里的是SPI1,改了很多处还是没能弄通.BSP包里连个硬件接口的说明都没找到.咱相信哪些例程肯定能用的,但对于咱入门的人来说,真的有点看天书一样,不够详细.

使用特权

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

本版积分规则

15

主题

624

帖子

1

粉丝