stm32的spi接收DR是个环形移位寄存器 我如何让他的指针归零

[复制链接]
5247|11
 楼主| jiaojian 发表于 2011-12-5 13:01 | 显示全部楼层 |阅读模式
在全双工模式下 spi主发送的时候也在接收 当我想接收的时候发送了0x00做时钟 但是发现接收的数据移位不对 ,是因为spi的DR是个环形寄存器吧 那我用什么指令 能在我想就收数据的时候 把DR的指针归零?谢谢
香水城 发表于 2011-12-5 13:32 | 显示全部楼层
在全双工模式下 spi主发送的时候也在接收 当我想接收的时候发送了0x00做时钟 但是发现接收的数据移位不对 ,是因为spi的DR是个环形寄存器吧 那我用什么指令 能在我想就收数据的时候 把DR的指针归零?谢谢 ...
jiaojian 发表于 2011-12-5 13:01


你怎么知道DR是个环形寄存器?

接收的数据移位不对有可能是采样的信号边沿不对。
 楼主| jiaojian 发表于 2011-12-5 13:45 | 显示全部楼层
哦那我可能弄错了 就算不是环形的话 我需要把指针清零 怎么做呢 就是我之前发送了若干数据 然后我到我想接收的时候 想让接收接收缓冲区重新开始接收 如何做呢 ?
香水城 发表于 2011-12-5 14:02 | 显示全部楼层
哦那我可能弄错了 就算不是环形的话 我需要把指针清零 怎么做呢 就是我之前发送了若干数据 然后我到我想接收的时候 想让接收接收缓冲区重新开始接收 如何做呢 ? ...
jiaojian 发表于 2011-12-5 13:45


不必做什么,直接接收即可。
 楼主| jiaojian 发表于 2011-12-5 19:29 | 显示全部楼层
写了个读函数
u8 SPIReceiveOneByte(void)
{
   
    unsigned char ucBitCounter=0;
    //u16 unSPIRecBuffer;
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1, 0x00);
        while((SPI1->SR &SPI_I2S_FLAG_RXNE)==RESET);
                return (SPI1->DR);
}
为什么我读的时候需要连续调用两次才能得到正确的值呢 ?
香水城 发表于 2011-12-5 21:03 | 显示全部楼层
本帖最后由 香水城 于 2011-12-5 21:05 编辑
写了个读函数
u8 SPIReceiveOneByte(void)
{
...................   
}
为什么我读的时候需要连续调用两次才能得到正确的值呢 ?jiaojian 发表于 2011-12-5 19:29


那是因为你之前写的时候仍然有数据进来,你没有读取,等你要读数据时,先读出了之前没有读出的最后一个数据,然后才是你要的数据。与你之前说的发现接收的数据移位不对完全是2回事。
 楼主| jiaojian 发表于 2011-12-5 21:29 | 显示全部楼层
没太懂 DR是个移位寄存器 之前我发送时 虽然也接收了无用的内容 但是我最后想接收时发送了 0x00 就是发出了8个clk 那就应该把最后miso上出现的内容移位到DR当中去吧 我读一次应该是正确的啊 ?如图0x40 是miso上我想读出的内容 可是第一次读读出的是0x00
QQ截图20111205215235.jpg
 楼主| jiaojian 发表于 2011-12-5 21:41 | 显示全部楼层
这是第一次读执行完的波形 0x40应该已经被移位进DR了吧
香水城 发表于 2011-12-5 22:08 | 显示全部楼层
为什么你想读的时候要发送一个0x00呢? 因为你想输出时钟!这个时钟是为了读回数据!

难道你之前发送的数据输出时钟吗? 也输出时钟! 难道这个时钟就不读回数据吗? 也读回数据!
 楼主| jiaojian 发表于 2011-12-6 07:53 | 显示全部楼层
多谢版主 可我还是没懂 如图是0x40 是从设备发来的数据 0x40 应该是通过它正下方的那8个clk移位进DR的低8位吧 那8个clk 正是我发0x00产生的 那函数return (SPI1->DR)的数据应该是0x40啊 多谢耐心指教
 楼主| jiaojian 发表于 2011-12-6 14:01 | 显示全部楼层
将读函数改成下面的就正常了
u8 SPIReceiveOneByte(void)
{
    u16 i=0;
    unsigned char ucBitCounter=0;
    u16 unSPIRecBuffer;
        ucBitCounter=SPI1->DR;//接收发送无用字节前 读一次DR 清除RXNE标识        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1, 0x00);
        for(i=500;i>0;i--);
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1, 0x00);
        while((SPI1->SR &SPI_I2S_FLAG_RXNE)==RESET);
                return (SPI1->DR);
}
那如果我一直没有读DR的话 头一次读出来的应该是最前面的8个clk移送的数据吧?
 楼主| jiaojian 发表于 2011-12-6 15:13 | 显示全部楼层
u8 SPIReceiveOneByte(void)
{
    u16 i=0;
    unsigned char ucBitCounter=0;
    u16 unSPIRecBuffer;
        ucBitCounter=SPI1->DR;//接收发送无用字节前 读一次DR 清除RXNE标识        
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
        SPI_I2S_SendData(SPI1, 0x00);
        while((SPI1->SR &SPI_I2S_FLAG_RXNE)==RESET);
                return (SPI1->DR);
}
应该是这样 前面复制多了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

196

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部