21ic电子技术开发论坛 已关闭版块 万利电子 求一个调通的SPI-SD-CARD的程序
发新帖我要提问
12下一页
返回列表
打印

求一个调通的SPI-SD-CARD的程序

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

求一个调通的SPI-SD-CARD的程序。
求一个调通的SPI-SD-CARD的程序。
非常感谢。
#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 auReadSPIData[2];

if(SPI0->CNTRL.GO_BUSY==1)
   printf("\n\nWrite Data is fail\n\n");
SPI0->TX[0] = val;         
SPI0->TX[1] = val;
SPI0->CNTRL.GO_BUSY = 1;
  
while(DrvSPI_IsBusy(eDRVSPI_PORT0));
DrvSYS_Delay(10);
auReadSPIData[0]=SPI0->RX[0];
return auReadSPIData[0];
}
uint32_t SD_SendCommand(uint8_t cmd,uint8_t arg,uint8_t crc)
{
uint32_t r1;
  uint32_t Retry=0;      //重复操作次数
DrvSPI_ClrSS(eDRVSPI_PORT0, eDRVSPI_SS0);
SPI_WriteByte(0xff);  
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
  DrvSPI_SetSS(eDRVSPI_PORT0, eDRVSPI_SS0);                       //使能片选信号
SPI0->CNTRL.TX_BIT_LEN = 8;
SPI_WriteByte(cmd | 0x40);          //分别写入命令
  SPI_WriteByte(arg>>24);            //数据段第4字节
SPI_WriteByte(arg>>16);           //数据段第3字节
    SPI0->CNTRL.TX_BIT_LEN = 8;        //设置传输的位数为 24
SPI_WriteByte(arg>>8);              //数据段第2字节
  SPI_WriteByte(arg);               //数据段第1字节
  SPI_WriteByte(crc);               //CRC效验和

  while((r1 = SPI_WriteByte(0xff)) == 0xff)//等待响应
    if(Retry++ > 200)
     break;//超时退出     
     
  DrvSPI_ClrSS(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);
printf("\nReturn CMD0 is success\n");
}

int32_t main()
{
uint32_t R1=1;
UARTSPI_INIT();
MMC_FLASH_Init();
DrvSDCARD_Open();
while(1){}
}

相关帖子

沙发
yoyowodeai| | 2010-11-19 22:44 | 只看该作者
没有,帮你顶下

使用特权

评论回复
板凳
hotpower| | 2010-11-20 02:52 | 只看该作者
俺都求助了好些次,未果…
这个论坛人气不旺呀…很晕

官方有2个,应该是调试通过的

使用特权

评论回复
地板
kyzb001|  楼主 | 2010-11-20 07:56 | 只看该作者
官方2个,我都看了下,一个NOTE里面的是flash  一个SD卡的。不知道他在做什么。写入CMD0命令都不带74时钟的..........改成SPI0(我的是nuc100,64脚的)后烧写进去没反应。
并且感觉官方给的库很乱。

使用特权

评论回复
5
kyzb001|  楼主 | 2010-11-20 10:02 | 只看该作者
自己美事顶顶.希望能顶一个出来。

使用特权

评论回复
6
hotpower| | 2010-11-20 13:36 | 只看该作者
它写了80个时钟。例程肯定可以用…
研讨会的nuc120是5v的,不能直接接sd卡,m0516的是3.3v,但需要例程的改动。

使用特权

评论回复
7
kyzb001|  楼主 | 2010-11-20 14:18 | 只看该作者
就是说。如果我们接SD卡,就要加电平转换了?  不能对SD卡进行读写操作。

使用特权

评论回复
8
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之前的设置。   不理解啊

使用特权

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

使用特权

评论回复
10
hotpower| | 2010-11-20 15:56 | 只看该作者
楼主用的什么板子?还是自己做的。
多交流…
QQ:1270688699

使用特权

评论回复
11
kyzb001|  楼主 | 2010-11-20 17:54 | 只看该作者
自己做的,我们产品的一个样板。 因为我们是代码移植。 所以就先做了一个样品测试。试试看好不好用,能不能用。   不过我很菜。所以搞的很纠结。  刚接触ARM就上手这玩意,太蛋疼了。

使用特权

评论回复
12
hotpower| | 2010-11-20 19:37 | 只看该作者
会好的,底层主要是SPI,代码移植都是C语言的

使用特权

评论回复
13
kyzb001|  楼主 | 2010-11-21 08:59 | 只看该作者
恩,做了半个月了。主要模块还剩下SPI读写SD卡和GPS的信号采集与分析。

使用特权

评论回复
14
kyzb001|  楼主 | 2010-11-21 09:00 | 只看该作者
不过我总共做了20天,经验不足。调试走了好多弯路啊!

使用特权

评论回复
15
kyzb001|  楼主 | 2010-11-21 09:01 | 只看该作者
自己在顶顶。哈哈,自己把每个贴都顶成红色

使用特权

评论回复
16
vv50000| | 2010-11-21 12:16 | 只看该作者
呵呵 我也在要这个客户要

使用特权

评论回复
17
hotpower| | 2010-11-22 17:54 | 只看该作者
不知楼主进展如何

使用特权

评论回复
18
kyzb001|  楼主 | 2010-11-22 19:48 | 只看该作者
这2天都没怎么调, 昨天上午刚调,芯片烧了。 今天上午 又有事情。 下午3点多才开始调。 不过依然输出ffffff   纠结的fffff。

使用特权

评论回复
19
hotpower| | 2010-11-22 19:58 | 只看该作者
俺觉得还是用原厂的例程先调试,把那几句sd卡上电控制和测试有卡的封掉试试

使用特权

评论回复
20
无冕之王| | 2010-11-22 21:31 | 只看该作者
楼主怎么会一调就烧芯片呢

使用特权

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

本版积分规则

15

主题

623

帖子

1

粉丝
关闭 热门推荐
快速回复 在线客服 返回列表 返回顶部