OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3516|回复: 1

DMA双缓冲无法切换buffer

[复制链接]

2

主题

5

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2018-12-27
在线时间
20 小时
发表于 2016-12-15 11:05:01 | 显示全部楼层 |阅读模式
1金钱
参考原子哥的程序如下:
#define jpeg_dma_bufsize        1024

void DCMI_DMA_Init(u32 DMA_Memory0BaseAddr,u32 DMA_Memory1BaseAddr,u16 DMA_BufferSize,u32 DMA_MemoryDataSize,u32 DMA_MemoryInc)
{
        DMA_InitTypeDef  DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
        DMA_DeInit(DMA2_Stream1);//等待DMA2_Stream1
        while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){}//等待DMA2_Stream1可配置
       
  /* 配置 DMA Stream */
  DMA_InitStructure.DMA_Channel = DMA_Channel_1;  //通道1 DCMI通道
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&DCMI->DR;//外设地址为CMI->DR
  DMA_InitStructure.DMA_Memory0BaseAddr = DMA_Memory0BaseAddr;//DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到存储器模式
  DMA_InitStructure.DMA_BufferSize = DMA_BufferSize;//数据传输量
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据长度:32位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize;//存储器数据长度
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; //FIFO模式
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//使用全FIFO
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//外设突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//存储器突发单次传输
  DMA_Init(DMA2_Stream1, &DMA_InitStructure);//初始化DMA Stream

        if(DMA_Memory1BaseAddr)//如果存储器1地址有效
  {
                DMA_DoubleBufferModeCmd(DMA2_Stream1,ENABLE);//双缓冲模式
          DMA_MemoryTargetConfig(DMA2_Stream1,DMA_Memory1BaseAddr,DMA_Memory_1);//配置目标地址1
                DMA_ITConfig(DMA2_Stream1,DMA_IT_TC,ENABLE);//开启传输完成中断
               
                NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级0
                NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //子优先级0
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
                NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、
        }
}
void DMA2_Stream1_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_TCIF1)==SET)//DMA2_Steam1,传输完成标志
        {
                 DMA_ClearFlag(DMA2_Stream1,DMA_FLAG_TCIF1);//清除传输完成中断
                 dcmi_rx_callback();        //执行摄像头接收回调函数,读取数据等操作在这里面处理  
        }
}  


void jpeg_dcmi_rx_callback(void)
{
        u16 i;
        if(DMA_GetCurrentMemoryTarget(DMA2_Stream1))
        {
        for(i=0;i<jpeg_dma_bufsize;i++)
        {
        USART_SendData(USART2,jpeg_buf0);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf0>>8);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf0>>16);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf0>>24);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);                               
        }
                printf("A  ");
                jpeg_data_len+=jpeg_dma_bufsize;//偏移
        }else
        {
        for(i=0;i<jpeg_dma_bufsize;i++)
        {
        USART_SendData(USART2,jpeg_buf1);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf1>>8);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf1>>16);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
        USART_SendData(USART2,jpeg_buf1>>24);
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);                               
        }

                printf("B  ");
                jpeg_data_len+=jpeg_dma_bufsize;//偏移
        }
}

通过打印A和B,在串口调试助手中是这样的,
QQ截图20161215110204.jpg


不是应该A和B进行交换的吗

最佳答案

查看完整内容[请看2#楼]

jpeg_dcmi_rx_callback,处理数据太多了,无法监控所有中断。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-12-15 11:05:02 | 显示全部楼层
jpeg_dcmi_rx_callback,处理数据太多了,无法监控所有中断。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 07:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表