SPI2发送使用DMA操作的数据不对

helh   2009-5-21 17:20 楼主
我使用SPI2操作M25P64,在写M25P64的时候,如果使用软件发送,读回来的数据是正确的,但是如果使用DMA发送数据即不正确。读回来的数据是0xff.下面是写M25P64的代码,帮忙看看是什么问题?是不是发送用DMA时没有对时钟进行控制,造成对SPI2写溢出?
static void DMA_TxConfiguration(const INT8U *BufferSRC, INT32U BufferSize)
{
    DMA_InitTypeDef DMA_InitStructure;

    DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5 | DMA1_FLAG_GL5);

    /* DMA1 Channel5 disable */
    DMA_Cmd(DMA1_Channel5, DISABLE);

    /* DMA1 Channel5 Config */
    DMA_InitStructure.DMA_PeripheralBaseAddr = (INT32U)SPI2_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (INT32U)BufferSRC;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    /* Enable SPI2 DMA Tx request */
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
    /* DMA1 Channel3 enable */
    DMA_Cmd(DMA1_Channel5, ENABLE);
    while(!DMA_GetFlagStatus(DMA1_FLAG_TC5));
}
static void SPI_FLASH_PageWrite(const INT8U* pBuffer,INT32U WriteAddr,INT16U NumByteToWrite)
{
    if(0 == NumByteToWrite)
        return;
    /* Enable the write access to the FLASH */
    SPI_FLASH_WriteEnable();
  
    /* Select the FLASH: Chip Select low */
    SPI_FLASH_CS_LOW();
    /* Send "Write to Memory " instruction */
    SPI_FLASH_SendByte(WRITE);
    /* Send WriteAddr high nibble address byte to write to */
    SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
    /* Send WriteAddr medium nibble address byte to write to */
    SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);  
    /* Send WriteAddr low nibble address byte to write to */
    SPI_FLASH_SendByte(WriteAddr & 0xFF);
#if 1  
    /* while there is data to be written on the FLASH */
    while(NumByteToWrite--) 
    {
        /* Send the current byte */
        SPI_FLASH_SendByte(*pBuffer);
        /* Point on the next byte to be written */
        pBuffer++; 
    }
    /* Deselect the FLASH: Chip Select high */
    SPI_FLASH_CS_HIGH();
    /* Wait the end of Flash writing */
    SPI_FLASH_WaitForWriteEnd();
#else
    DMA_TxConfiguration(pBuffer,NumByteToWrite);
    SPI_FLASH_CS_HIGH();
    SPI_FLASH_WaitForWriteEnd();
#endif  
}

回复评论 (5)

用示波器看看

                                 再尝试把SPI速度降低点看看。
点赞  2009-5-21 18:59

用示波器看到的结果

设置SPI的时钟为4.5MHz
使用软件发送时:发送1byte到下1byte的时间是4.56us,每bit的时间是220ns
使用DMA发送时:发送1byte到下1byte的时间是3.32us,每bit的时间是220ns
这些可以得出什么结论吗?
点赞  2009-5-22 10:27

1)你可能要检查一下你的设备的时序,2)检查SPI传输结束标

从你给出的数据看,软件发送与DMA发送相比,每bit的时间是一样的,但每byte的时间不一样,这需要检查的设备时序。


还有一个问题,DMA结束时,SPI的传输还没有结束,你需要在DMA结束后通过检查SPI_SR的BSY标志,决定SPI的传输结束。估计这可能是你的问题。
点赞  2009-5-22 11:33
                                 请问如何检查设备的时序?基础问题我还不是很懂
点赞  2009-9-9 14:48
请问如何检查设备的时序?基础问题我还不是很懂
这个问题需要从你使用的外部设备的数据手册中找答案,一般的数据手册中都会有时序的说明。
点赞  2009-9-9 23:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复