clear sky . 2024-07-14 22:18 采纳率: 23.1%
浏览 3

DMA实现USART到内存数据转运

#include "stm32f4xx.h"                  // Device header
#include "delay.h"



#include "serial.h"
#include <stdio.h>



#define BUFF_SIZE 100
void DMA_USART_to_RAM();
uint8_t RxData;
uint8_t RxFlag;
uint8_t RxBuf[BUFF_SIZE]={0};
void DMA_USART_ENABLE();
int main(){
    Serial_Init();
    DMA_USART_to_RAM();
    
    printf("success\r\n");
   
    while(1){
            if(RxFlag==1){                
                printf("into interrupt\r\n");                
                DMA_USART_ENABLE();                
                printf("RxData=%d\r\n",RxData);
                printf("USART_ReceiveData(USART2)=%d\r\n",USART_ReceiveData(USART2));
                while(DMA_GetFlagStatus(DMA1_Stream5,DMA_FLAG_TCIF5)==RESET);

                for(uint16_t k=0;k<BUFF_SIZE;k++){
                printf("RxBuf[%d]=%d\r\n",k,RxBuf[k]);                
                }
                RxFlag=0;
            }
    } 
}

void DMA_USART_to_RAM(){
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);    
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_BufferSize=BUFF_SIZE; 
    DMA_InitStructure.DMA_Channel=DMA_Channel_4;
    
    DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&RxBuf;  
    DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&USART2->DR;     
    DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;//详细说明
    
    DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;    
    DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
    
    DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;    
    DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;  
    DMA_InitStructure.DMA_Priority=DMA_Priority_High;    
    DMA_Init(DMA1_Stream5,&DMA_InitStructure);
    DMA_ITConfig(DMA1_Stream5,DMA_IT_TC,ENABLE);
}

void DMA_USART_ENABLE(){
    USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA1_Stream5,ENABLE);
}
void USART2_IRQHandler(){
    if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET){
        RxData=USART_ReceiveData(USART2);
        RxFlag=1;
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);        
        }
}





#include "stm32f4xx.h"                  // Device header
#include "delay.h"



#include "serial.h"
#include <stdio.h>



#define BUFF_SIZE 100
void DMA_USART_to_RAM();
uint8_t RxData;
uint8_t RxFlag;
uint8_t RxBuf[BUFF_SIZE]={0};
void DMA_USART_ENABLE();
int main(){
    Serial_Init();
    DMA_USART_to_RAM();
    
    printf("success\r\n");
   
    while(1){
            if(RxFlag==1){                
                printf("into interrupt\r\n");                
                DMA_USART_ENABLE();                
                printf("RxData=%d\r\n",RxData);
                printf("USART_ReceiveData(USART2)=%d\r\n",USART_ReceiveData(USART2));
                while(DMA_GetFlagStatus(DMA1_Stream5,DMA_FLAG_TCIF5)==RESET);

                for(uint16_t k=0;k<BUFF_SIZE;k++){
                printf("RxBuf[%d]=%d\r\n",k,RxBuf[k]);                
                }
                RxFlag=0;
            }
    } 
}

void DMA_USART_to_RAM(){
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);    
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_BufferSize=BUFF_SIZE; 
    DMA_InitStructure.DMA_Channel=DMA_Channel_4;
    
    DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&RxBuf;  
    DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&USART2->DR;     
    DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;//详细说明
    
    DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;    
    DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
    
    DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;    
    DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;  
    DMA_InitStructure.DMA_Priority=DMA_Priority_High;    
    DMA_Init(DMA1_Stream5,&DMA_InitStructure);
    DMA_ITConfig(DMA1_Stream5,DMA_IT_TC,ENABLE);
}

void DMA_USART_ENABLE(){
    USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA1_Stream5,ENABLE);
}
void USART2_IRQHandler(){
    if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET){
        RxData=USART_ReceiveData(USART2);
        RxFlag=1;
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);        
        }
}

为什么DMA不能实现USART2->DR到RxBuf数据转运?

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-14 22:18
    关注

    引自免费微信小程序:皆我百晓生

    从你的代码中可以看出,DMA(Direct Memory Access)已经正确地被用来实现从USART2接收到的数据自动传送到RxBuf数组的功能。然而,如果你遇到了DMA不能正确实现USART到内存数据转运的问题,可能有以下几个原因:

    1. DMA配置问题:确保DMA的配置参数是正确的。例如,DMA通道、内存地址、外设地址等是否正确配置。特别注意DMA_FIFOThreshold的设置,这里设置为DMA_FIFOThreshold_Full表示当FIFO完全满时开始传输,确保这是你所期望的行为。
    2. USART初始化问题:确认USART(USART2)是否被正确初始化并且配置为正确的模式。检查Serial_Init()函数的实现以确保所有相关设置都是正确的。
    3. 中断优先级问题:确保USART的中断优先级与DMA的中断优先级是匹配的或者DMA的优先级更高。在某些情况下,如果中断的优先级处理不当,可能会导致数据传输问题。
    4. 数据流问题:确保接收到的数据正确存储在RxBuf数组中。你可以在DMA传输完成后检查RxBuf数组的内容来确认这一点。同时,确保DMA传输结束后相关的标志位被正确清除。
    5. 硬件问题:如果以上软件层面的检查都没有问题,那么可能是硬件层面的问题。确保USART和DMA硬件连接是正确的,并且没有损坏或连接不良的情况。
    6. 其他中断冲突问题:检查是否有其他中断(如其他USART中断或其他外设的中断)与DMA传输发生冲突,导致数据传输异常。

    为了更好地诊断问题,你可以添加一些调试语句和代码来监视DMA和USART的状态,并在DMA传输结束后检查RxBuf数组的内容是否完整正确。此外,也可以参考STM32的官方文档和示例代码来确保你的实现是正确的。如果问题仍然存在,可能需要使用调试器进行更深入的分析和调试。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月14日

悬赏问题

  • ¥15 一道ban了很多东西的pyjail题
  • ¥15 关于#r语言#的问题:如何将生成的四幅图排在一起,且对变量的赋值进行更改,让组合的图漂亮、美观@(相关搜索:森林图)
  • ¥15 C++识别堆叠物体异常
  • ¥15 微软硬件驱动认证账号申请
  • ¥15 有人知道怎么在R语言里下载Git上的miceco这个包吗
  • ¥15 GPT写作提示指令词
  • ¥20 根据动态演化博弈支付矩阵完成复制动态方程求解和演化相图分析等
  • ¥20 关于DAC输出1.000V对分辨率和精度的要求
  • ¥15 华为超融合部署环境下RedHat虚拟机分区扩容问题
  • ¥15 哪位能做百度地图导航触点播报?