F103的SPI2 通过DMA回收数据的问题

2019-07-21 06:03发布


大家好,我最近要用F103做一个 小系统,需要用 SPI1 +DMA1 往外发数据(输出), 另外需要用SPI2+DMA1 回收数据(输入)

SPI和DMA的初始化如下:

    GPIO_InitTypeDef     GPIO_InitStructure;
    SPI_InitTypeDef       SPI_InitStructure;      
    DMA_InitTypeDef DMA_InitStructure;
   
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1  |RCC_APB2Periph_AFIO, ENABLE);   
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//??SPI2??

    /* ³õʼ»¯SCK¡¢MISO¡¢MOSIÒý½Å */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

    /* ³õʼ»¯CSÒý½Å */
    GPIO_InitStructure.GPIO_Pin = W5500_SCS;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(W5500_SCS_PORT, &GPIO_InitStructure);
    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);

    /* ³õʼ»¯ÅäÖÃSTM32 SPI1 */
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;    //SPIÉèÖÃΪ˫ÏßË«ÏòÈ«Ë«¹¤
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;                            //ÉèÖÃΪÖ÷SPI
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;                        //SPI·¢ËͽÓÊÕ8λ֡½á¹¹
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;                            //ʱÖÓÐü¿ÕµÍ
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;                            //Êý¾Ý²¶»ñÓÚµÚ1¸öʱÖÓÑØ
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;                                //NSSÓÉÍⲿ¹Ü½Å¹ÜÀí
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;    //²¨ÌØÂÊÔ¤·ÖƵֵΪ2
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;                    //Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼
    SPI_InitStructure.SPI_CRCPolynomial=7;                                //CRC¶àÏîʽΪ7
    SPI_Init(SPI1,&SPI_InitStructure);                                    //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPI1¼Ä´æÆ÷

    SPI_Cmd(SPI1,ENABLE);    //STM32ʹÄÜSPI1
   
   
        /* ³õʼ»¯SCK¡¢MISO¡¢MOSIÒý½Å */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

    /* ³õʼ»¯CSÒý½Å */
    GPIO_InitStructure.GPIO_Pin = FPGA_SCS;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(FPGA_SCS_PORT, &GPIO_InitStructure);
    GPIO_SetBits(FPGA_SCS_PORT, FPGA_SCS);

    /* ³õʼ»¯ÅäÖÃSTM32 SPI2 */
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_RxOnly;
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;                            //ÉèÖÃΪÖ÷SPI
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;                        //SPI·¢ËͽÓÊÕ8λ֡½á¹¹
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;                            //ʱÖÓÐü¿ÕµÍ
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;                            //Êý¾Ý²¶»ñÓÚµÚ1¸öʱÖÓÑØ
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;                                //NSSÓÉÍⲿ¹Ü½Å¹ÜÀí
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;    //²¨ÌØÂÊÔ¤·ÖƵֵΪ2
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;                    //Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼
    SPI_InitStructure.SPI_CRCPolynomial=7;                                //CRC¶àÏîʽΪ7
    SPI_Init(SPI2,&SPI_InitStructure);                                    //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPI1¼Ä´æÆ÷

    SPI_Cmd(SPI2,ENABLE);    //STM32ʹÄÜSPI2
   
   


/*????*/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);


        DMA_DeInit(DMA1_Channel4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI2Rx_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 1024;
    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_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);

        DMA_Cmd (DMA1_Channel4,ENABLE);

    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Tx_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 1024;
    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_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);
        DMA_Cmd (DMA1_Channel3,ENABLE);



提上我把重点高亮, SPI1配置为全双工, SPI2 配置为只读模式。

我的系统不需要使用DMA中断,故希望使用阻塞模式进行DMA传输



在主循环中,


            GPIO_ResetBits(FPGA_SCS_PORT, FPGA_SCS);                     
            SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
            while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET);
            GPIO_SetBits(FPGA_SCS_PORT, FPGA_SCS);

通过手动控制FPGA_SCS IO ,在该IO为 低 期间,完成SPI2+DMA1的回收工作,但是,在使用逻辑分析仪时,发现波形如下:
QQ截图20190109031459.png

图中白 {MOD} 就是SPI2的时钟(因为比较密集,所以连一起了),发现 与我设计的有出入。 从程序中, 当FPGA_SCS拉低后,开启DMA,阻塞等待完成,然后拉高FPGA_SCS。但是图中发现 拉高后怎么还有SPI2的时钟在跑呢?
好像while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); 这句话无效

请问怎么回事呢




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。