首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

更改问题,就关于MC9S12DP256 发送数据的问题,麻烦各位帮助,谢谢

更改问题,就关于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么?

麻烦各位指点。
还是没有弄明白怎么回事。。。 求救呀~~
求助呀
谢谢
SPTEF为1表示SPI发送数据寄存器已空,可以写入下一个发送数据了。当发送数据寄存器里的数据转移到移位寄存器里时(此时SPI开始一位一位地输出数据),即使发送过程还没有完成,就已经可以写入下一个待发送数据了。而这个数据转移的过程是很快的,所以单步执行时,一般看不到SPTEF为0的状态。
海纳百川  有容乃大
本帖最后由 jasontf 于 2010-4-13 11:30 编辑

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

再次麻烦你了版主。
SPIDR寄存器实际上是两个寄存器,一个是输出寄存器,一个是输入寄存器,它们是共址的。当对这个地址写入时,实际上是对输出寄存器进行操作;而当读这个地址时,则是对输入寄存器进行操作。SPIDR的值是否改变,要看是否有新的输入数据。
海纳百川  有容乃大
SPIDR寄存器实际上是两个寄存器,一个是输出寄存器,一个是输入寄存器,它们是共址的。当对这个地址写入时,实际上是对输出寄存器进行操作;而当读这个地址时,则是对输入寄存器进行操作。SPIDR的值是否改变,要看是 ...
strongchen 发表于 2010-4-14 10:28
恍然大悟,多谢版主!!!
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引脚发送数据的信号在片选拉低的同时激发。
这样的效果与我在函数定义的步骤是一样的,先拉低,后发送数据。

导致这样现象的缘由实在想不通。求助!
你不用while循环的时候,程序是怎样的呢?
海纳百川  有容乃大
本帖最后由 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引脚发送数据的信号在片选拉低的同时才拉低。


麻烦您了版主

20100414543.jpg (324.19 KB)

20100414543.jpg

补充下示波器

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


麻烦斑竹看看,谢谢您
你这些信号都是分别捕捉的,不是用多通道示波器同时获取的,怎么知道哪个先触发哪个后触发呢?单看信号本身的延时是不准确的,那具有一定的随机性。
海纳百川  有容乃大
弄来弄去是板子的问题。 不过真的很谢谢斑竹,学习到了很多知识。谢谢!
返回列表