2440SPI驱动问题请教。

InsaneCode 2010-05-18 10:44:45
大家好:
这两天搞SPI驱动,2440的SPI寄存器里面有一个发送数据寄存器和一个读数据寄存器。小弟想请问一下,这两个寄存器都是8位的。
问题:
(1)现在如果我写了一个byte的数据到发送的寄存器,我什么时候才能继续发送下一个byte的数据呢?
(2)同样的,我把读取数据寄存器中的一个byte读出来,什么时候去读下一个byte呢?
(3)如果大家谁有2440 wince的SPI驱动可以发给我的话,小弟在这里谢谢了,我的邮箱kacyquan@gmail.com

祝大家天天工作开心,哈哈。
...全文
281 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
gsymichael 2010-05-27
  • 打赏
  • 举报
回复
SPI传输根据相位和电平有4种组合,你这个是否正确?
InsaneCode 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 wjf_zjut 的回复:]
nSS,这个信号是主SPI控制器提供的,每当读或者写的时候会拉低,读完后置高。除非你要模拟主SPI控制。建议示波器看一下,就明白了!
[/Quote]

哦~谢谢您为我解惑了啊~!
InsaneCode 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 gsymichael 的回复:]
引用楼主 kacyquan 的回复:
大家好:
这两天搞SPI驱动,2440的SPI寄存器里面有一个发送数据寄存器和一个读数据寄存器。小弟想请问一下,这两个寄存器都是8位的。
问题:
(1)现在如果我写了一个byte的数据到发送的寄存器,我什么时候才能继续发送下一个byte的数据呢?
(2)同样的,我把读取数据寄存器中的一个byte读出来,什么时候去读下一个byte呢?
(3)如果大家……
[/Quote]

谢谢,学习了。示波器抓了一下,CLK和数据都有了,就是没有模块回来的数据。迷茫了。
InsaneCode 2010-05-27
  • 打赏
  • 举报
回复
谢谢大家的支持。基本上已经可以了~!结贴了
InsaneCode 2010-05-26
  • 打赏
  • 举报
回复
又开始搞了~!继续下一个请教的问题:
传输过程之中nSS这个低电平有效的信号是不是一直拉低就可以,还是写一个byte就是给一个高呢?
谢谢谢谢大家支持啦
wjf_zjut 2010-05-26
  • 打赏
  • 举报
回复
nSS,这个信号是主SPI控制器提供的,每当读或者写的时候会拉低,读完后置高。除非你要模拟主SPI控制。建议示波器看一下,就明白了!
gsymichael 2010-05-26
  • 打赏
  • 举报
回复
[Quote=引用楼主 kacyquan 的回复:]
大家好:
这两天搞SPI驱动,2440的SPI寄存器里面有一个发送数据寄存器和一个读数据寄存器。小弟想请问一下,这两个寄存器都是8位的。
问题:
(1)现在如果我写了一个byte的数据到发送的寄存器,我什么时候才能继续发送下一个byte的数据呢?
(2)同样的,我把读取数据寄存器中的一个byte读出来,什么时候去读下一个byte呢?
(3)如果大家谁有2440 wince……
[/Quote]
没有看过2440的SPI,不过搞过6440的,一般来说对于SPI不仅只有读写寄存器,还有对应的FIFO和移位寄存器,FIFO和移位寄存器对于你来说相当于不可见的,在设置过程中你需要指定FIFO的一个level,比如说FIFO有10个字节,你设置level为5个字节,那么你不停的往写寄存器中写数据,数据就被移到FIFO,FIFO中的数据不停被写到移位寄存器发送出去,如果你写的快,当FIFO数据超过5时,就会告诉你一个Busy状态,那么你就停止一会再往写寄存器中写数据。
所以对于读写来说,你只需要在读写前检查一下状态,状态OK就一直可以读写。
wjcapple 2010-05-24
  • 打赏
  • 举报
回复
顶起,继续学习
InsaneCode 2010-05-24
  • 打赏
  • 举报
回复
感谢大家的帮助。不过数据依然没有写进去。所以暂时不结贴
FrankBIBI 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wjf_zjut 的回复:]
引用 6 楼 kacyquan 的回复:
大家来看我这样写可以不可以
(1)SPI管脚初始化和SPI寄存器初始化
(2)判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果是1则可以开始读写,于是写进去一个byte的数据
(3)再次判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果不是一等待Sleep(1);再去判断(s2440SPI->SPSTA0)寄存器,这个……
[/Quote]

