本帖最后由 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, ¶m);
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){}
} |