eew_7QI3Yq 发表于 2024-8-30 13:57

【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+摄像头和显示屏结合

<div class='showpostmsg'><p>上次我们通过开发板进行了摄像头测试,关键我们只能通过仿真然后进内存中查看里面的图像数据,还有点掉帧,所以我们结合我们的屏幕进行测试直接显示到LCD上。</p>

<p > &nbsp;</p>

<p >我们在摄像头的基础上增加我们的RGB LCD的配置。之前都是现成的所以拿来用下即可。</p>

<p > &nbsp;</p>

<p >把关键的引脚初始化好,相关的配置设置好。即可。</p>

<p >我们都知道摄像头的数据都是存储在内存中的,所以我们去找相关内存数据给其刷新到LCD上即可。</p>

<p > &nbsp;</p>

<p >也就是我自己定义的一个函数,主要是按照图片大小来进行刷新。</p>

<p > &nbsp;</p>

<p >关键的是我们要给其数组进行拼接,因为RGB565是16位的数据为一个颜色。</p>

<pre>
<code>#include "hal_data.h"
#include "ceu.h"
#include "ov5640.h"
#include "board_sdram.h"
#include "glcdc_ep.h"


FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER


extern uint32_t g_image_width;
extern uint32_t g_image_height;
extern uint8_t * gp_image_buffer;
extern sensor_reg_t const * gp_ov5640_resolution;
extern capture_instance_t const * gp_ceu_instance;


/* Variables to store resolution information */
uint16_t g_hz_size, g_vr_size;
/* Variables used for buffer usage */
uint32_t g_buffer_size;
uint8_t * g_p_single_buffer, * g_p_double_buffer;

#define RESET_VALUE             (0x00)

static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);

static void color_band_display(void);

static void show_img_display(void);

/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */
//    fsp_pack_version_tversion = {RESET_VALUE};
    fsp_err_t         err   = FSP_SUCCESS;




    /* Initialize SDRAM */
    bsp_sdram_init();
    /* Initialize GPT module */
//    err = R_GPT_Open(&amp;g_timer_periodic_ctrl, &amp;g_timer_periodic_cfg);
//    handle_error(err, " ** R_GPT_Open API FAILED ** \r\n");

    /* Start GPT module to provide the 24MHz clock frequency output for the camera clock source */
//    err = R_GPT_Start(&amp;g_timer_periodic_ctrl);
//    handle_error(err, " ** R_GPT_Start API FAILED ** \r\n");

    /* Initialize IIC module */
    err = R_SCI_B_I2C_Open(&amp;g_sci_i2c_master_for_ov5640_ctrl, &amp;g_sci_i2c_master_for_ov5640_cfg);
//    handle_error(err, " ** R_IIC_MASTER_Open API FAILED ** \r\n");

    /* Initialize OV3640 sensor with output format as YUV422 */
    err = ov5640_open();
//    handle_error(err, " ** ov3640_open FAILED ** \r\n");

    /* Get LCDC configuration */
    g_hz_size = (g_display_cfg.input.hsize);
    g_vr_size = (g_display_cfg.input.vsize);
    /* Initialize buffer pointers */
    g_buffer_size = (uint32_t) (g_hz_size * g_vr_size * BYTES_PER_PIXEL);
    g_p_single_buffer = (uint8_t *) g_display_cfg.input.p_base;
    /* Double buffer for drawing color bands with good quality */
    g_p_double_buffer = g_p_single_buffer + g_buffer_size;


    /* Initialize GLCDC driver */
    err = R_GLCDC_Open(&amp;g_display_ctrl, &amp;g_display_cfg);


   /* Handle error */
//       if(FSP_SUCCESS != err)
//       {
//         /* GLCDC initialization failed*/
//         APP_ERR_PRINT("\r\n ** GLCDC driver initialization FAILED ** \r\n");
//         APP_ERR_TRAP(err);
//       }

   /* Start GLCDC display output */
   err = R_GLCDC_Start(&amp;g_display_ctrl);
   /* Handle error */
//       if(FSP_SUCCESS != err)
//       {
//         /* GLCDC initialization failed*/
//         APP_ERR_PRINT("\r\n ** GLCDC driver start FAILED ** \r\n");
//         APP_ERR_TRAP(err);
//       }

   /* Clear LCD screen using appropriate co-ordinates */
   screen_display((uint16_t)X1_CO_ORDINATE, (uint16_t)Y1_CO_ORDINATE, g_hz_size, g_vr_size, YELLOW);

   /* Display color bands on LCD screen */
