在STR912的SPI通信中使用 DMA 的困惑
使用环境: 使用的SPI端口为 SSP0, 初始化速率为5Mhz 使用 DMA Channel1 作为SPI的发送控制, DMA Channel2 作为SPI的接收控制, SPI的外接设备为一个SPI转UART的芯片。 当设置 SPI为 Loop 测试模式的时候,使用下面的程序工作正常,指示灯亮
SSP_LoopBackMode(SSP0,ENABLE); //1 VK_StartDMA_Tx(BU0,5); //2 VK_StartDMA_Rx(BU1,5); //3 DMA_VKRx_WaitEnd; //4 DMA_VKRx_ClrEnd; //5
if ( BU0[0]==BU1[0] && BU0[1]==BU1[1] && BU0[2]==BU1[2] ) LED_ON(LED1); else LED_OFF(LED1);
当SPI为正常模式的时候, 必须在2和3语句之间加延时才能正确,延时的时间大于 VK_StartDMA_Tx函数DMA发送完成所需的时间 给人的感觉SSP0不支持收发同时进行DMA传送。 感觉ST STR912的技术文档比TI 430的差的很多,而且ST网站的速度太慢!!! 附有关代码
/************************************************** VK Start DMA Tx **************************************************/ void VK_StartDMA_Tx(void *Bu, u16 Count) {
DMA_VKTx_ClrEnd; DMA_VKTx_ClrErr; DMA_VKTx_DISABLE; DMA_VKTx->SRC=(u32)Bu; DMA_VKTx->CC = DMA_SrcWidth_HalfWord | DMA_ChannelSRCInc | 0x80000000 | DMA_DesWidth_HalfWord | (Count & 0x0FFF); DMA_VKTx_ENABLE; }
/************************************************** Init SSP0 **************************************************/ void init_SSP0(void) { SSP_InitTypeDef SSP_InitStructure; SSP_StructInit(&SSP_InitStructure); SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_Motorola; SSP_InitStructure.SSP_Mode = SSP_Mode_Master; SSP_InitStructure.SSP_CPOL = SSP_CPOL_Low; SSP_InitStructure.SSP_CPHA = SSP_CPHA_1Edge; SSP_InitStructure.SSP_DataSize = SSP_DataSize_16b; SSP_InitStructure.SSP_SlaveOutput = SSP_SlaveOutput_Enable; SSP_InitStructure.SSP_ClockRate = 0; SSP_InitStructure.SSP_ClockPrescaler = 10; // 4.8 MHz SSP_Init(SSP0, &SSP_InitStructure); SSP_Cmd(SSP0,ENABLE);
/************************************************** Start DMA Rx **************************************************/ void VK_StartDMA_Rx(void *Bu, u16 Count) {
DMA_VKRx_ClrEnd; DMA_VKRx_ClrErr; DMA_VKRx_DISABLE; DMA_VKRx->DES=(u32)Bu; DMA_VKRx->CC = DMA_SrcWidth_HalfWord | DMA_ChannelDESInc | 0x80000000 | DMA_DesWidth_HalfWord | (Count & 0x0FFF); DMA_VKRx_ENABLE; }
void init_DMA() { DMA_InitTypeDef DMA_InitStruct;
DMA_Cmd(ENABLE); // Enable the DMA // DMA For SSP0 Tx DMA_VKTx_DISABLE; DMA_SyncConfig(DMA_SSP0_TX_Mask, ENABLE); // 同步设置 DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm = 0; DMA_InitStruct.DMA_Channel_DesAdd = (u32)(&SSP0->DR); DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize= DMA_DesBst_1Data; // ????? DMA_InitStruct.DMA_Channel_SrcBstSize= DMA_SrcBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl1_DMA; // memory-to-Peripheral DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP0_TX;
DMA_Init(DMA_VKTx,&DMA_InitStruct); SSP_DMACmd(SSP0,SSP_DMA_Transmit,ENABLE);
// DMA For SSP0 Rx DMA_VKRx_DISABLE; DMA_SyncConfig(DMA_SSP0_RX_Mask, ENABLE); // 同步设置 DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm = 0; DMA_InitStruct.DMA_Channel_SrcAdd = (u32)(&SSP0->DR); DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize= DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_SrcBstSize= DMA_SrcBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl2_DMA; // Peripheral-to-memory DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX;
DMA_Init(DMA_VKRx,&DMA_InitStruct); SSP_DMACmd(SSP0,SSP_DMA_Receive,ENABLE); } |