GD32H759I-EVAL开发板还带了一个DCI接口摄像头,下面试试摄像头功能,在LCD上显示摄像头内容。
摄像头接口如下:
1712397184333.jpg
参考了例程重新整理了一下摄像头驱动。首先初始化GPIO接口,然后就是DCI外设初始化,通过DMA方式将DCI的摄像头数据传到SDRAM地址0XC1000000。
下面是DCI的初始化:
/*!
  •     \brief      configure the DCI to interface with the camera module
  •     \param[in]  none
  •     \param[out] none
  •     \retval     none
  • */
  • void dci_config(void)
  • {
  •     dci_parameter_struct dci_struct;
  •     dma_single_data_parameter_struct  dma_single_struct;
  •    
  •     rcu_periph_clock_enable(RCU_GPIOA);
  •     rcu_periph_clock_enable(RCU_GPIOB);
  •     rcu_periph_clock_enable(RCU_GPIOC);
  •     rcu_periph_clock_enable(RCU_GPIOE);
  •     rcu_periph_clock_enable(RCU_GPIOH);
  •     rcu_periph_clock_enable(RCU_GPIOG);
  •     rcu_periph_clock_enable(RCU_DCI);

  •     /* DCI GPIO AF configuration */
  •     /* configure DCI_PIXCLK(PE3), DCI_VSYNC(PB7), DCI_HSYNC(PA4) */
  •     gpio_af_set(GPIOE, GPIO_AF_13, GPIO_PIN_3);
  •     gpio_af_set(GPIOB, GPIO_AF_13, GPIO_PIN_7);
  •     gpio_af_set(GPIOA, GPIO_AF_13, GPIO_PIN_4);

  •     gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
  •     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_3);
  •     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
  •     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);

  •     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
  •     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_4);

  •     /* configure  DCI_D0(PC6), DCI_D1(PH10) DCI_D2(PC8), DCI_D3(PC9), DCI_D4(PE4), DCI_D5(PB6), DCI_D6(PE5), DCI_D7(PE6) */
  •     gpio_af_set(GPIOC, GPIO_AF_13, GPIO_PIN_6);
  •     gpio_af_set(GPIOC, GPIO_AF_13, GPIO_PIN_8);
  •     gpio_af_set(GPIOC, GPIO_AF_13, GPIO_PIN_9);
  •     gpio_af_set(GPIOB, GPIO_AF_13, GPIO_PIN_6);
  •     gpio_af_set(GPIOE, GPIO_AF_13, GPIO_PIN_4);
  •     gpio_af_set(GPIOE, GPIO_AF_13, GPIO_PIN_5);
  •     gpio_af_set(GPIOE, GPIO_AF_13, GPIO_PIN_6);
  •     gpio_af_set(GPIOH, GPIO_AF_13, GPIO_PIN_10);

  •     gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
  •     gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_10);

  •     gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
  •     gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);
  •     gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
  •     gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_9);
  •     gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
  •     gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_8);
  •     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
  •     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);

  •     gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
  •     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_4);
  •     gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
  •     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_5);
  •     gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
  •     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);

  •     /* DCI configuration */
  •     dci_struct.capture_mode = DCI_CAPTURE_MODE_CONTINUOUS;
  •     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;
  •     dci_struct.interface_format = DCI_INTERFACE_FORMAT_8BITS;
  •     dci_init(&dci_struct);

  •     /* DCI DMA configuration */
  •     rcu_periph_clock_enable(RCU_DMA1);
  •     rcu_periph_clock_enable(RCU_DMAMUX);

  •     dma_single_data_para_struct_init(&dma_single_struct);
  •     dma_deinit(DMA1, DMA_CH7);
  •     dma_single_struct.request = DMA_REQUEST_DCI;
  •     dma_single_struct.periph_addr = (uint32_t)DCI_DATA_ADDRESS;
  •     dma_single_struct.memory0_addr = (uint32_t)0xC1000000;
  •     dma_single_struct.direction = DMA_PERIPH_TO_MEMORY;
  •     dma_single_struct.number = 38400;
  •     dma_single_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  •     dma_single_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  •     dma_single_struct.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;
  •     dma_single_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
  •     dma_single_struct.priority = DMA_PRIORITY_HIGH;
  •     dma_single_data_mode_init(DMA1, DMA_CH7, &dma_single_struct);
  •    
  •     /* DMA interrupt and channel enable */
  •     dma_interrupt_enable(DMA1, DMA_CH7, DMA_CHXCTL_FTFIE);
  •     dma_channel_enable(DMA1, DMA_CH7);
  •     /* enable DMA1 channel 7 */
  •     nvic_irq_enable(DMA1_Channel7_IRQn, 0U, 1U);
  • }
  • 复制代码
    /*!
  •     \brief      ckout0 initialization
  •     \param[in]  none
  •     \param[out] none
  •     \retval     none
  • */
  • void ckout0_init(void)
  • {
  •     rcu_periph_clock_enable(RCU_GPIOA);
  •    
  •     gpio_af_set(GPIOA, GPIO_AF_CKOUT, GPIO_PIN_8);
  •     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
  •     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);

  •     rcu_ckout0_config(RCU_CKOUT0SRC_HXTAL, RCU_CKOUT0_DIV2);
  • }

  • /*!
  •     \brief      DCI camera outsize set
  •     \param[in]  width: outsize width
  •     \param[in]  height: outsize height
  •     \param[out] none
  •     \retval     0x00 or 0xFF
  • */
  • uint8_t ov2640_outsize_set(uint16_t width, uint16_t height)
  • {
  •     uint16_t outh;
  •     uint16_t outw;
  •     uint8_t temp;
  •    
  •     if(width % 4) {
  •         return 0xFF;
  •     }
  •     if(height % 4) {
  •         return 0xFF;
  •     }
  •     outw = width / 4;
  •     outh = height / 4;
  •    
  •     dci_byte_write(0xFF, 0x00);
  •     dci_byte_write(0xE0, 0x04);
  •     dci_byte_write(0x5A, outw & 0xFF);
  •     dci_byte_write(0x5B, outh & 0xFF);
  •    
  •     temp = (outw >> 8) & 0x03;
  •     temp |= (outh >> 6) & 0x04;
  •    
  •     dci_byte_write(0x5C, temp);
  •     dci_byte_write(0xE0, 0x00);
  •    
  •     return 0;
  • }
  • 复制代码

    整个初始化如下:
    /*!
  •     \brief      DCI camera initialization
  •     \param[in]  none
  •     \param[out] none
  •     \retval     0x00 or 0xFF
  • */
  • uint8_t dci_ov2640_init(void)
  • {
  •     uint8_t i;
  •    
  •     sccb_config();
  •     dci_config();
  •     ckout0_init();
  •    
  •     delay_1ms(100);
  •    
  •     /* OV2640 reset */
  •     if(dci_byte_write(0xFF, 0x01) != 0) {
  •         return 0xFF;
  •     }
  •     if(dci_byte_write(0x12, 0x80) != 0) {
  •         return 0xFF;
  •     }
  •     delay_1ms(10);
  •     for(i = 0; i < sizeof(ov2640_svga_init_reg_tbl) / 2; i++)
  •     {
  •         if(0 != dci_byte_write(ov2640_svga_init_reg_tbl[i][0], ov2640_svga_init_reg_tbl[i][1]))
  •         {
  •             return 0xFF;
  •         }
  •     }

  •     delay_1ms(100);
  •     for(i = 0; i < (sizeof(ov2640_rgb565_reg_tbl) / 2); i++)
  •     {
  •         if(0 != dci_byte_write(ov2640_rgb565_reg_tbl[i][0], ov2640_rgb565_reg_tbl[i][1]))
  •         {
  •             return 0xFF;
  •         }
  •     }
  •     delay_1ms(100);
  •     ov2640_outsize_set(320, 240);
  •    
  •     dci_ov2640_id_read(&ov2640id);

  •     return 0;
  • }
  • 复制代码

    DMA中断函数如下:
    /*!
  •     \brief      this function handles DMA1_Channel7_IRQ interrupt request
  •     \param[in]  none
  •     \param[out] none
  •     \retval     none
  • */
  • void DMA1_Channel7_IRQHandler(void)
  • {
  •     if(dma_interrupt_flag_get(DMA1, DMA_CH7, DMA_INT_FLAG_FTF))
  •     {
  •         int i = 0, x = 0, y = 0;
  •         dma_channel_disable(DMA1, DMA_CH7);
  •         dma_interrupt_flag_clear(DMA1, DMA_CH7, DMA_INT_FLAG_FTF);
  •         dma_channel_enable(DMA1, DMA_CH7);
  •     }
  • }
  • 复制代码
    main中调用lcd显示初始化和摄像头初始化和捕捉图像如下:
    1712397281237.jpg
    int main(void)
  • {
  •     /* enable the CPU cache */
  •     SCB_EnableICache();/* enable i-cache */
  •     SCB_EnableDCache();/* enable d-cache */
  •     nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
  •    
  •     /* configure systick */
  •     systick_config();
  •    
  •     init_cycle_counter(true);
  •    
  •     gpio_config();
  •     usart_config();
  •     /* output a message on hyperterminal using printf function */
  •     printf("\r\n GD32H759 Board example.\r\n");
  •    
  •     gd_eval_lcd_init();
  •     lcd_font_set(&LCD_DEFAULT_FONT);
  •     lcd_layer_set(LCD_LAYER_BACKGROUND);
  •     lcd_vertical_string_display(10,0,(uint8_t *)" GD32H759 Camera");
  •    
  •     lcd_layer_set_window(LCD_LAYER_FOREGROUND, 80,15,320, 240,0xC1000000);
  •    
  •     /* camera initialization */
  •     dci_ov2640_init();
  •     dci_enable(); /* DCI enable */
  •     dci_capture_enable();
  •    
  •     while(1)
  •     {
  •         
  • //        GPIO_TG(LED2_GPIO_PORT) = LED2_PIN;
  • //        delay_1ms(100);
  • //        GPIO_TG(LED1_GPIO_PORT) = LED1_PIN;
  • //        delay_1ms(100);
  •         if(gpio_input_bit_get(TAMPER_KEY_GPIO_PORT, TAMPER_KEY_PIN) == RESET)
  •         {
  •             printf("\r\n TAMPER_KEY Press.\r\n");
  •         }
  •         if(gpio_input_bit_get(WAKEUP_KEY_GPIO_PORT, WAKEUP_KEY_PIN) == RESET)
  •         {
  •             printf("\r\n WAKEUP_KEY Press.\r\n");
  •         }
  •         if(gpio_input_bit_get(USER_KEY_GPIO_PORT, USER_KEY_PIN) == RESET)
  •         {
  •             printf("\r\n USER_KEY Press.\r\n");
  •         }
  •     }
  • }
  • 复制代码

    这里重新初始化lcd显示的Layer1为摄像头尺寸320*240分辨率。并且显存直接设置成摄像头的数据区地址0xC1000000.
    lcd_layer_set_window(LCD_LAYER_FOREGROUND, 80,15,320, 240,0xC1000000);
    复制代码

    编译下载之后就可以在lcd上看到摄像头的内容了。
    image.png

    工程:
    GDH7_Demo.zip (1.22 MB, 下载次数: 7)
    全部回复 0
    暂无评论,快来抢沙发吧