大家好,我最近要用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的回收工作,但是,在使用逻辑分析仪时,发现波形如下:
图中白 {MOD} 就是SPI2的时钟(因为比较密集,所以连一起了),发现 与我设计的有出入。 从程序中, 当FPGA_SCS拉低后,开启DMA,阻塞等待完成,然后拉高FPGA_SCS。但是图中发现 拉高后怎么还有SPI2的时钟在跑呢?
好像while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); 这句话无效
请问怎么回事呢
一周热门 更多>