Board logo

标题: 更改问题,就关于MC9S12DP256 发送数据的问题,麻烦各位帮助,谢谢 [打印本页]

作者: jasontf    时间: 2010-4-7 17:48     标题: 更改问题,就关于MC9S12DP256 发送数据的问题,麻烦各位帮助,谢谢

本帖最后由 jasontf 于 2010-4-8 23:11 编辑

问题缩小:

void SPISendChar ( char c1)
{
    if(SPI2SR_SPTEF ==0)
    while(SPI2SR_SPTEF == 0);
    SPI2DR = c1;

}


char SPIGetChar ( void )
{
    char temp;
    if(SPI2SR_SPIF == 1)
    {
        temp = SPI2DR;
    }
    SPISendChar( 0x00);
    while(SPI2SR_SPIF == 0);
    return SPI2DR;
}

在硬件仿真中单步执行函数  SPISendChar(0X06)
执行到:
    if(SPI2SR_SPTEF ==0)
    while(SPI2SR_SPTEF == 0);

这里的时候,SPIF  是0, SPTEF是1

然后执行到:
    SPI2DR = c1;
这个时候SPIF 变为了1, SPTEF依旧是1

问题:
1.   这不是说明数据已经传送成功了么? 为什么查看SPI0DR数据寄存器的时候,什么东西都没有呢?

2.    SPTEF是不是应该为0呢,不是说先读SPI0SR后写SPI0DR就可以让SPTEF变成0么?

麻烦各位指点。
作者: jasontf    时间: 2010-4-8 11:23

还是没有弄明白怎么回事。。。 求救呀~~
作者: jasontf    时间: 2010-4-8 23:11

求助呀
谢谢
作者: strongchen    时间: 2010-4-9 09:45

SPTEF为1表示SPI发送数据寄存器已空,可以写入下一个发送数据了。当发送数据寄存器里的数据转移到移位寄存器里时(此时SPI开始一位一位地输出数据),即使发送过程还没有完成,就已经可以写入下一个待发送数据了。而这个数据转移的过程是很快的,所以单步执行时,一般看不到SPTEF为0的状态。
作者: jasontf    时间: 2010-4-13 11:28

本帖最后由 jasontf 于 2010-4-13 11:30 编辑

感谢版主,那么我也观察不到SPIDR里面出现数据,这样正常么?
不是单步执行的时候也观察不到SPIDR值有变化。
好比:
SPISendChar(0X01)
直接运行完了观察SPIDR是没有值的。
这样也是正常的么?

再次麻烦你了版主。
作者: strongchen    时间: 2010-4-14 10:28

SPIDR寄存器实际上是两个寄存器,一个是输出寄存器,一个是输入寄存器,它们是共址的。当对这个地址写入时,实际上是对输出寄存器进行操作;而当读这个地址时,则是对输入寄存器进行操作。SPIDR的值是否改变,要看是否有新的输入数据。
作者: jasontf    时间: 2010-4-15 10:07

SPIDR寄存器实际上是两个寄存器,一个是输出寄存器,一个是输入寄存器,它们是共址的。当对这个地址写入时,实际上是对输出寄存器进行操作;而当读这个地址时,则是对输入寄存器进行操作。SPIDR的值是否改变,要看是 ...
strongchen 发表于 2010-4-14 10:28
恍然大悟,多谢版主!!!
作者: jasontf    时间: 2010-4-15 10:19

void stay (void)
{
    int i;
    for(i=0; i<500; ++i)
    {

    }
}


void  InitSPI(void)
{

   
    /* for spi0 and m25p64 */

    DDRK|=DDRK_BIT1_MASK ;
    DDRK|=DDRK_BIT2_MASK ;    //设置PK2口为输出格式
   
    CS_disable (1);
    CS_disable (2);
    SPI0CR1 = 0x50;              //    使能SPI,高位先发
    SPI0CR2 = 0x00;              //
    SPI0BR  = 0x06;              //    128分频
   
  
}


void SPISendChar ( char c1)
{
    if(SPI2SR_SPTEF ==0)
    while(SPI2SR_SPTEF == 0);
    SPI2DR = c1;

}


char SPIGetChar ( void )
{
    char temp;
    if(SPI2SR_SPIF == 1)
    {
        temp = SPI2DR;
    }
    SPISendChar( 0x00);
    while(SPI2SR_SPIF == 0);
    return SPI2DR;
}


char FLASHReadStatus (void)
{
    char temp;
    CS_enable(2);
    stay();
   //PORTK_BIT2 =0 ;
    SPISendChar(RDSR);
    temp = SPIGetChar();
    temp = SPIGetChar();
    stay();
    //PORTK_BIT2 =1;
    CS_disable(2);
    return temp;
}




