STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]( 二 )

SPI的配置

STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]

文章插图
STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]

文章插图
1 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA传输 2 ///////以下配置DMA CH2用于接收SPI的DMA通道///// 3 DMA_DeInit(DMA1_Channel2);//将DMA的通道1寄存器重设为缺省值 4 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(SPI1->DR);//DMA外设基地址 5 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)spi_rx_buff;//DMA内存基地址 6 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取数据到内存 7 DMA_InitStructure.DMA_BufferSize = num;//DMA通道的DMA缓存的大小 8 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变 9 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增10 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位11 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位12 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常模式13 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA通道 x拥有中优先级14 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输15 DMA_Init(DMA1_Channel2, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道16 ///////以下配置DMA的SPI发送通道///////////17 DMA_DeInit(DMA1_Channel3);18 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(SPI1->DR); //设置接收外设(0x4001300C) 地址(源地址)19 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_tx_buff;//设置 SRAM 存储地址(源地址)20 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//传输方向 内存-外设21 DMA_InitStructure.DMA_BufferSize = num;//设置 SPI1 接收长度22 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址增量(不变)23 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址增量(变化)24 DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord; //外设传输宽度(字节)25 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存传输宽度(字节)26 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //传输方式,一次传输完停止,不重新加载27 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA优先级28 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//内存到内存方式禁止29 DMA_Init(DMA1_Channel3, &DMA_InitStructure);收发两个DMA通道的配置
主程序中收发控制程序如下:
STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]

文章插图
STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]

文章插图
1 SPIx_Init();//SPI初始化 2 DMA_Config(256);//配置DMA对应的两个通道,数据深度设为256 3 SPI_I2S_DMACmd(SPI1 , SPI_I2S_DMAReq_Rx , ENABLE); 4 SPI_I2S_DMACmd(SPI1 , SPI_I2S_DMAReq_Tx , ENABLE); 5 while(1) 6 { 7DMA_SetCurrDataCounter(DMA1_Channel2,256);//必须在每次启动DMA之前设置 8DMA_SetCurrDataCounter(DMA1_Channel3,256);//必须在每次启动DMA之前设置 9DMA_Cmd(DMA1_Channel2, ENABLE);//使能DMA所指示的通道10DMA_Cmd(DMA1_Channel3, ENABLE);//使能DMA所指示的通道11while(1)12{13if(DMA_GetFlagStatus(DMA1_FLAG_TC2) != RESET)//判断通道2传输完成14{15DMA_ClearFlag(DMA1_FLAG_TC2);//清除通道2传输完成标志16break;17}18}19DMA_Cmd(DMA1_Channel2, DISABLE);//禁止DMA20DMA_Cmd(DMA1_Channel3, DISABLE);//禁止DMA21delay_ms(1);22 }SPI主机DMA使用流程
这里我没有使用DMA中断,为的是验证代码的简单易懂;在实际使用时,建议读者使用中断以提高数据读写效率 。另外,代码中值得注意的地方有:

经验总结扩展阅读