分类: WINDOWS
2009-04-24 16:14:53
一般操作步骤
如果SPI控制寄存器SPCON已经设置过,则写数据发送寄存器SPTDAT启动发送。对SPI卡操作步骤如下:
(1)设置预分频寄存器SPPRE;
(2)设置控制寄存器SPCON;
(3)设置一个GPIO引脚,使选中的MMC或SD卡的片选信号nSS有效;
(4)向数据发送寄存器SPTDAT写10次0xFF,对MMC或SD卡初始化;
(5)发送数据:先要查询Tx/Rx REDY是否为1,然后向数据发送寄存器SPTDAT写数据;
(6)接收数据:
一般方式(同时收发,TAGD=0):向数据发送寄存器SPTDAT写0xFF,查询并确认Rx REDY为1,然后从数据接收寄存器中读取数据。
仅接收方式(TAGD=1):并确认Rx REDY为1,然后从数据接收寄存器中读取数据。读取数据的同时启动一次发送。
(7)设置GPIO引脚,使选中的MMC或SD卡的片选信号nSS无效,结束传输。
基本上看了这些,再看一下E文,对于2440(与2410的一样)的SPI就应该没问题了
下面是我的代码,是在WIN CE5。0下用的
2440 SPI初使化代码(WIN CE驱动下)
WIN CE 下的SPI口地址映射
看程序不能断章取义,这个是我的一部分代码,只是给大家参考一下,要是自己写的话还是得看明白文档,不过这个初使化还是可以拿来主义的。哈哈
网上的那个mdd.c和spi.c有好多错误,首先是没有v_pCLKPWRregs->rCLKCON |=(1<<18);
这一句,设置SPI的寄存器没用,其次就是SPI的地址映射 v_pCLKPWRregs = (volatile CLKPWRreg *)VirtualAlloc(0, sizeof(CLKPWRreg), MEM_RESERVE, PAGE_NOACCESS);
VirtualCopy((PVOID)v_pCLKPWRregs, (PVOID)(CLKPWR_BASE), sizeof(CLKPWRreg), PAGE_READWRITE | PAGE_NOCACHE);
这一段要加上,还有一个地方就是这个函数
BOOL
SPI_InitAddrSPI(void)
{
BOOL RetValue = TRUE;
// RETAILMSG (1, (TEXT("SPI_InitializeAddresses \r\n") ));
v_pSSPregs = (volatile SSPreg *)VirtualAlloc(0, sizeof(UART2reg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pSSPregs == NULL)
{
// ERRORMSG(1,(TEXT("For SPI_UART2regs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pSSPregs, (PVOID)(UART2_BASE), sizeof(UART2reg), PAGE_READWRITE | PAGE_NOCACHE))
{
// ERRORMSG(1,(TEXT("For SPI_UART2regs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
// RETAILMSG (1, (TEXT("::: SPI_InitializeAddresses - Fail!!\r\n") ));
if (v_pSSPregs)
{
VirtualFree((PVOID) v_pSSPregs, 0, MEM_RELEASE);
}
v_pSSPregs = NULL;
}
else
{
;
// RETAILMSG (1, (TEXT("SPI_InitializeAddresses - Success\r\n") ));
return(RetValue);
}
要改为
BOOL
SPI_InitAddrSPI(void)
{
BOOL RetValue = TRUE;
// RETAILMSG (1, (TEXT("SPI_InitializeAddresses \r\n") ));
v_pSSPregs = (voSSPregslatile SSPreg *)VirtualAlloc(0, sizeof(SSPregs), MEM_RESERVE, PAGE_NOACCESS);
if (v_pSSPregs == NULL)
{
// ERRORMSG(1,(TEXT("For SPI_UART2regs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pSSPregs, (PVOID)(SSP_BASE), sizeof(SSPregs), PAGE_READWRITE | PAGE_NOCACHE))
{
// ERRORMSG(1,(TEXT("For SPI_UART2regs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
// RETAILMSG (1, (TEXT("::: SPI_InitializeAddresses - Fail!!\r\n") ));
if (v_pSSPregs)
{
VirtualFree((PVOID) v_pSSPregs, 0, MEM_RELEASE);
}
v_pSSPregs = NULL;
}
else
{
;
// RETAILMSG (1, (TEXT("SPI_InitializeAddresses - Success\r\n") ));
}
return(RetValue);
}
就这么几个错误搞了我半个月,还有我在61ic上重了3块钱,其实那个程序也是错的,并且是我原来在pudn上下的那个,那个骗人的网站,晕呀!
chinaunix网友2010-08-19 11:06:10
时钟没有明白TAGD位的作用。 在该位位1是,是在什么时机来触发接收的呢? 如果是通过上次读取寄存器来触发,是不是很不灵活呢?
chinaunix网友2010-03-21 13:24:49
你好,我用的是wince,这是驱动程序,不用操作系统直接裸机跑SPI肯定是可以的,那就是把ARM单单片机用了,至于你的程序为什么不好使,应该是你的时序没写对,你是在ADS上编译的吧,你再好好看看你的时序写对了没有,写对了的话应该是有数据出来的。
chinaunix网友2010-01-16 22:47:18
我现在也在做2410的SPI方面,有个疑问想向你请教一下。 2410的SPI程序非得是在LINUX或者WINCE下么?不带系统不行么?我是初学者,还玩不转系统,只是照着书的寄存器设定之类的参考资料写的。但是结果就是SPI的输入输出口子上都没有数据。不明白是不是自己哪里出错,麻烦您帮我看看程序好么? ------------------ #include "config.h" void DelayNS(uint32 dly) { uint32 i; for(; dly>0; dly--) for(i=0; i<50000; i++); } int num1; char rec_data[128]; void spi_init() { rSPPRE1=24; rSPCON1=0x02; rSPPIN1=0x03; rGPGCON = rGPGCON & ~0xFCF3 | 0xFCF1; rGPGDAT = rGPGCON & ~1; //使GPG0输出0 } int main(vo