乌月明星稀 发表于 2024-1-4 12:27

GD32W515 DCI ov2640摄像头连续捕获模式采集帧率低的问题

OV2640在800*600分辨率,JPG格式输出,日志信息如下:
收←◆[ DEBUG]    ov2640 frame count:32768
收←◆[ DEBUG]    ov2640 frame count:33792
收←◆[ DEBUG]    ov2640 frame count:34816
收←◆[ DEBUG]    ov2640 frame count:34816
收←◆[ DEBUG]    ov2640 frame count:34816
收←◆[ DEBUG]    ov2640 frame count:34816
收←◆[ DEBUG]    ov2640 frame count:34816
收←◆[ DEBUG]    ov2640 frame count:34816
即,将近1S才采集一帧。
用逻辑分析仪测试VSYNC,周期大概在37ms,也就是说,一秒有将近30帧输出(可先排除OV2640寄存器相关配置问题,通过串口将jpeg输出到上位机,查看图片也没有问题)。
只要DCI有中断回调,则打印日志,日志速率在500K左右(不用考虑日志速率过低导致漏帧问题)。

DCI的关键配置代码片段如下(参考官方ov2640例程):
    // dci相关I/O口配置为166MHZ速率
    // dci配置
    dci_parameter_struct dci_struct;
    dci_struct.capture_mode   = DCI_CAPTURE_MODE_CONTINUOUS;//DCI_CAPTURE_MODE_SNAPSHOT;
    dci_struct.clock_polarity   = DCI_CK_POLARITY_RISING;
    dci_struct.hsync_polarity   = DCI_HSYNC_POLARITY_LOW;
    dci_struct.vsync_polarity   = DCI_VSYNC_POLARITY_LOW;
    dci_struct.frame_rate       = DCI_FRAME_RATE_ALL;
    // dma配置
    dma_multi_data_parameter_struct      dma_multi_struct;
    dma_multi_struct.periph_addr      = (uint32_t)DCI_DATA_ADDRESS;
    dma_multi_struct.memory0_addr       = (uint32_t)(capture[0].image);
    dma_multi_struct.direction          = DMA_PERIPH_TO_MEMORY;
    dma_multi_struct.number             = (FRAME_BUFFER_SIZE)>>2;
    dma_multi_struct.periph_inc         = DMA_PERIPH_INCREASE_DISABLE;
    dma_multi_struct.memory_inc         = DMA_MEMORY_INCREASE_ENABLE;
    dma_multi_struct.periph_width       = DMA_PERIPH_WIDTH_32BIT;
    dma_multi_struct.memory_width       = DMA_MEMORY_WIDTH_32BIT;
    dma_multi_struct.circular_mode      = DMA_CIRCULAR_MODE_DISABLE,
    dma_multi_struct.priority         = DMA_PRIORITY_HIGH;
    dma_multi_struct.critical_value   = DMA_FIFO_4_WORD;
    dma_multi_struct.memory_burst_width = DMA_MEMORY_BURST_SINGLE;
    dma_multi_struct.periph_burst_width = DMA_PERIPH_BURST_SINGLE;

    dci_struct.interface_format         = DCI_INTERFACE_FORMAT_8BITS;

// ov2640的XCLK时钟输入(由于硬件接到PA2,只能用PWM输出16M左右的时钟作为OV2640时钟输入)
    const timer_parameter_struct timer_init_struct={
      .prescaler          = 0,
      .alignedmode      = TIMER_COUNTER_EDGE,
      .counterdirection   = TIMER_COUNTER_UP,
      .period             = 180/32-1,
      .clockdivision      = 0,
      .repetitioncounter= 0,
    };
    const timer_oc_parameter_struct timer_oc_init_struct={
      .outputstate      = TIMER_CCX_ENABLE,
      .outputnstate       = TIMER_CCXN_DISABLE,
      .ocpolarity         = TIMER_OC_POLARITY_HIGH,
      .ocnpolarity      = TIMER_OCN_POLARITY_HIGH,
      .ocidlestate      = TIMER_OC_IDLE_STATE_LOW,
      .ocnidlestate       = TIMER_OCN_IDLE_STATE_LOW,
    };
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_166MHZ, GPIO_PIN_2);

    timer_init(TIMER1,(timer_parameter_struct*)&timer_init_struct);
    timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM0);
    timer_channel_output_config(TIMER1,TIMER_CH_2,(timer_oc_parameter_struct*)&timer_oc_init_struct);
    timer_break_disable(TIMER1);
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,180/32-2);
    timer_channel_output_state_config(TIMER1,TIMER_CH_2,TIMER_CCX_ENABLE);
    timer_enable(TIMER1);



// DCI连续采集使能
    dma_channel_enable(DMA1,DMA_CH7);
    dci_capture_enable();
    dci_enable();


// DCI中断处理代码
/// @brief 拍照中断
/// @param
void DCI_IRQHandler(void)
{
int size;
size = FRAME_BUFFER_SIZE - (dma_transfer_number_get(DMA1,DMA_CH7)<<2);

dci_interrupt_flag_clear(DCI_INT_EF|DCI_INT_OVR);
// 看现在是捕获进哪个缓冲区,必须清DMA的标志,否则会导致无法继续捕获
dma_channel_disable(DMA1,DMA_CH7);
dma_flag_clear(DMA1,DMA_CH7,DMA_FLAG_FTF|DMA_FLAG_HTF);

if(capture_active){
    if(capture_windex){
      capture_windex = 0;
      capture_rindex = 1;
    }else{
      capture_windex = 1;
      capture_rindex = 0;
    }
    image_size = size;
    capture_active = 0;
    dma_memory_address_config(DMA1,DMA_CH7,DMA_MEMORY_0,(uint32_t)capture.image);
}
dma_transfer_number_config(DMA1,DMA_CH7,(FRAME_BUFFER_SIZE)>>2);
dma_channel_enable(DMA1,DMA_CH7);
//
if(fn_frame_cb)fn_frame_cb(size);
}




乌月明星稀 发表于 2024-1-4 18:43

怎么删帖?问题找到了,OV2640 PCLK时钟降频导致帧率低

wo13579wo 发表于 2025-4-18 23:34

你好 请教一下 为啥我的程序只进一次中断

duo点 发表于 2025-4-28 11:16

帖子发了是删不了的。可重新编辑。
页: [1]
查看完整版本: GD32W515 DCI ov2640摄像头连续捕获模式采集帧率低的问题