历史上的今天
返回首页

历史上的今天

今天是: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);

  }

}

推荐阅读

史海拾趣

Delock公司的发展小趣事

在快速发展的同时,Delock公司始终将产品质量放在首位。公司建立了严格的质量控制体系,从原材料采购到生产流程,再到产品出厂,每一个环节都经过严格的检验。这种对品质的坚持让Delock公司的产品赢得了用户的信赖和好评。同时,公司还积极参与各类国际认证和评测,不断提升产品的品质水平。这些努力让Delock公司逐渐在电子行业中树立起了品质卓越的品牌形象。

安信可(Ai)公司的发展小趣事

在快速发展的过程中,安信可通过收购与合作的方式,不断增强自身的综合实力。例如,在2016年,安信可被博安通投资收购,成为其旗下的一员。博安通作为一家专注于物联网领域的技术密集型高新技术企业,为安信可提供了更多的技术支持和市场资源。通过与博安通的合作,安信可进一步巩固了在物联网市场的地位。

联捷(Elinker)公司的发展小趣事

进入21世纪,联捷(Elinker)意识到技术创新的重要性,开始加大在研发方面的投入。经过数年的努力,公司成功研发出具有自主知识产权的电子产品,并在市场上取得了良好的反响。同时,公司开始注重品牌建设,通过一系列的市场推广活动,逐渐树立了联捷(Elinker)在电子行业中的品牌形象。

GSN Electronics公司的发展小趣事

进入21世纪,联捷(Elinker)意识到技术创新的重要性,开始加大在研发方面的投入。经过数年的努力,公司成功研发出具有自主知识产权的电子产品,并在市场上取得了良好的反响。同时,公司开始注重品牌建设,通过一系列的市场推广活动,逐渐树立了联捷(Elinker)在电子行业中的品牌形象。

明微公司的发展小趣事

随着市场的不断变化,明微公司意识到单一业务领域的发展空间有限。于是,公司决定拓展业务领域,实现多元化发展。在保持数字电视芯片领域优势的同时,明微公司积极进军数据通信、汽车电子等领域,通过引进优秀人才、加强技术研发,成功推出了一系列具有市场竞争力的新产品。这些新业务的拓展不仅为公司带来了新的增长点,也进一步提升了公司的市场竞争力。

ASSMANN WSW components公司的发展小趣事

随着公司规模的扩大和产品质量的提升,ASSMANN WSW components公司开始积极拓展全球市场。通过与全球知名企业的合作,公司成功打入国际市场,产品远销海外。同时,公司还积极参加国际电子展会和交流活动,与全球同行建立了广泛的合作关系。这些举措不仅提升了ASSMANN WSW的品牌知名度和影响力,还为公司带来了更多的商业机会和发展空间。

问答坊 | AI 解惑

求助~什么是高压发生电路?

快要毕业了,发现毕业设计完全搞不懂(感觉更像物理专业的人做的-_-|:( )。网上又找不到资料,老师又没什么帮助,我现在着急的很。希望这方面的达人给我些帮助,或者有这方面的资料的给我发一下。非常感谢 题目:CRT彩显高压产生原理及应用--对设 ...…

查看全部问答>

LPC1114 关于GPS模块的资料!!

有做这方面的 交流!!!…

查看全部问答>

高薪招聘硬件工程师

外资公司,工作地点:成都—一座来了就不想离开的城市 硬件工程师(10名): 工作职责(Job Description) : 1、手持设备数模系统的设计、开发与调试; 2、无线通讯终端基带电路的设计、开发与调试; 3、电子消费产品的硬件系统分析、功能定 ...…

查看全部问答>

NAT源代码分析

有没有人做过NAT的功能阿,或研究过WINDNET NAT的源代码的阿?? 大家手上有没有vnvrmsth.h这个文件阿??…

查看全部问答>

贡献一个读GPS信息的串口程序!

通过这几天的摸索,我终于成功写出一个读取GPS信息的串口程序! 它基于windowsMobile5.0 ppc 程序  在多普达p800中测试通过。 在这里共享给大家! 如果大家有新的思路和方法,咱们也可以一起讨论和研究! 我的妹儿yunfeng83@163. ...…

查看全部问答>

linux与windowsCE的选择

大家好:     最近公司做个项目,需要其它公司提供手持终端,但就选择什么系统的手持终端机产生了疑惑。有的公司用的是linux系统的,有的是windowsCE。当然,设计人员各执己见了,说不同的系统有各自的弊端和优点。     所以 ...…

查看全部问答>

关于SSDT HOOK后通过事件通知应用程序问题

关于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 平台的性能与可移植性。 欲知更多多 ...…

查看全部问答>