stm32f429(HAL库)串口1 DMA双缓冲接收数据模仿录音实验,失败!!!

2019-07-20 08:55发布

相关的配置函数

//串口1接收DMA初始化配置
//DMA2 数据流5  通道2或5
void UART1RxDMA_Config(u8* buf0,u8 *buf1,u16 num,u8 width)
{
    u32 memwidth=0,perwidth=0;     
    switch(width)
    {
        case 0:      
            memwidth=DMA_MDATAALIGN_BYTE;
            perwidth=DMA_PDATAALIGN_BYTE;
            break;
        case 1:     
            memwidth=DMA_MDATAALIGN_HALFWORD;
            perwidth=DMA_PDATAALIGN_HALFWORD;
            break;
        case 2:      
            memwidth=DMA_MDATAALIGN_WORD;
            perwidth=DMA_PDATAALIGN_WORD;
            break;
            
    }
        //impinjbuf1=mymalloc(SRAMEX,IMPINJ_BUF_SIZE);
        //impinjbuf2=mymalloc(SRAMEX,IMPINJ_BUF_SIZE);
    __HAL_RCC_DMA2_CLK_ENABLE();                                
    __HAL_LINKDMA(&UART1_Handler,hdmarx,UART1RxDMA_Handler);      
    UART1RxDMA_Handler.Instance=DMA2_Stream5;                                          
    UART1RxDMA_Handler.Init.Channel=DMA_CHANNEL_4;                 
    UART1RxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;        
    UART1RxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;           
    UART1RxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;               
    UART1RxDMA_Handler.Init.PeriphDataAlignment=perwidth;           
    UART1RxDMA_Handler.Init.MemDataAlignment=memwidth;            
    UART1RxDMA_Handler.Init.Mode=DMA_CIRCULAR;                       
    UART1RxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;           
    UART1RxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;         
    UART1RxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;            
    UART1RxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;           
    HAL_DMA_DeInit(&UART1RxDMA_Handler);                           
    HAL_DMA_Init(&UART1RxDMA_Handler);                              
   
    HAL_DMAEx_MultiBufferStart(&UART1RxDMA_Handler,(u32)&USART1->DR,(u32)buf0,(u32)buf1,num);
    __HAL_DMA_DISABLE(&UART1RxDMA_Handler);                        
    delay_us(10);                                                
    __HAL_DMA_CLEAR_FLAG(&UART1RxDMA_Handler,DMA_FLAG_TCIF1_5);//清除传输完成中断标志位     
    __HAL_DMA_ENABLE_IT(&UART1RxDMA_Handler,DMA_IT_TC);    //开启传输完成中断         
   
    HAL_NVIC_SetPriority(DMA2_Stream5_IRQn,0,1);                 
    HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
}

void ImpinjRxDMA_Start(void)
{   
    __HAL_DMA_ENABLE(&UART1RxDMA_Handler);
}

void ImpinjRxDMA_Stop(void)
{
    __HAL_DMA_DISABLE(&UART1RxDMA_Handler);
}

void DMA2_Stream5_IRQHandler(void)
{  
    if(__HAL_DMA_GET_FLAG(&UART1RxDMA_Handler,DMA_FLAG_TCIF1_5)!=RESET) //DMA传输完成
    {
        __HAL_DMA_CLEAR_FLAG(&UART1RxDMA_Handler,DMA_FLAG_TCIF1_5);     //清除DMA传输完成中断标志位
        UART1RxDMA_callback();    //执行回调函数,读取数据等操作在这里面处理  
    }        
}

//这个回调函数里是切换传输完成内存块的地址
//我所用的双缓冲是在一个大缓存里取相邻的两个小缓存
void UART1RxDMA_callback(void)
{      
        sw_cnt=sw_cnt+1;
      if(sw_cnt/2==1)
        {
            sw_0=sw_0+1;
        }
        else
        {
            sw_1=sw_1+1;
        }            
        if(DMA2_Stream5->CR&(1<<19))
        {
            DMA2_Stream1->M0AR = (u32)&IPJ_BUF[sw_0*2*IPJ_miniBUF_SIZE];
            LED0=!LED0;
        }
        else
        {
            DMA2_Stream1->M1AR = (u32)&IPJ_BUF[IPJ_miniBUF_SIZE+sw_1*2*IPJ_miniBUF_SIZE];
            LED1=!LED1;
        }            
}

//初始化
IPJ_BUF_MALLOC();   //大缓存内存申请
UART1RxDMA_Config(IPJ_BUF,&IPJ_BUF[IPJ_miniBUF_SIZE],IPJ_miniBUF_SIZE,0);//开始采用大缓存的首地址和一个偏移地址,传输项目量为偏移地址大小即小缓存大小
ImpinjRxDMA_Start();//开启传输


问题:无法进入传输完成中断

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
战舰水手
1楼-- · 2019-07-20 14:48
正点原子 发表于 2016-11-20 19:22
先搞出来DMA接收数据(不用双缓冲)

问题找到了  没有使能串口1的DMA传输  
另外原子哥看下这个帖子http://www.openedv.com/thread-87508-1-1.html

里面的串口1接收DMA通道选择是不是不对:DMA_Streamx->CR|=(u32)chx<<25;  //通道选择

战舰水手
2楼-- · 2019-07-20 16:31
 精彩回答 2  元偷偷看……
战舰水手
3楼-- · 2019-07-20 21:26
 精彩回答 2  元偷偷看……
战舰水手
4楼-- · 2019-07-20 22:15
这是录音机实验接收DMA配置后寄存器状态
战舰水手
5楼-- · 2019-07-20 22:51
 精彩回答 2  元偷偷看……
正点原子
6楼-- · 2019-07-21 01:29
先搞出来DMA接收数据(不用双缓冲)

一周热门 更多>