恩 有思路就快了~呵呵
InsaneCode 2010-05-20
  • 打赏
  • 举报
回复
还不能结贴,因为这两天没有调试小板了还没试呢~~调通了就结贴给分。
IT铁哥 2010-05-19
  • 打赏
  • 举报
回复
void __irq Spi_Int(void)
{
unsigned int status;

rINTMSK|=BIT_SPI0;
ClearPending(BIT_SPI0);
status=rSPSTA0;
if(rSPSTA0&0x6)
Uart_Printf("Data Collision or Multi Master Error(0x%x)!!!\n", status);
while(!(rSPSTA0&0x1)); //Check ready state
*spiRxStr++=rSPRDAT0; //First Rx data is garbage data
// Uart_Printf("Current Rx address = 0x%x\n",spiRxStr);

if(*spiTxStr!='\0')
{
rSPTDAT0=*spiTxStr++;
rINTMSK&=~BIT_SPI0;
}
else
{
endSpiTx=1;
}
}
wjf_zjut 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 kacyquan 的回复:]
大家来看我这样写可以不可以
(1)SPI管脚初始化和SPI寄存器初始化
(2)判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果是1则可以开始读写,于是写进去一个byte的数据
(3)再次判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果不是一等待Sleep(1);再去判断(s2440SPI->SPSTA0)寄存器,这个寄存器是1了,我就写进下一个byte。
这……
[/Quote]
可以的啊!
IT铁哥 2010-05-18
  • 打赏
  • 举报
回复
以下是2442的SPI测试代码,希望对你有作用。

void SPI_Port_Init(int MASorSLV)
{
// SPI channel 0 setting
spi_rGPECON=rGPECON;
spi_rGPEDAT=rGPEDAT;
spi_rGPEUP=rGPEUP;
rGPECON=((rGPECON&0xf03fffff)|0xa800000); // using SPI 0
rGPEUP = (rGPEUP & ~(7<<11)) | (1<<13);
spi_rGPGCON=rGPGCON;
spi_rGPGDAT=rGPGDAT;
spi_rGPGUP=rGPGUP;
if(MASorSLV==1)
{
rGPGCON=((rGPGCON&0xffffffcf)|0x10); // Master(GPIO_Output)
rGPGDAT|=0x4; // Activate nSS
}
else
rGPGCON=((rGPGCON&0xffffffcf)|0x30); // Slave(nSS)
rGPGUP|=0x4;
/*
// SPI channel 1-1 setting --> Key board
rGPGCON=(rGPGCON&0xffff033f)|(3<<6)|(3<<10)|(3<<12)|(1<<14); // MISO1, MOSI1, CLK1, Master
rGPGDAT|=0x8;
rGPGUP=(rGPGUP&~(7<<5))|(1<<7);
*/
// SPI channel 1-2 setting --> VD16~18
spi_rGPDCON=rGPDCON;
spi_rGPDDAT=rGPDDAT;
spi_rGPDUP=rGPDUP;
rGPDCON=(rGPDCON&0xcfc0ffff)|(3<<16)|(3<<18)|(3<<20)|(1<<28); // MISO1, MOSI1, CLK1, Master
rGPDDAT|=1<<14;
rGPDUP=(rGPDUP&~(7<<8))|(1<<10);
}

void Test_Spi_M_Int(void)
{
char *rxStr,*txStr;
SPI_Port_Init(1); // Master
Uart_Printf("[SPI Interrupt Master Rx test]\n");
Uart_Printf("This test should be configured two boards\nStart Slave first.\n");
pISR_SPI0=(unsigned)Spi_Int;
endSpiTx=0;
spiTxStr="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
spiRxStr=(char *) SPI_BUFFER;
txStr=(char *)spiTxStr;
rxStr=(char *)spiRxStr;
rSPPRE0=0x1; //if PCLK=50Mhz,SPICLK=12.5Mhz
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//int,en-SCK,master,low,A,normal
// rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//int,en-SCK,master,low,B,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
rGPGDAT&=0xfffffffb; // Activate nSS
rINTMSK=~(BIT_SPI0);

while(endSpiTx==0);

rGPGDAT|=0x4; // Deactivate nSS
rSPCON0=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Poll,dis-SCK,master,low,A,normal
// rSPCON0=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//Poll,dis-SCK,master,low,B,normal
Uart_Printf("Current address :0x%x\n",spiRxStr);
*spiRxStr='\0';//attach End of String(Null)
Uart_Printf("Tx Strings:%s\n",txStr);
Uart_Printf("Rx Strings:%s :",rxStr+1);//remove first dummy data
if(strcmp((rxStr+1),txStr)==0)
Uart_Printf("O.K.\n");
else
Uart_Printf("ERROR!!!\n");
SPI_Port_Return();
}
InsaneCode 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 peasant_lee 的回复:]
"谢谢您了,我的想法不知道是否正确,请您指教。我是主设备,是不是我每发送一个byte的时候,就先时能时钟,然后写一下次数据寄存器,然后再关闭时钟。然后再写下一个byte的时候还这样弄呢?
谢谢了。"

