正点原子7寸屏所用的显示接口为RGB888 24位色接口,并同时向下兼容RGB666和RGB565两种显示方式,RA8D1-Vision Board上的40针液晶接口开放了RGB666显示方式,即三种颜色的最低两位都拉低了:
根据袁老师的提示,需要将Output颜色格式设置为RGB666,大端模式:
G2D的配置直接照搬RTT例程即可:
使用模拟I2C方式驱动OV5640的SCCB接口,读写寄存器:
uint8_t OV5640_RD_Reg(uint16_t reg) { uint8_t val=0; SCCB_Start(); //启动SCCB传输 SCCB_WR_Byte(OV5640_ADDR); //写器件ID SCCB_WR_Byte(reg>>8); //写寄存器高8位地址 SCCB_WR_Byte(reg); //写寄存器低8位地址 SCCB_Stop(); SCCB_Start(); SCCB_WR_Byte(OV5640_ADDR|0X01);//发送读命令 val=SCCB_RD_Byte(); //读取数据 SCCB_No_Ack(); SCCB_Stop(); return val; } uint8_t OV5640_WR_Reg(uint16_t reg,uint8_t data) { uint8_t res=0; SCCB_Start(); //启动SCCB传输 if(SCCB_WR_Byte(OV5640_ADDR))res=1; //写器件ID if(SCCB_WR_Byte(reg>>8))res=1; //写寄存器高8位地址 if(SCCB_WR_Byte(reg))res=1; //写寄存器低8位地址 if(SCCB_WR_Byte(data))res=1; //写数据 SCCB_Stop(); return res; }
复制代码
OV5640的寄存器是16位的地址,8位的数据,使用一个简单的数组用于存放OV5640初始化寄存器的设置值即可:
static const uint8_t default_regs[][3] = { // https://github.com/ArduCAM/Arduino/blob/master/ArduCAM/ov5640_regs.h { 0x47, 0x40, 0x20 }, { 0x40, 0x50, 0x6e }, { 0x40, 0x51, 0x8f }, { 0x30, 0x08, 0x42 }, { 0x31, 0x03, 0x03 }, { 0x30, 0x17, 0xff }, // { 0x30, 0x17, 0x7f }, { 0x30, 0x18, 0xff }, { 0x30, 0x2c, 0x02 }, { 0x31, 0x08, 0x01 }, { 0x36, 0x30, 0x2e }, { 0x36, 0x32, 0xe2 }, { 0x36, 0x33, 0x23 }, { 0x36, 0x21, 0xe0 }, { 0x37, 0x04, 0xa0 }, { 0x37, 0x03, 0x5a }, { 0x37, 0x15, 0x78 }, { 0x37, 0x17, 0x01 }, { 0x37, 0x0b, 0x60 }, { 0x37, 0x05, 0x1a }, { 0x39, 0x05, 0x02 }, { 0x39, 0x06, 0x10 }, { 0x39, 0x01, 0x0a }, { 0x37, 0x31, 0x12 }, { 0x36, 0x00, 0x08 }, { 0x36, 0x01, 0x33 }, { 0x30, 0x2d, 0x60 }, { 0x36, 0x20, 0x52 }, { 0x37, 0x1b, 0x20 }, { 0x47, 0x1c, 0x50 }, { 0x3a, 0x18, 0x00 }, { 0x3a, 0x19, 0xf8 }, { 0x36, 0x35, 0x1c }, { 0x36, 0x34, 0x40 }, { 0x36, 0x22, 0x01 }, { 0x3c, 0x04, 0x28 }, { 0x3c, 0x05, 0x98 }, { 0x3c, 0x06, 0x00 }, { 0x3c, 0x07, 0x08 }, { 0x3c, 0x08, 0x00 }, { 0x3c, 0x09, 0x1c }, { 0x3c, 0x0a, 0x9c }, { 0x3c, 0x0b, 0x40 }, { 0x38, 0x20, 0x47 }, // { 0x38, 0x20, 0x41 }, { 0x38, 0x21, 0x01 }, { 0x38, 0x00, 0x00 }, { 0x38, 0x01, 0x00 }, { 0x38, 0x02, 0x00 }, { 0x38, 0x03, 0x04 }, { 0x38, 0x04, 0x0a }, { 0x38, 0x05, 0x3f }, { 0x38, 0x06, 0x07 }, { 0x38, 0x07, 0x9b }, { 0x38, 0x08, 0x05 }, { 0x38, 0x09, 0x00 }, { 0x38, 0x0a, 0x03 }, { 0x38, 0x0b, 0xc0 }, { 0x38, 0x10, 0x00 }, { 0x38, 0x11, 0x10 }, { 0x38, 0x12, 0x00 }, { 0x38, 0x13, 0x06 }, { 0x38, 0x14, 0x31 }, { 0x38, 0x15, 0x31 }, { 0x30, 0x34, 0x1a }, { 0x30, 0x35, 0x11 }, // { 0x30, 0x35, 0x21 }, { 0x30, 0x36, OMV_OV5640_PLL_CTRL2 }, // { 0x30, 0x36, 0x46 }, { 0x30, 0x37, OMV_OV5640_PLL_CTRL3 }, { 0x30, 0x38, 0x00 }, { 0x30, 0x39, 0x00 }, { 0x38, 0x0c, 0x07 }, { 0x38, 0x0d, 0x68 }, { 0x38, 0x0e, 0x03 }, { 0x38, 0x0f, 0xd8 }, { 0x3c, 0x01, 0xb4 }, { 0x3c, 0x00, 0x04 }, { 0x3a, 0x08, 0x00 }, { 0x3a, 0x09, 0x93 }, { 0x3a, 0x0e, 0x06 }, { 0x3a, 0x0a, 0x00 }, { 0x3a, 0x0b, 0x7b }, { 0x3a, 0x0d, 0x08 }, { 0x3a, 0x00, 0x38 }, // { 0x3a, 0x00, 0x3c }, { 0x3a, 0x02, 0x05 }, { 0x3a, 0x03, 0xc4 }, { 0x3a, 0x14, 0x05 }, { 0x3a, 0x15, 0xc4 }, { 0x36, 0x18, 0x00 }, { 0x36, 0x12, 0x29 }, { 0x37, 0x08, 0x64 }, { 0x37, 0x09, 0x52 }, { 0x37, 0x0c, 0x03 }, { 0x40, 0x01, 0x02 }, { 0x40, 0x04, 0x02 }, { 0x30, 0x00, 0x00 }, { 0x30, 0x02, 0x1c }, { 0x30, 0x04, 0xff }, { 0x30, 0x06, 0xc3 }, { 0x30, 0x0e, 0x58 }, { 0x30, 0x2e, 0x00 }, { 0x43, 0x00, 0x30 }, { 0x50, 0x1f, 0x00 }, { 0x47, 0x13, 0x04 }, // { 0x47, 0x13, 0x03 }, { 0x44, 0x07, 0x04 }, { 0x46, 0x0b, 0x35 }, { 0x46, 0x0c, 0x22 }, { 0x38, 0x24, 0x02 }, // { 0x38, 0x24, 0x01 }, { 0x50, 0x01, 0xa3 }, { 0x34, 0x06, 0x01 }, { 0x34, 0x00, 0x06 }, { 0x34, 0x01, 0x80 }, { 0x34, 0x02, 0x04 }, { 0x34, 0x03, 0x00 }, { 0x34, 0x04, 0x06 }, { 0x34, 0x05, 0x00 }, { 0x51, 0x80, 0xff }, { 0x51, 0x81, 0xf2 }, { 0x51, 0x82, 0x00 }, { 0x51, 0x83, 0x14 }, { 0x51, 0x84, 0x25 }, { 0x51, 0x85, 0x24 }, { 0x51, 0x86, 0x16 }, { 0x51, 0x87, 0x16 }, { 0x51, 0x88, 0x16 }, { 0x51, 0x89, 0x62 }, { 0x51, 0x8a, 0x62 }, { 0x51, 0x8b, 0xf0 }, { 0x51, 0x8c, 0xb2 }, { 0x51, 0x8d, 0x50 }, { 0x51, 0x8e, 0x30 }, { 0x51, 0x8f, 0x30 }, { 0x51, 0x90, 0x50 }, { 0x51, 0x91, 0xf8 }, { 0x51, 0x92, 0x04 }, { 0x51, 0x93, 0x70 }, { 0x51, 0x94, 0xf0 }, { 0x51, 0x95, 0xf0 }, { 0x51, 0x96, 0x03 }, { 0x51, 0x97, 0x01 }, { 0x51, 0x98, 0x04 }, { 0x51, 0x99, 0x12 }, { 0x51, 0x9a, 0x04 }, { 0x51, 0x9b, 0x00 }, { 0x51, 0x9c, 0x06 }, { 0x51, 0x9d, 0x82 }, { 0x51, 0x9e, 0x38 }, { 0x53, 0x81, 0x1e }, { 0x53, 0x82, 0x5b }, { 0x53, 0x83, 0x14 }, { 0x53, 0x84, 0x06 }, { 0x53, 0x85, 0x82 }, { 0x53, 0x86, 0x88 }, { 0x53, 0x87, 0x7c }, { 0x53, 0x88, 0x60 }, { 0x53, 0x89, 0x1c }, { 0x53, 0x8a, 0x01 }, { 0x53, 0x8b, 0x98 }, { 0x53, 0x00, 0x08 }, { 0x53, 0x01, 0x30 }, { 0x53, 0x02, 0x3f }, { 0x53, 0x03, 0x10 }, { 0x53, 0x04, 0x08 }, { 0x53, 0x05, 0x30 }, { 0x53, 0x06, 0x18 }, { 0x53, 0x07, 0x28 }, { 0x53, 0x09, 0x08 }, { 0x53, 0x0a, 0x30 }, { 0x53, 0x0b, 0x04 }, { 0x53, 0x0c, 0x06 }, { 0x54, 0x80, 0x01 }, { 0x54, 0x81, 0x06 }, { 0x54, 0x82, 0x12 }, { 0x54, 0x83, 0x24 }, { 0x54, 0x84, 0x4a }, { 0x54, 0x85, 0x58 }, { 0x54, 0x86, 0x65 }, { 0x54, 0x87, 0x72 }, { 0x54, 0x88, 0x7d }, { 0x54, 0x89, 0x88 }, { 0x54, 0x8a, 0x92 }, { 0x54, 0x8b, 0xa3 }, { 0x54, 0x8c, 0xb2 }, { 0x54, 0x8d, 0xc8 }, { 0x54, 0x8e, 0xdd }, { 0x54, 0x8f, 0xf0 }, { 0x54, 0x90, 0x15 }, { 0x55, 0x80, 0x06 }, { 0x55, 0x83, 0x40 }, { 0x55, 0x84, 0x20 }, { 0x55, 0x89, 0x10 }, { 0x55, 0x8a, 0x00 }, { 0x55, 0x8b, 0xf8 }, { 0x50, 0x00, 0x27 }, // { 0x50, 0x00, 0xa7 }, { 0x58, 0x00, 0x20 }, { 0x58, 0x01, 0x19 }, { 0x58, 0x02, 0x17 }, { 0x58, 0x03, 0x16 }, { 0x58, 0x04, 0x18 }, { 0x58, 0x05, 0x21 }, { 0x58, 0x06, 0x0F }, { 0x58, 0x07, 0x0A }, { 0x58, 0x08, 0x07 }, { 0x58, 0x09, 0x07 }, { 0x58, 0x0a, 0x0A }, { 0x58, 0x0b, 0x0C }, { 0x58, 0x0c, 0x0A }, { 0x58, 0x0d, 0x03 }, { 0x58, 0x0e, 0x01 }, { 0x58, 0x0f, 0x01 }, { 0x58, 0x10, 0x03 }, { 0x58, 0x11, 0x09 }, { 0x58, 0x12, 0x0A }, { 0x58, 0x13, 0x03 }, { 0x58, 0x14, 0x01 }, { 0x58, 0x15, 0x01 }, { 0x58, 0x16, 0x03 }, { 0x58, 0x17, 0x08 }, { 0x58, 0x18, 0x10 }, { 0x58, 0x19, 0x0A }, { 0x58, 0x1a, 0x06 }, { 0x58, 0x1b, 0x06 }, { 0x58, 0x1c, 0x08 }, { 0x58, 0x1d, 0x0E }, { 0x58, 0x1e, 0x22 }, { 0x58, 0x1f, 0x18 }, { 0x58, 0x20, 0x13 }, { 0x58, 0x21, 0x12 }, { 0x58, 0x22, 0x16 }, { 0x58, 0x23, 0x1E }, { 0x58, 0x24, 0x64 }, { 0x58, 0x25, 0x2A }, { 0x58, 0x26, 0x2C }, { 0x58, 0x27, 0x2A }, { 0x58, 0x28, 0x46 }, { 0x58, 0x29, 0x2A }, { 0x58, 0x2a, 0x26 }, { 0x58, 0x2b, 0x24 }, { 0x58, 0x2c, 0x26 }, { 0x58, 0x2d, 0x2A }, { 0x58, 0x2e, 0x28 }, { 0x58, 0x2f, 0x42 }, { 0x58, 0x30, 0x40 }, { 0x58, 0x31, 0x42 }, { 0x58, 0x32, 0x08 }, { 0x58, 0x33, 0x28 }, { 0x58, 0x34, 0x26 }, { 0x58, 0x35, 0x24 }, { 0x58, 0x36, 0x26 }, { 0x58, 0x37, 0x2A }, { 0x58, 0x38, 0x44 }, { 0x58, 0x39, 0x4A }, { 0x58, 0x3a, 0x2C }, { 0x58, 0x3b, 0x2a }, { 0x58, 0x3c, 0x46 }, { 0x58, 0x3d, 0xCE }, { 0x56, 0x88, 0x11 }, // { 0x56, 0x88, 0x22 }, { 0x56, 0x89, 0x11 }, // { 0x56, 0x89, 0x22 }, { 0x56, 0x8a, 0x11 }, // { 0x56, 0x8a, 0x42 }, { 0x56, 0x8b, 0x11 }, // { 0x56, 0x8b, 0x24 }, { 0x56, 0x8c, 0x11 }, // { 0x56, 0x8c, 0x42 }, { 0x56, 0x8d, 0x11 }, // { 0x56, 0x8d, 0x24 }, { 0x56, 0x8e, 0x11 }, // { 0x56, 0x8e, 0x22 }, { 0x56, 0x8f, 0x11 }, // { 0x56, 0x8f, 0x22 }, { 0x50, 0x25, 0x00 }, { 0x3a, 0x0f, 0x42 }, // { 0x3a, 0x0f, 0x30 }, { 0x3a, 0x10, 0x38 }, // { 0x3a, 0x10, 0x28 }, { 0x3a, 0x1b, 0x44 }, // { 0x3a, 0x1b, 0x30 }, { 0x3a, 0x1e, 0x36 }, // { 0x3a, 0x1e, 0x28 }, { 0x3a, 0x11, 0x60 }, // { 0x3a, 0x11, 0x61 }, { 0x3a, 0x1f, 0x10 }, { 0x40, 0x05, 0x1a }, { 0x34, 0x06, 0x00 }, { 0x35, 0x03, 0x00 }, { 0x30, 0x08, 0x02 }, // OpenMV Custom. { 0x3a, 0x02, 0x07 }, { 0x3a, 0x03, 0xae }, { 0x3a, 0x08, 0x01 }, { 0x3a, 0x09, 0x27 }, { 0x3a, 0x0a, 0x00 }, { 0x3a, 0x0b, 0xf6 }, { 0x3a, 0x0e, 0x06 }, { 0x3a, 0x0d, 0x08 }, { 0x3a, 0x14, 0x07 }, { 0x3a, 0x15, 0xae }, { 0x44, 0x01, 0x0d }, // | Read SRAM enable when blanking | Read SRAM at first blanking { 0x47, 0x23, 0x03 }, // DVP JPEG Mode456 Skip Line Number // End. { 0x00, 0x00, 0x00 } };
复制代码
需要在初始化中按以上数组进行配置:
for (i = 0; default_regs[i][0]; i++) { uint16_t addr = (default_regs[i][0] << 8) | (default_regs[i][1] << 0); uint8_t data = default_regs[i][2]; OV5640_WR_Reg(addr, data); reg = 0; reg = OV5640_RD_Reg(addr); printf("addr 0x%x = 0x%02x\n" , addr , reg); }
复制代码
CEU配置完成后,中断会自动生效,当CEU接口采集到一帧图像之后会触发中断:
#define CAM_WIDTH 320 #define CAM_HEIGHT 240 uint8_t g_image_rgb565_sdram_buffer[CAM_WIDTH * CAM_HEIGHT * 2] BSP_PLACE_IN_SECTION(".sdram") BSP_ALIGN_VARIABLE(8); volatile bool g_ceu_callback_flag = false; void g_ceu_callback(capture_callback_args_t *p_args) { if (CEU_EVENT_HD == p_args->event) { /* Capture has started. Process V-Sync event. */ } if (CEU_EVENT_FRAME_END == p_args->event) { printf("CEU_EVENT_FRAME_END.\n"); g_ceu_callback_flag = true; if (sensor.frame_callback) { sensor.frame_callback(); } } }
复制代码
在主函数中对采集到的缓存进行显示:
while(1) { if(g_ceu_callback_flag) { g_ceu_callback_flag = false; // printf("g_ceu_callback_flag.\n"); lcd_draw_jpg(0 , 0 , g_image_rgb565_sdram_buffer, CAM_WIDTH, CAM_HEIGHT); // R_BSP_SoftwareDelay(500 , BSP_DELAY_UNITS_MILLISECONDS); sensor_snapshot(&sensor, g_image_rgb565_sdram_buffer, 0); } }
复制代码
由于摄像头返回的图像缓存是320*240的分辨率,在大屏幕上面显示太小了,所以可以利用G2D的横纵缩放功能进行图像缓存的放大:
void lcd_draw_jpg(int32_t x, int32_t y, const void *p, int32_t xSize, int32_t ySize) { uint32_t ModeSrc; ModeSrc = d2_mode_rgb565; // Generate render operations d2_framebuffer(d2_handle_obj_get(), (uint16_t *)&fb_background[0], LCD_WIDTH, LCD_WIDTH, LCD_HEIGHT, ModeSrc); d2_selectrenderbuffer(d2_handle_obj_get(), d2_renderbuffer_get()); d2_cliprect(d2_handle_obj_get(), 0, 0, LCD_WIDTH, LCD_HEIGHT); d2_setblitsrc(d2_handle_obj_get(), (void *) p, xSize, xSize, ySize, ModeSrc); // d2_blitcopy(d2_handle_obj_get(), xSize, ySize, 0, 0, (d2_width)(LCD_WIDTH << 4), (d2_width)(LCD_HEIGHT << 4), // (d2_point)(x << 4), (d2_point)(y << 4), 0); d2_blitcopy(d2_handle_obj_get() , xSize , ySize , 0 , 0 , (d2_width)(xSize << 5) , (d2_width)(ySize << 5) , (d2_point)(x << 4) , (d2_point)(y << 4) , 0); // Execute render operations d2_executerenderbuffer(d2_handle_obj_get(), d2_renderbuffer_get(), 0); // In single-buffered mode always wait for DRW to finish before returning d2_flushframe(d2_handle_obj_get()); }
复制代码
|