void main()
{

InitSPI();

while(1)
{
temp= FLASHReadStatus ();
stay();
}

}


通过示波器观察遇到一个不解的问题就是,在主程序中有一个用while循环读 一个flash芯片状态的函数。

当我使用while循环不停地读,SPI时钟信号在片选拉低前就激发了,而MOSI引脚发送数据的信号在片选拉低的同时才激发。

当我不用while循环,利用示波器捕捉到的却是,片选拉低后,时钟信号才激发,  MOSI引脚发送数据的信号在片选拉低的同时激发。
这样的效果与我在函数定义的步骤是一样的,先拉低,后发送数据。

导致这样现象的缘由实在想不通。求助!
作者: strongchen    时间: 2010-4-15 13:58

你不用while循环的时候,程序是怎样的呢?
作者: jasontf    时间: 2010-4-15 15:45

本帖最后由 jasontf 于 2010-4-15 15:49 编辑
你不用while循环的时候,程序是怎样的呢?
strongchen 发表于 2010-4-15 13:58
void main()
{

InitSPI();

temp= FLASHReadStatus ();

}

如果不用while只有一个temp= FLASHReadStatus ();
在restart的时候,也会出错,现象依旧是SPI时钟信号在片选拉低前就激发了,而MOSI引脚发送数据的信号在片选拉低的同时才拉低。

这个是用while的示波器波形:
依次是
SCK时钟信号,片选信号,MOSI  SPI数据输出口

20100413532.jpg 20100413534.jpg 20100413533.jpg

这个是  不用while循环  的示波器波形:
依次是
SCK时钟信号,片选信号,MOSI  SPI数据输出口

20100414541.jpg 20100414542.jpg 20100414543.jpg


一直没有明白是什么导致这样的问题。因为在restart的时候,也会出错,现象和用了while一样,SPI时钟信号在片选拉低前就激发了,而MOSI引脚发送数据的信号在片选拉低的同时才拉低。


麻烦您了版主

图片附件: 20100413534.jpg (2010-4-15 15:42, 625.45 KB) / 下载次数 364
http://bbs.eccn.com/attachment.php?aid=8140&k=dc6fd17168f4916c1754c15df093b43d&t=1732468705&sid=T6ETkT



图片附件: 20100413532.jpg (2010-4-15 15:42, 890.44 KB) / 下载次数 446
http://bbs.eccn.com/attachment.php?aid=8141&k=454f5c01da724e08e718689bc3af6365&t=1732468705&sid=T6ETkT



图片附件: 20100413533.jpg (2010-4-15 15:42, 618.36 KB) / 下载次数 390
http://bbs.eccn.com/attachment.php?aid=8142&k=cd0e732d45d259ee558af55c7185e361&t=1732468705&sid=T6ETkT



图片附件: 20100414541.jpg (2010-4-15 15:42, 670.78 KB) / 下载次数 406
http://bbs.eccn.com/attachment.php?aid=8143&k=577ebd75f494e1e7aaea7fd72b66fe66&t=1732468705&sid=T6ETkT



图片附件: 20100414542.jpg (2010-4-15 15:43, 700.11 KB) / 下载次数 396
http://bbs.eccn.com/attachment.php?aid=8144&k=dca839bac06c2f16312e4be81e4933cf&t=1732468705&sid=T6ETkT



图片附件: 20100414543.jpg (2010-4-15 15:43, 687.1 KB) / 下载次数 399
http://bbs.eccn.com/attachment.php?aid=8145&k=a8cf3cdc1cb5dfc34e8488addd4b0990&t=1732468705&sid=T6ETkT



图片附件: 20100414543.jpg (2010-4-15 15:45, 324.19 KB) / 下载次数 239
http://bbs.eccn.com/attachment.php?aid=8146&k=e8af3829b5655c47a3ceb526d29ce4d8&t=1732468705&sid=T6ETkT


作者: jasontf    时间: 2010-4-15 15:51

补充下示波器

用while的时候使用的是auto模式来观察信号的
不用while的时候,我用single模式来捕捉信号的


麻烦斑竹看看,谢谢您
作者: strongchen    时间: 2010-4-16 10:03

你这些信号都是分别捕捉的,不是用多通道示波器同时获取的,怎么知道哪个先触发哪个后触发呢?单看信号本身的延时是不准确的,那具有一定的随机性。
作者: jasontf    时间: 2010-5-20 12:05

弄来弄去是板子的问题。 不过真的很谢谢斑竹,学习到了很多知识。谢谢!




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0