本帖最后由 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真是一头雾水啊! |