不是的。。。

我说的是SPI的时序,也就是,假如你用GPIO去模拟SPI协议的话,就应该要按照我刚才的说法,我说刚才的那段,是想让你去理解SPI是怎样工作,如何通信的。

当时,你现……
[/Quote]

这样啊~~~太谢谢了,看来我还要好好看看2440的SPEC。有什么问题还需要继续向您请教啊。
Peasant_Lee 2010-05-18
  • 打赏
  • 举报
回复
上面笔误:

当时,你现在使用的是2440的 SPI接口,

但是,你现在使用的是2440的 SPI接口,
Peasant_Lee 2010-05-18
  • 打赏
  • 举报
回复
"谢谢您了,我的想法不知道是否正确,请您指教。我是主设备,是不是我每发送一个byte的时候,就先时能时钟,然后写一下次数据寄存器,然后再关闭时钟。然后再写下一个byte的时候还这样弄呢?
谢谢了。"

不是的。。。

我说的是SPI的时序,也就是,假如你用GPIO去模拟SPI协议的话,就应该要按照我刚才的说法,我说刚才的那段,是想让你去理解SPI是怎样工作,如何通信的。

当时,你现在使用的是2440的 SPI接口,不是模拟的。里面硬件已经做了相关的处理,包括时钟的发出和检测等等,都不需要使用者去理会。一般来说。你现在只要写数据到发送寄存器,就会启动一次发送,但是有些芯片需要设置一下发送使能,这个要看具体的datasheet说明。同理,接收也一样。当接收到一byte数据,会有对应的接收标志位的变化。你去查询这个位,就知道接收到数据,你就去读这个数据。又或者使能了中断的话,接收到数据,会产生中断,等等。

还有,现在很多SPI的接口,都可以设置传输的byte数量了,有些可以一次传若干个byte,,,,
InsaneCode 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 peasant_lee 的回复:]
什么时候需要发送数据,什么时候接收数据,就要看你的时钟了。

SPI的接收发送是同时的,沿不同而已。
假设是双边通信,也就是两边都要收发数据。
假如你是主机,需要发数或者接数的时候,先启动时钟,然后可以发数据或这接数据了。
假如你是从机,只要检测到时钟,就要接收数据,而且同时发数据。
[/Quote]

谢谢您了,我的想法不知道是否正确,请您指教。我是主设备,是不是我每发送一个byte的时候,就先时能时钟,然后写一下次数据寄存器,然后再关闭时钟。然后再写下一个byte的时候还这样弄呢?
谢谢了。
Peasant_Lee 2010-05-18
  • 打赏
  • 举报
回复
什么时候需要发送数据,什么时候接收数据,就要看你的时钟了。

SPI的接收发送是同时的,沿不同而已。
假设是双边通信,也就是两边都要收发数据。
假如你是主机,需要发数或者接数的时候,先启动时钟,然后可以发数据或这接数据了。
假如你是从机,只要检测到时钟,就要接收数据,而且同时发数据。
InsaneCode 2010-05-18
  • 打赏
  • 举报
回复
大家来看我这样写可以不可以
(1)SPI管脚初始化和SPI寄存器初始化
(2)判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果是1则可以开始读写,于是写进去一个byte的数据
(3)再次判断(s2440SPI->SPSTA0)这个寄存器是否为1,如果不是一等待Sleep(1);再去判断(s2440SPI->SPSTA0)寄存器,这个寄存器是1了,我就写进下一个byte。
这样可以吗?
还需要怎么修改。

19,504

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