历史上的今天
今天是:2025年04月27日(星期日)
2019年04月27日 | Stm32作为主设备使用DMA接收SPI数据
2019-04-27 来源:eefocus
DMA发送中断和DMA接收中断必须都打开,如果接受中断不开,貌似只能接收一次成功。同时DMA接收比发送优先级要高,这条没有测试过!!!
以下代码在stm32f407上测试通过
#include "spi_dma.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx.h"
#include "spi.h"
#include "SRAM.h"
#include "data_process.h"
#include #define DMA2_TX_STREAM DMA2_Stream3 #define DMA2_TX_CHANNEL DMA_Channel_3 #define DMA2_RX_STREAM DMA2_Stream0 #define DMA2_RX_CHANNEL DMA_Channel_3 static DMA_InitTypeDef DMA2_Tx_InitStructure; static DMA_InitTypeDef DMA2_Rx_InitStructure; int DMA2_Trans_OVER(void) { return GET_SPI1_STATE; } static void NVIC_DMA2_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//½ÓÊÕÓÅÏȼ¶Òª¸ßÓÚ·¢ËÍ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void DMA2_Configuration(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); DMA_DeInit(DMA2_TX_STREAM); DMA2_Tx_InitStructure.DMA_Channel = DMA2_TX_CHANNEL; //ͨµÀÑ¡Ôñ DMA2_Tx_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;//ÍâÉèµØÖ· DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = 0;//base_address;//ÄÚ´æµØÖ· DMA2_Tx_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//·½ÏòÊÇÄÚ´æµ½ÍâÉè DMA2_Tx_InitStructure.DMA_BufferSize = 0;//ndtr;//´«ÊäÊý¾Ý´óС DMA2_Tx_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèÊý¾ÝÖ¸Õë²»±ä DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æÃ¿´ÎµÝÔö DMA2_Tx_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//ÍâÉèÒ»×Ö½ÚΪµ¥Î» DMA2_Tx_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//ÄÚ´æÒÔ×Ö½ÚΪµ¥Î» DMA2_Tx_InitStructure.DMA_Mode = DMA_Mode_Normal;//Õý³£Ä£Ê½ DMA2_Tx_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA2_Tx_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA2_Tx_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA2_Tx_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//´æ´¢Æ÷Í»·¢µ¥´Î´«Êä DMA2_Tx_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//ÍâÉèÍ»·¢µ¥´Î´«Êä /////////////////////////////////////////////////////////////////////////////// DMA_DeInit(DMA2_RX_STREAM); DMA2_Rx_InitStructure.DMA_Channel = DMA2_RX_CHANNEL; //ͨµÀÑ¡Ôñ DMA2_Rx_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;//ÍâÉèµØÖ· DMA2_Rx_InitStructure.DMA_Memory0BaseAddr = 0;//base_address;//ÄÚ´æµØÖ· DMA2_Rx_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//·½ÏòÊÇÍâÉèµ½ÄÚ´æ DMA2_Rx_InitStructure.DMA_BufferSize = 0;//ndtr;//´«ÊäÊý¾Ý´óС DMA2_Rx_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèÊý¾ÝÖ¸Õë²»±ä DMA2_Rx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æÃ¿´ÎµÝÔö DMA2_Rx_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//ÍâÉèÒ»×Ö½ÚΪµ¥Î» DMA2_Rx_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//ÄÚ´æÒÔ×Ö½ÚΪµ¥Î» DMA2_Rx_InitStructure.DMA_Mode = DMA_Mode_Normal;//Õý³£Ä£Ê½ DMA2_Rx_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA2_Rx_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA2_Rx_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA2_Rx_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//´æ´¢Æ÷Í»·¢µ¥´Î´«Êä DMA2_Rx_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//ÍâÉèÍ»·¢µ¥´Î´«Êä /////////////////////////////////////////////////////////////////////////////// NVIC_DMA2_Configuration(); DMA_ClearITPendingBit(DMA2_TX_STREAM,DMA_IT_TCIF3); DMA_ClearITPendingBit(DMA2_RX_STREAM,DMA_IT_TCIF0); DMA_ITConfig(DMA2_TX_STREAM, DMA_IT_TC, ENABLE);//ʹÄÜDMA·¢ËÍÖÐ¶Ï DMA_ITConfig(DMA2_RX_STREAM, DMA_IT_TC, ENABLE);//ʹÄÜDMA½ÓÊÕÖÐ¶Ï /* Enable SPI1 DMA TX request */ SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx,ENABLE); SET_SPI1_DISABLE; } void SPI1_DMA2_Configuration(void) { printf(" ---------SPI1_DMA2_Configuration----------n"); DMA2_Configuration(); } void SPI1_DMA2_Sendbuffer(uint32_t base_address,uint16_t ndtr,uint8_t *send_buffer) { printf("DMA2 Sendbuffer : address = %x length = %xrn",base_address,ndtr); while (DMA_GetCmdStatus(DMA2_TX_STREAM) != DISABLE){printf(",");} DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)send_buffer; DMA2_Tx_InitStructure.DMA_BufferSize = ndtr; DMA_Init(DMA2_TX_STREAM, &DMA2_Tx_InitStructure); SET_SPI1_ENABLE; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0xe5); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 16) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 8) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 0) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(ndtr >> 8) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(ndtr >> 0) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0x00); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0x00); DMA_Cmd(DMA2_TX_STREAM, ENABLE); } void SPI1_DMA2_Recvbuffer(uint32_t base_address,uint16_t ndtr,uint8_t *recv_buffer) { unsigned char buffer = 0xff; printf("DMA2 Recvbuffer : address = %x length = %xrn",base_address,ndtr); while (DMA_GetCmdStatus(DMA2_RX_STREAM) != DISABLE){printf(".");} while (DMA_GetCmdStatus(DMA2_TX_STREAM) != DISABLE){printf(",");} DMA2_Rx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)recv_buffer; DMA2_Rx_InitStructure.DMA_BufferSize = ndtr; DMA_Init(DMA2_RX_STREAM, &DMA2_Rx_InitStructure); DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//ÄÚ´æµÝÔö DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buffer; DMA2_Tx_InitStructure.DMA_BufferSize = ndtr; DMA_Init(DMA2_TX_STREAM, &DMA2_Tx_InitStructure); SET_SPI1_ENABLE; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0xaa); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 16) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 8) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(base_address >> 0) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(ndtr >> 8) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,(ndtr >> 0) & 0xff); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0x00); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(SPI1,0x00); while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(".");} while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET){ SPI_I2S_ReceiveData(SPI1); } DMA_Cmd(DMA2_RX_STREAM, ENABLE); DMA_Cmd(DMA2_TX_STREAM, ENABLE); } void SPI1_DMA2_GetCounter(void) { printf("DMA2 RECV %d | SEND %drn",(uint16_t)(DMA2_RX_STREAM->NDTR),(uint16_t)(DMA2_TX_STREAM->NDTR)); } void DMA2_Stream3_IRQHandler(void) { if(DMA_GetITStatus(DMA2_TX_STREAM,DMA_IT_TCIF3) != RESET) { DMA_ClearITPendingBit(DMA2_TX_STREAM,DMA_IT_TCIF3); while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(".");} SET_SPI1_DISABLE; //printf("[ISend]"); DMA_Cmd(DMA2_TX_STREAM, DISABLE); } } void DMA2_Stream0_IRQHandler(void) { if(DMA_GetITStatus(DMA2_RX_STREAM,DMA_IT_TCIF0) != RESET) { DMA_ClearITPendingBit(DMA2_RX_STREAM,DMA_IT_TCIF0); while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(",");} //printf("[IRecv]"); DMA_Cmd(DMA2_RX_STREAM, DISABLE); } }
史海拾趣
|
快要毕业了,发现毕业设计完全搞不懂(感觉更像物理专业的人做的-_-|:( )。网上又找不到资料,老师又没什么帮助,我现在着急的很。希望这方面的达人给我些帮助,或者有这方面的资料的给我发一下。非常感谢 题目:CRT彩显高压产生原理及应用--对设 ...… 查看全部问答> |
|
通过这几天的摸索,我终于成功写出一个读取GPS信息的串口程序! 它基于windowsMobile5.0 ppc 程序 在多普达p800中测试通过。 在这里共享给大家! 如果大家有新的思路和方法,咱们也可以一起讨论和研究! 我的妹儿yunfeng83@163. ...… 查看全部问答> |
|
大家好: 最近公司做个项目,需要其它公司提供手持终端,但就选择什么系统的手持终端机产生了疑惑。有的公司用的是linux系统的,有的是windowsCE。当然,设计人员各执己见了,说不同的系统有各自的弊端和优点。 所以 ...… 查看全部问答> |
|
关于SSDT HOOK后通过事件通知应用程序问题 HOOK SSDT应该没有问题通过DbgPrint在自己的函数中显示被HOOK的信息一切正常但是通过事件通知应用程序时却有时候会蓝屏 驱动: 在列程序IRP_MJ_WRITE中 通过 RtlCopyMemory(&hEventApp,Irp->Associa ...… 查看全部问答> |
|
杭州奇比电子产品有限公司诚聘以下岗位:岗位名称:LED产品销售 区域经理(急)岗位职责:1、负责LED灯具和显示屏产品销售;2、制定区域市场营销计划并完成指标;3、收集和分析市场信息,进行客户分析、发展、建立良好的客户关系和客户档案;4、建 ...… 查看全部问答> |
|
我们从德仪e2e博客http://e2e.ti.com/blogs_/default.aspx的多核产品园地博客中发现了很多关于多核应用的好文章,我们翻译、分享一些给大家。 本文重点通过支持多核协会 MCAPI 的可扩展编程模型优化多核 DSP 平台的性能与可移植性。 欲知更多多 ...… 查看全部问答> |