//   color_band_display();

    /* Main loop */
    while(true)
    {
      /* User selects type of memory to store image and resolution of image */
      selection_menu();

      /* Set camera resolution specified by ov3640 array pointer */
      err = ov5640_set_resolution(gp_ov5640_resolution);
//      handle_error(err, " ** ov3640_set_resolution FAILED ** \r\n");

      /* Perform CEU operation specified by ceu instance pointer and store image in buffer specified by image buffer pointer */
      err = ceu_operation(gp_ceu_instance, gp_image_buffer, g_image_width, g_image_height);

      show_img_display();

//      screen_display((uint16_t)X1_CO_ORDINATE, (uint16_t)Y1_CO_ORDINATE, g_hz_size, g_vr_size, &amp;gp_image_buffer);
//      handle_error(err, " ** ceu_operation FAILED ** \r\n");
    }


#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
* This function is called at various points during the startup process.This implementation uses the event that is
* called right before main() to set up the pins.
*
* @paramevent    Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

      /* Enable reading from data flash. */
      R_FACI_LP-&gt;DFLCTL = 1U;

      /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
      /* C runtime environment and system clocks are setup. */

      /* Configure pins. */
      R_IOPORT_Open (&amp;IOPORT_CFG_CTRL, &amp;IOPORT_CFG_NAME);

#if BSP_CFG_SDRAM_ENABLED

      /* Setup SDRAM and initialize it. Must configure pins first. */
      R_BSP_SdramInit(true);
#endif
    }
}

#if BSP_TZ_SECURE_BUILD

FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
FSP_CPP_FOOTER

#endif



static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color)
{
    /*Declare local variables */
    uint16_t start_x, start_y, display_length, display_height;
    uint32_t start_addr;

    /* Assign co-ordinate values and calculate start address */
    start_x = x1;
    start_y = y1;
    start_addr = (uint32_t)((start_x * BYTES_PER_PIXEL) + (start_y * g_hz_size* BYTES_PER_PIXEL));

    /* Calculate display box length and height */
    display_length = (uint16_t)((x2 - x1) * BYTES_PER_PIXEL);
    display_height = (y2 - y1);

    /* Display required color band */
    for(uint16_t ver_value = Y1_CO_ORDINATE; ver_value &lt; (display_height - INC_DEC_VALUE); ver_value++)
    {
      for(uint32_t hor_value = start_addr; hor_value &lt; (start_addr + display_length); hor_value += BYTES_PER_PIXEL)
      {
            *(uint32_t *) (g_p_single_buffer + hor_value) = color;
            *(uint32_t *) (g_p_double_buffer + hor_value) = color;
      }
      start_addr = (uint32_t)(start_addr + (g_hz_size * BYTES_PER_PIXEL));
    }
}

static void color_band_display(void)
{

    uint16_t color= {RED, GREEN, BLUE, BLACK, WHITE, YELLOW, MAGENTA, CYAN};

    uint16_t width = g_vr_size/COLOR_BAND_COUNT;

    for (uint8_t display_count = RESET_VALUE; display_count &lt; COLOR_BAND_COUNT; display_count++)
    {
       screen_display((uint16_t)X1_CO_ORDINATE, (display_count * width), g_hz_size, (uint16_t)(((display_count * width) + width) + INC_DEC_VALUE), color);
    }


}
static void show_img_display(void)
{
//    uint16_t color= {RED, GREEN, BLUE, BLACK, WHITE, YELLOW, MAGENTA, CYAN};

//    uint16_t width = g_vr_size/COLOR_BAND_COUNT;

    uint32_t gp_image_buffer_count = 0;

    for (uint16_t y_count = 0; y_count &lt; g_image_height; y_count++)
    {
      for (uint16_t x_count = 0; x_count &lt; g_image_width; x_count++)
       {

            screen_display((uint16_t)x_count, (uint16_t)y_count , (uint16_t)x_count+1, (uint16_t)(y_count + 2), ((gp_image_buffer)&lt;&lt;8|(gp_image_buffer)));
            gp_image_buffer_count = gp_image_buffer_count + 2;
       }

    }

}


</code></pre>

<p > &nbsp;</p>

<p >这样显示出我们天花板的图像了,刷新还比较慢,后期应该可以通过其他方式给他加速。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+摄像头和显示屏结合