cubeIDE开发,在LCD显示摄像头抓取的图片数据
创始人
2024-04-17 15:11:43
0

一、摄像头相关资料信息

        在LCD上显示当前camera的图像数据,类似我们前面提到的LCD显示图片数据,就是实时将摄像头抓取的视频数据帧(图片)转换成图片字码表,即LCD宽*LCD高像素大小的颜色点阵,然后推送到LCD接口实现刷新显示。

        本博文使用的是STM32L496VGT3开发板进行测试,该开发板自带了Camera摄像头,采用DCMI 接口与MCU通信,Camera 是由深圳影领电子有限公司提供的 YL-F170066-0329.采用的是 8bits 数据接口,通过 24Pin BTB 连接器外接一个 Camera 模组。Camera 配置通过 I2C3 接入 MCU,地址为 0x78/0x79。BTB 连接器的接口定义如下表:

         即对于Camera 下行指令是采用I2C通信,视频数据推送给MCU采用的是DCMI 通信。Camera 的硬件原理框图如下:

         各个引脚相关参数:

二、 基于旧(.ioc)创建新工程

        本文基于本专栏前面的LCD显示图片博文上进行创建新工程,并将其源码移植到新工程,然后在此基础上进行Camera相关配置及源码实现。

        cubeIDE开发,结合图片取模工具,stm32程序在LCD显示图片_py_free的博客-CSDN博客

        【1】在CubeIDE工作空间,创建一个stm32L496VGTx_cam的目录文件,将前面LCD显示图片工程的(stm32L496VGTx_lcm.ioc)拷贝到该目录下,并改名为stm32L496VGTx_cam.ioc.

        【2】打开cubeIDE开发工具,选择Create a New STM32 Project from an Existing STM32CubeMX Configuration File(.ioc)新建一个工程

         【2】选择刚刚拷贝并修改了名字的(.ioc)文件,在工程配置属性页面中,将工程名称及工程存放路径设置为刚刚新建文件夹的路径,完成工程创建。

         【4】创建工程后,在工程目录下新建一个ICore源文件夹,将原来stm32L496VGTx_lcm工程的ICore源码文件目录拷贝覆盖该文件夹。同时,也可将原来工程有过调整的spi.c和main.c文件拷贝覆盖到新工程文件中,同样,禁止syscalls.c编译。设置项目编译输出支持bin和hex格式。

         然后点击编译,成功通过编译,妥妥的是上次博文中实现的工程,只是更换了个工程名字而已。

  三、配置与Camera相关的MCU引脚

        在成功移植LCD显示图片工程后,双击stm32L496VGTx_cam.ioc打开cubeMX编辑界面,按上述的引脚要求配置MCU与Camera相关引脚。

        【1】开启I2C3的功能,参数保持默认设置即可

         I2C3的引脚相关配置如下:

        【2】开启DCMI功能 ,参数设置如下。

         添加DCMI的DMA功能支持

         并开启DCMI的终端功能支持

         DCMI相关引脚配置如下:

         【3】开启Camera辅助功能的GPIO引脚接口(PB8、PE13配置,与上面开发板给出的引脚参数资料不同)

         PA8引脚配置

         完成配置后点击保存输出生成代码。

四、Camera源码设计

        在ICore中添加一个cam目录,并在该目录下创建Camera.h和Camera.c源文件。图形编辑配置界面生成代码及手动添加代码结构如下。

         1、gc0329 型号芯片数据手册分析

        本Camera模组的MCU芯片是gc0329 型号芯片,我在网上查阅该型号的数据手册及逐项分析如下:

        【1】Camera模组参数从设备地址0X62/3,非开发板指出的0x78/0x79

         gc0329芯片支持I2C接口控制信号设计如下:

         PWDN 与 RESET 均是异步设计,生效时不需要 MCLK pin 有时钟提供。PWDN 高有效,Low -> 正常工作,High -> 省电模式;RESET 低有效,Low -> reset 芯片,High -> 正常工作

        设帧同步信号 Vsync 低有效,行同步 Hsync 为高有效,而图像输出格式为 YCbCr 或 RGB565。例如我们在LCD显示图像时,图片转换工具了设置16位真彩的RGB565格式一样。

         GC0329 采用逐行扫描的方式将阵列产生的信号依次输入到模拟信号处理模块中。最开始的
行为 0 行。在默认寄存器设置下,Sensor 的阵列数据输出顺序为从下到上,从左到右。图像扫描的方式输出设置地址为0X17。
        【2】模拟转换地址(analog PWC)0XFC,将寄存器 0xfc[0]置 1,0xf0 写为 0x00。此方式同样降低功耗,输出 pin 高阻,寄存器值保持不变。此时寄存器是可以读写的。要恢复 normal 工作模式,需要将 0xfc[0]置 0,0xf0 写为 0xff。芯片内部寄存器复位默认值有两种方式:1) RESET pin 接入低电平;2) 将寄存器 0xfe[7]置 1。      

        更多输出使能控制。

VSync output enable  0xf0[0]         控制 VSYNC pin 输出0 –> VSYNC pin 高阻1 –> VSYNC pin 正常输出HSync output enable  0xf0[1]         控制 HSYNC pin 输出0 –> HSYNC pin 高阻1 –> HSYNC pin 正常输出PCLK output enable  0xf0[2]         控制 PCLK pin 输出0 –> PCLK pin 高阻1 –> PCLK pin 正常输出Pixel data[7:0] output enable 0xf0[3]   控制 data pin 输出0 –> data pin 高阻1 –> data pin 正常输出

        寄存器相关信息,设备ID存储地址为0X00。page 选择由 P0:0xfe[1:0]设置,设为 0x00 表示page0,设为 0x01 表示 page1 。

        【3】输出PIN驱动能力,PCLK PIN 、Data PIN、SYNC PIN的设置

         【4】时钟预分频,外部 MCLK 时钟输入后,通过 clock divider 模块对 MCLK 进行分频,芯片内部工作频率基于分频后的频率。

         【5】同步模式设置,VSYNC 为场同步信号,HSYNC 为行同步信号,PCLK 为输出 data 的同步时钟,可以通过寄存器0X46来控制这三个信号的极性。

         【6】GC0329 可以截取任意尺寸(≤VGA)的窗口输出,且有两种模式实现窗口输出,这两种模式输出小于 VGA 窗口时,视角均会变小。

         Windowing 模式,用 column start 和 row start 来分别确定要挖窗口起始的 X/Y 坐标,用 window width-8 和 window height-8(注意寄存器设置要比实际输出多 8)来确定所需要窗口的宽度和高度。

        Crop window 模式,用 Out window x0 和 Out window y0 来分别确定要挖窗口
起始的 X/Y 坐标,用 Out window width 和 Out window height 来确定所需要窗口的宽度和
高度。

        subsample 模式,如果要实现视角不变输出 QVGA/QQVGA/CIF/QCIF等窗口,需要用到 subsample 模式,在 windowing(0x09-0x10 寄存器)确定好图像窗口尺寸后,采用抽点的
方式输出更小尺寸的数据,最终输出图像尺寸的行/列可以为设定窗口行/列的 1/2, 1/3, 1/4,
1/5, 1/6, 1/7(表示行为原始尺寸的 1/7,列也为原始尺寸的 1/7),同时也能实现 3/5,2/3,
4/7 等采样率。例如下图设置示例(P0:0x5a 表示 0x5a 寄存器是 page0 的)。

         【7】在 GC0329 中,消除灯管频率导致的 flicker 问题,需要同时配置 exposure step register(P1:0x03,P1;0x04)Hb({P0:0x05,P0:0x06}),Vb({P0:0x07,P0:0x08}),exp_level(P1:0x2b~0x32)来实现。消除 flicker 的原理即是曝光时间是灯管周期的整数倍。
计算方法为: step * row_time = N * T。

         可以配置 4 档 Exp_level,用户可以通过修改 P1:0x33[5:4]来设置用哪一档 exp_level(范围为 0-3),设置完成后,AEC 最大曝光时间只能达到 exp_level 所设定的值,从而达到控制帧率的目的。Exp_level 的配置只要用是所计算出来的 step 的整数倍即可,可按照想要的帧率配置,每个 level 需要配两个寄存器,如 0xe4[3:0]为高位,0xe5 为低位。

         【8】输出模式设置

        YUV/RGB565 输出设置及RawRGB 输出设置:

         自动曝光控制(Auto Exposure Control)设置

Function           Address         Value     Description
AEC enable         P0:0x4f[0]      1’b0      使能 AEC 模块
Target Y           P1:0x13         0x50      AEC 目标亮度值
AEC action period  P1:0x11[6:4]    2’b3      AEC 每隔几帧调一次
Exp level          P1:0x2b-0x32    --        配置曝光等级,具体见 4.6.2
Max exp level      P1:0x33[5:4]    --        选择曝光等级 0~3 中的一档
Exp min            P1:0x34         0x04      设置 AEC 自动调节的最小值
Auto pre gain      P0:0x71         --        AEC 使能时,为只读。
Auto post gain     P0:0x72         --        AEC 不使能时,可读写。
Pre gain limit     P1:0x22         0x40      Auto_pre_gain 的最大值。
Post gain limit    P1:0x21         0x80      Auto_post_gain 的最大值。

         自动白平衡(Auto White Balance)设置

Function         Address         Value         Description
AWB enable       P0:0x42[1]      1’b0          使能 AWB 模块
AWB_R_gain       P0:0x77         --            AWB 使能时,为只读。AWB 不使能时,可读写。
AWB_G_gain       P0:0x78         --
AWB_B_gain       P0:0x79         --
AWB_R_gain_limit P1:0x67         0x80          AWB 中 R 通道的增益限制
AWB_G_gain_limit P1:0x68         0x80          AWB 中 G 通道的增益限制
AWB_B_gain_limit P1:0x69         0x80          AWB 中 B 通道的增益限制
AWB action period P1: 0x5d[5:4]  1’b0          AWB 每隔几帧调一次。
R_ratio          P0:0x7a         0x80         做完 AWB 后 R 通道所乘的增益,0x80 为 1 倍增益。
G_ratio          P0:0x7b         0x80         做完 AWB 后 R 通道所乘的增益,0x80 为 1 倍增益。
B_ratio          P0:0x7c         0x80         做完 AWB 后 B 通道所乘的增益,0x80 为 1 倍增益。

        以及镜头阴影补偿(Lens Shading Compensation)、去坏点(Delete defective points)、去噪(Denoise)、边缘加强(Edge Enhancement)、饱和度、对比度、特效参数、Gamma 调整、色彩矩阵(Color Matrix)等摄像头图像输出相关设置就不逐一列举。

  2.程序代码设计

        【1】伪代码实现设计

从机地址:0X62/0X63
Init
拉低CAM_PD,拉高CAM_RST
向 0xfe 写入 设置值
向 0xfc 写入 设置值
向 0x00 读取 CHIPID 验证是否==0XC0
进行 摄像头参数设置:
(analog、blk、ISP、DNDD、INTPEE、ASDE、RGB-gamma、Y-gamma、YCP、AEC、ABS、AWB、LSC、flicker、输出等)
进行 LCD显示输出配置(VGA-DCMI)
启动DCMI抓取数据及写入DMA刷新显示
DCMI回调,调用LCD显示函数进行屏幕刷新显示

        【2】依据上述分析及伪代码设计,给出camera.h和camera.c源码

#ifndef __GC0329_H
#define __GC0329_H
#include "main.h"
#include "dcmi.h"
#include "i2c.h"
#include "gpio.h"
#include "../oled/oled.h"#define  GC0329_I2CADDR 0X62
#define  GC0329_ID    	0xC0
#define  GC0329_CHIPID  0x00/* GC0329 Registers definition */
#define GC0329_SENSOR_PIDH              0x00
#define GC0329_SENSOR_PIDL              0x0B
#define GC0329_SENSOR_COM7              0x12
#define GC0329_SENSOR_TSLB              0x3A
#define GC0329_SENSOR_MTX1              0x4F
#define GC0329_SENSOR_MTX2              0x50
#define GC0329_SENSOR_MTX3              0x51
#define GC0329_SENSOR_MTX4              0x52
#define GC0329_SENSOR_MTX5              0x53
#define GC0329_SENSOR_MTX6              0x54
#define GC0329_SENSOR_BRTN              0x55
#define GC0329_SENSOR_CNST1             0x56
#define GC0329_SENSOR_CNST2             0x57/*** @brief  GC0329 Features Parameters*/
#define GC0329_BRIGHTNESS_LEVEL0        0xB0     /* Brightness level -2         */
#define GC0329_BRIGHTNESS_LEVEL1        0x98     /* Brightness level -1         */
#define GC0329_BRIGHTNESS_LEVEL2        0x00     /* Brightness level 0          */
#define GC0329_BRIGHTNESS_LEVEL3        0x18     /* Brightness level +1         */
#define GC0329_BRIGHTNESS_LEVEL4        0x30     /* Brightness level +2         */#define GC0329_BLACK_WHITE_BW           0xCC000000000000  /* Black and white effect      */
#define GC0329_BLACK_WHITE_NEGATIVE     0xEC808000008080  /* Negative effect             */
#define GC0329_BLACK_WHITE_BW_NEGATIVE  0xEC000000000000  /* BW and Negative effect      */
#define GC0329_BLACK_WHITE_NORMAL       0xCC808000008080  /* Normal effect               */#define GC0329_CONTRAST_LEVEL0          0x30     /* Contrast level -2           */
#define GC0329_CONTRAST_LEVEL1          0x38     /* Contrast level -1           */
#define GC0329_CONTRAST_LEVEL2          0x40     /* Contrast level 0            */
#define GC0329_CONTRAST_LEVEL3          0x50     /* Contrast level +1           */
#define GC0329_CONTRAST_LEVEL4          0x60     /* Contrast level +2           */#define GC0329_COLOR_EFFECT_NONE        0xCC808000008080  /* No color effect             */
#define GC0329_COLOR_EFFECT_ANTIQUE     0xCC000020F00000  /* Antique effect              */
#define GC0329_COLOR_EFFECT_BLUE        0xCC000000000060  /* Blue effect                 */
#define GC0329_COLOR_EFFECT_GREEN       0xCC000000008000  /* Green effect                */
#define GC0329_COLOR_EFFECT_RED         0xCC600000000000  /* Red effect                  */#define CAMERA_R160x120                 0x00   /* QQVGA Resolution                     */
#define CAMERA_R320x240                 0x01   /* QVGA Resolution                      */
#define CAMERA_R480x272                 0x02   /* 480x272 Resolution                   */
#define CAMERA_R640x480                 0x03   /* VGA Resolution                       */#define CAMERA_CONTRAST_BRIGHTNESS      0x00   /* Camera contrast brightness features  */
#define CAMERA_BLACK_WHITE              0x01   /* Camera black white feature           */
#define CAMERA_COLOR_EFFECT             0x03   /* Camera color effect feature          */#define CAMERA_BRIGHTNESS_LEVEL0        0x00   /* Brightness level -2         */
#define CAMERA_BRIGHTNESS_LEVEL1        0x01   /* Brightness level -1         */
#define CAMERA_BRIGHTNESS_LEVEL2        0x02   /* Brightness level 0          */
#define CAMERA_BRIGHTNESS_LEVEL3        0x03   /* Brightness level +1         */
#define CAMERA_BRIGHTNESS_LEVEL4        0x04   /* Brightness level +2         */#define CAMERA_CONTRAST_LEVEL0          0x05   /* Contrast level -2           */
#define CAMERA_CONTRAST_LEVEL1          0x06   /* Contrast level -1           */
#define CAMERA_CONTRAST_LEVEL2          0x07   /* Contrast level  0           */
#define CAMERA_CONTRAST_LEVEL3          0x08   /* Contrast level +1           */
#define CAMERA_CONTRAST_LEVEL4          0x09   /* Contrast level +2           */#define CAMERA_BLACK_WHITE_BW           0x00   /* Black and white effect      */
#define CAMERA_BLACK_WHITE_NEGATIVE     0x01   /* Negative effect             */
#define CAMERA_BLACK_WHITE_BW_NEGATIVE  0x02   /* BW and Negative effect      */
#define CAMERA_BLACK_WHITE_NORMAL       0x03   /* Normal effect               */#define CAMERA_COLOR_EFFECT_NONE        0x00   /* No effects                  */
#define CAMERA_COLOR_EFFECT_BLUE        0x01   /* Blue effect                 */
#define CAMERA_COLOR_EFFECT_GREEN       0x02   /* Green effect                */
#define CAMERA_COLOR_EFFECT_RED         0x03   /* Red effect                  */
#define CAMERA_COLOR_EFFECT_ANTIQUE     0x04   /* Antique effect              *//*** @}*/typedef struct
{void     (*Init)(uint16_t, uint32_t);uint16_t (*ReadID)(uint16_t);void     (*Config)(uint16_t, uint32_t, uint32_t, uint32_t);
} CAMERA_DrvTypeDef;//void gc0329_mclk_onoff(int on);
void gc0329_power_onoff(int on);
void gc0329_Init(uint16_t DeviceAddr, uint32_t resolution);
void gc0329_Config(uint16_t DeviceAddr, uint32_t feature, uint32_t value, uint32_t BR_value);
uint16_t gc0329_ReadID(uint16_t dummy);
uint64_t gc0329_ConvertValue(uint32_t feature, uint32_t value);/* CAMERA driver structure */
extern CAMERA_DrvTypeDef   gc0329_drv;
extern DCMI_HandleTypeDef hdcmi;void enable_camera_display(uint8_t on);
void CAMERA_Init(uint32_t Resolution);
void CameraDEMO_Init();
void enable_camera_display(uint8_t on);
int CameraHAL_Capture_Start(uint8_t * buf, uint32_t len, void(*notify)());
#endif //__GC0329_H

        camera.c

#include "camera.h"
#include 
#include extern I2C_HandleTypeDef hi2c3;
CAMERA_DrvTypeDef *camera_drv;
DCMI_HandleTypeDef *phdcmi;
uint16_t *camera_buff = NULL;
static void(*pCapFunc)() = 0;CAMERA_DrvTypeDef   gc0329_drv =
{gc0329_Init,gc0329_ReadID,gc0329_Config,
};/* Initialization sequence for VGA resolution (640x480)*/
const unsigned char GC0329_VGA[][2] =
{{0xfe, 0x80},{0xfc, 0x16},{0xfc, 0x16},{0xfe, 0x00},{0xfa, 0x00},{0x70, 0x48},{0x73, 0x90},{0x74, 0x80},{0x75, 0x80},{0x76, 0x94},  //80 jambo{0x77, 0x62},{0x78, 0x47},{0x79, 0x40},{0x03, 0x02},{0x04, 0x40},analog{0xfc, 0x16},{0x09, 0x00},{0x0a, 0x02},{0x0b, 0x00},{0x0c, 0x02},#ifndef CAMERA_GRAY_MIRROR{0x17, 0x15},  //0x14#endif{0x19, 0x05},{0x1b, 0x24},{0x1c, 0x04},{0x1e, 0x08},{0x1f, 0x08},  //C8{0x20, 0x01},{0x21, 0x48},{0x22, 0xba},{0x23, 0x22},{0x24, 0x16},blkadded for MID{0x26, 0xf4},  //BLK{0x2a, 0x2c},{0x2b, 0x2c},{0x2c, 0x2c},{0x2d, 0x2c},{0x26, 0xf7},  //BLK{0x28, 0x7f},  //BLK limit{0x29, 0x00},{0x32, 0x00},  //04 darkc{0x33, 0x20},  //blk ratio{0x34, 0x20},{0x35, 0x20},{0x36, 0x20},{0x3b, 0x04},  //manual offset{0x3c, 0x04},{0x3d, 0x04},{0x3e, 0x04},ISP BLOCK ENABLE{0x40, 0xff},{0x41, 0x24}, //[5]skin detection{0x42, 0xfa}, //disable ABS{0x46, 0x03},{0x4b, 0xca},{0x4d, 0x01},{0x4f, 0x01},{0x70, 0x48},DNDD{0x80, 0x07},  // 0xe7 20140915{0x81, 0xc2},  // 0x22 20140915{0x82, 0x90},  //DN auto DNDD DEC DNDD //0e //55 jambo{0x83, 0x05},{0x87, 0x40},  // 0x4a  20140915INTPEE{0x90, 0x8c},  //ac{0x92, 0x05},{0x94, 0x05},{0x95, 0x45},  //0x44{0x96, 0x88},ASDE{0xfe, 0x01},{0x18, 0x22},{0xfe, 0x00},{0x9c, 0x0a},{0xa0, 0xaf},{0xa2, 0xff},{0xa4, 0x30},  //50 jambo{0xa5, 0x31},{0xa7, 0x35},RGB gamma{0xfe, 0x00},{0xbf, 0x0b},{0xc0, 0x1d},{0xc1, 0x33},{0xc2, 0x49},{0xc3, 0x5d},{0xc4, 0x6e},{0xc5, 0x7c},{0xc6, 0x99},{0xc7, 0xaf},{0xc8, 0xc2},{0xc9, 0xd0},{0xca, 0xda},{0xcb, 0xe2},{0xcc, 0xe7},{0xcd, 0xf0},{0xce, 0xf7},{0xcf, 0xff},Y gamma{0xfe, 0x00},{0x63, 0x00},{0x64, 0x06},{0x65, 0x0d},{0x66, 0x1b},{0x67, 0x2b},{0x68, 0x3d},{0x69, 0x50},{0x6a, 0x60},{0x6b, 0x80},{0x6c, 0xa0},{0x6d, 0xc0},{0x6e, 0xe0},{0x6f, 0xff},//CC///#if 1 //main{0xfe, 0x00},{0xb3, 0x44},{0xb4, 0xfd},{0xb5, 0x02},{0xb6, 0xfa},{0xb7, 0x48},{0xb8, 0xf0},#else //sub{0xfe, 0x00},{0xb3, 0x42}, //40{0xb4, 0xff}, //00{0xb5, 0x06}, //06{0xb6, 0xf0}, //00{0xb7, 0x44}, //40{0xb8, 0xf0}, //00#endif// crop{0x50, 0x01},YCP{0xfe, 0x00},{0xd0, 0x40},{0xd1, 0x28},{0xd2, 0x28},{0xd3, 0x40},  //cont 0x40{0xd5, 0x00},{0xdd, 0x14},{0xde, 0x34},AEC{0xfe, 0x01},{0x10, 0x40},  // before Gamma{0x11, 0x21},  //{0x12, 0x13},	// center weight *2{0x13, 0x50},  //4 //4}, // AE Target#ifdef CAMERA_GRAY_MIRROR{0x17, 0xa9},	//88, 08, c8, a8#else{0x17, 0xa8},	//88, 08, c8, a8#endif{0x1a, 0x21},{0x20, 0x31},	//AEC stop margin{0x21, 0xc0},{0x22, 0x60},{0x3c, 0x50},{0x3d, 0x40},{0x3e, 0x45},  //read 3f for status//main{0xfe, 0x01},{0x06, 0x12},{0x07, 0x06},{0x08, 0x9c},{0x09, 0xee},{0x50, 0xfc},{0x51, 0x28},{0x52, 0x10},{0x53, 0x20},{0x54, 0x12},{0x55, 0x16},{0x56, 0x30},{0x58, 0x60},{0x59, 0x08},{0x5a, 0x02},{0x5b, 0x63},{0x5c, 0x35},{0x5d, 0x72},{0x5e, 0x11},{0x5f, 0x40},{0x60, 0x40},{0x61, 0xc8},{0x62, 0xa0},{0x63, 0x40},{0x64, 0x50},{0x65, 0x98},{0x66, 0xfa},{0x67, 0x80},{0x68, 0x60},{0x69, 0x90},{0x6a, 0x40},{0x6b, 0x39},{0x6c, 0x30},{0x6d, 0x60},{0x6e, 0x41},{0x70, 0x10},{0x71, 0x00},{0x72, 0x10},{0x73, 0x40},{0x80, 0x60},{0x81, 0x50},{0x82, 0x42},{0x83, 0x40},{0x84, 0x40},{0x85, 0x40},{0x74, 0x40},{0x75, 0x58},{0x76, 0x24},{0x77, 0x40},{0x78, 0x20},{0x79, 0x60},{0x7a, 0x58},{0x7b, 0x20},{0x7c, 0x30},{0x7d, 0x35},{0x7e, 0x10},{0x7f, 0x08},///ABS///{0x9c, 0x00},{0x9e, 0xc0},{0x9f, 0x40},CC-AWB{0xd0, 0x00},{0xd2, 0x2c},{0xd3, 0x80},///LSC //{0xfe, 0x01},{0xc0, 0x0b},{0xc1, 0x07},{0xc2, 0x05},{0xc6, 0x0b},{0xc7, 0x07},{0xc8, 0x05},{0xba, 0x39},{0xbb, 0x24},{0xbc, 0x23},{0xb4, 0x39},{0xb5, 0x24},{0xb6, 0x23},{0xc3, 0x00},{0xc4, 0x00},{0xc5, 0x00},{0xc9, 0x00},{0xca, 0x00},{0xcb, 0x00},{0xbd, 0x2b},{0xbe, 0x00},{0xbf, 0x00},{0xb7, 0x09},{0xb8, 0x00},{0xb9, 0x00},{0xa8, 0x31},{0xa9, 0x23},{0xaa, 0x20},{0xab, 0x31},{0xac, 0x23},{0xad, 0x20},{0xae, 0x31},{0xaf, 0x23},{0xb0, 0x20},{0xb1, 0x31},{0xb2, 0x23},{0xb3, 0x20},{0xa4, 0x00},{0xa5, 0x00},{0xa6, 0x00},{0xa7, 0x00},{0xa1, 0x3c},{0xa2, 0x50},{0xfe, 0x00},flicker ///{0x05, 0x02},{0x06, 0x2c},{0x07, 0x00},{0x08, 0xb8},{0xfe, 0x01},{0x29, 0x00},	//anti-flicker step [11:8]{0x2a, 0x60},	//anti-flicker step [7:0]{0x2b, 0x02},	//exp level 0  14.28fps{0x2c, 0xa0},{0x2d, 0x03},	//exp level 1  12.50fps{0x2e, 0x00},{0x2f, 0x03},	//exp level 2  10.00fps{0x30, 0xc0},{0x31, 0x05},	//exp level 3  7.14fps{0x32, 0x40},{0x33, 0x20},{0xfe, 0x00},out ///#ifdef CAMERA_GRAY_MIRROR{0x44, 0xB1},#else{0x44, 0xA6},#endif{0xf0, 0x07},{0xf1, 0x01},
};/* Initialization sequence for QVGA resolution (320x240) */
const unsigned char GC0329_QVGA[][2] =
{{0xff, 0xff},
};/* Initialization sequence for QQVGA resolution (160x120) */
const char GC0329_QQVGA[][2] =
{{0xff, 0xff},
};//void gc0329_mclk_onoff(int on)
//{
//    RCC_OscInitTypeDef RCC_OscInitStruct;
//
//    /*xiehj add RCC_OSCILLATORTYPE_HSI48*/
//    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
//
//    /*xiehj add*/
//    if(on)
//        RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
//    else
//        RCC_OscInitStruct.HSI48State = RCC_HSI48_OFF;
//
//    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
//    {
//
//    }
//}void gc0329_power_onoff(int on)
{if(1 == on){HAL_GPIO_WritePin(CAM_PD_GPIO_Port, CAM_PD_Pin, GPIO_PIN_RESET);HAL_Delay(10);HAL_GPIO_WritePin(CAM_RST_GPIO_Port, CAM_RST_Pin, GPIO_PIN_RESET);HAL_Delay(50);HAL_GPIO_WritePin(CAM_RST_GPIO_Port, CAM_RST_Pin, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(CAM_RST_GPIO_Port, CAM_RST_Pin, GPIO_PIN_RESET);HAL_Delay(50);HAL_GPIO_WritePin(CAM_PD_GPIO_Port, CAM_PD_Pin, GPIO_PIN_SET);}
}uint8_t CAMERA_IO_Read(uint8_t DevAddr, uint8_t Reg)
{uint8_t read_value = 0;HAL_StatusTypeDef i2c3_status = 0X00;
//    i2c3_status = HAL_I2C_Mem_Read_IT(&hi2c3, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&read_value, 1);i2c3_status = HAL_I2C_Mem_Read(&hi2c3, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&read_value, 1, 1000);if(HAL_OK != i2c3_status){printf("[1]CAMERA_IO_Read error HAL_StatusTypeDef(0x%02x) ErrorCode(%lu) State(%u) \r\n",i2c3_status,hi2c3.ErrorCode,hi2c3.State);return read_value ;}return read_value;
}uint8_t CAMERA_IO_Write(uint8_t DevAddr, uint8_t Reg, uint8_t Value)
{HAL_StatusTypeDef i2c3_status = 0X00;
//	i2c3_status = HAL_I2C_Mem_Write_IT(&hi2c3, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&Value, 1);i2c3_status = HAL_I2C_Mem_Write(&hi2c3, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&Value, 1, 1000);if(HAL_OK != i2c3_status){printf("1)CAMERA_IO_Write error HAL_StatusTypeDef(0x%02x) hi2c3.ErrorCode(%lu) hi2c3.State(%u)\r\n",i2c3_status,hi2c3.ErrorCode,hi2c3.State);return  HAL_ERROR;}return HAL_OK ;
}uint16_t gc0329_ReadID(uint16_t dummy)
{  /* Get the camera ID */// CAMERA_IO_Write(0xfe, 0x00);
//  CAMERA_IO_Write(GC0329_I2CADDR,0xfe, 0x48);CAMERA_IO_Write(GC0329_I2CADDR,0xfc, 0x16);return (CAMERA_IO_Read(GC0329_I2CADDR, GC0329_CHIPID));
}void gc0329_Init(uint16_t DeviceAddr, uint32_t resolution)
{uint32_t index;/* Initialize GC0329 */switch (resolution){case CAMERA_R160x120:{for(index = 0; index < (sizeof(GC0329_QQVGA) / 2); index++){CAMERA_IO_Write(DeviceAddr, GC0329_QQVGA[index][0], GC0329_QQVGA[index][1]);HAL_Delay(2);}break;}case CAMERA_R320x240:{for(index = 0; index < (sizeof(GC0329_QVGA) / 2); index++){CAMERA_IO_Write(DeviceAddr, GC0329_QVGA[index][0], GC0329_QVGA[index][1]);HAL_Delay(2);}break;}case CAMERA_R480x272:{/* Not supported resolution */break;}case CAMERA_R640x480:{for(index = 0; index < (sizeof(GC0329_VGA) / 2); index++){CAMERA_IO_Write(DeviceAddr, GC0329_VGA[index][0], GC0329_VGA[index][1]);HAL_Delay(2);}break;}default:{break;}}
}void gc0329_Config(uint16_t DeviceAddr, uint32_t feature, uint32_t value, uint32_t brightness_value)
{/* Convert the input value into gc0329 parameters */gc0329_ConvertValue(feature, value);gc0329_ConvertValue(CAMERA_CONTRAST_BRIGHTNESS, brightness_value);
}uint64_t gc0329_ConvertValue(uint32_t feature, uint32_t value)
{
//    uint64_t ret = 0;return 0;#if 0switch(feature){case CAMERA_BLACK_WHITE:{switch(value){case CAMERA_BLACK_WHITE_BW:{ret =  GC0329_BLACK_WHITE_BW;break;}case CAMERA_BLACK_WHITE_NEGATIVE:{ret =  GC0329_BLACK_WHITE_NEGATIVE;break;}case CAMERA_BLACK_WHITE_BW_NEGATIVE:{ret =  GC0329_BLACK_WHITE_BW_NEGATIVE;break;}case CAMERA_BLACK_WHITE_NORMAL:{ret =  GC0329_BLACK_WHITE_NORMAL;break;}default:{ret =  GC0329_BLACK_WHITE_NORMAL;break;}}break;}case CAMERA_CONTRAST_BRIGHTNESS:{switch(value){case CAMERA_BRIGHTNESS_LEVEL0:{ret =  GC0329_BRIGHTNESS_LEVEL0;break;}case CAMERA_BRIGHTNESS_LEVEL1:{ret =  GC0329_BRIGHTNESS_LEVEL1;break;}case CAMERA_BRIGHTNESS_LEVEL2:{ret =  GC0329_BRIGHTNESS_LEVEL2;break;}case CAMERA_BRIGHTNESS_LEVEL3:{ret =  GC0329_BRIGHTNESS_LEVEL3;break;}case CAMERA_BRIGHTNESS_LEVEL4:{ret =  GC0329_BRIGHTNESS_LEVEL4;break;}case CAMERA_CONTRAST_LEVEL0:{ret =  GC0329_CONTRAST_LEVEL0;break;}case CAMERA_CONTRAST_LEVEL1:{ret =  GC0329_CONTRAST_LEVEL1;break;}case CAMERA_CONTRAST_LEVEL2:{ret =  GC0329_CONTRAST_LEVEL2;break;}case CAMERA_CONTRAST_LEVEL3:{ret =  GC0329_CONTRAST_LEVEL3;break;}case CAMERA_CONTRAST_LEVEL4:{ret =  GC0329_CONTRAST_LEVEL4;break;}default:{ret =  GC0329_CONTRAST_LEVEL0;break;}}break;}case CAMERA_COLOR_EFFECT:{switch(value){case CAMERA_COLOR_EFFECT_ANTIQUE:{ret =  GC0329_COLOR_EFFECT_ANTIQUE;break;}case CAMERA_COLOR_EFFECT_BLUE:{ret =  GC0329_COLOR_EFFECT_BLUE;break;}case CAMERA_COLOR_EFFECT_GREEN:{ret =  GC0329_COLOR_EFFECT_GREEN;break;}case CAMERA_COLOR_EFFECT_RED:{ret =  GC0329_COLOR_EFFECT_RED;break;}case CAMERA_COLOR_EFFECT_NONE:default:{ret =  GC0329_COLOR_EFFECT_NONE;break;}}break;default:{ret = 0;break;}}}#endif
//    return ret;
}uint8_t camera_dis_on = 0;void enable_camera_display(uint8_t on)
{camera_dis_on = on;
}void CAMERA_Init(uint32_t Resolution)
{camera_drv = &gc0329_drv;phdcmi = &hdcmi;/* Camera Module Initialization via I2C to the wanted 'Resolution' */if (Resolution == CAMERA_R640x480){/* For 240x240 resolution, the OV9655 sensor is set to QVGA resolution* as OV9655 doesn't supports 240x240  resolution,* then DCMI is configured to output a 240x240 cropped window */camera_drv->Init(GC0329_I2CADDR, CAMERA_R640x480);HAL_DCMI_ConfigCROP(phdcmi,150,                 /* Crop in the middle of the VGA picture */120,                 /* Same height (same number of lines: no need to crop vertically) */(WIDTH * 2) - 1,     /* 2 pixels clock needed to capture one pixel */(HEIGHT * 1) - 1);    /* All 240 lines are captured */HAL_DCMI_EnableCROP(phdcmi);}
}void CameraDEMO_Init()
{uint16_t buff[WIDTH * HEIGHT] = {LCD_DISP_BLUE};camera_buff = buff;
//    camera_dispaly(camera_buff, (WIDTH * HEIGHT));gc0329_power_onoff(1);uint8_t sensor_id = gc0329_ReadID(0);printf("camera sensor_id = 0x%02X\r\n", sensor_id);/* gc0329_power_onoff(0); */if (sensor_id == GC0329_ID){CAMERA_Init(CAMERA_R640x480);/* Wait 1s to let auto-loops in the camera module converge and lead to correct exposure *//* aos_msleep(1000); */HAL_Delay(200);/*##-4- Camera Continuous capture start in QVGA resolution ############################*//* Disable unwanted HSYNC (IT_LINE)/VSYNC interrupts */__HAL_DCMI_DISABLE_IT(phdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC);/* LCD size is 240 x 240 and format is RGB565 i.e. 16 bpp or 2 bytes/pixel.The LCD frame size is therefore 240 * 240 half-words of (240*240)/2 32-bit long words .Since the DMA associated to DCMI IP is configured in  BSP_CAMERA_MspInit() of stm32l496g_discovery_camera.c filewith words alignment, the last parameter of HAL_DCMI_Start_DMA is set to:(ST7789H2_LCD_PIXEL_WIDTH*ST7789H2_LCD_PIXEL_HEIGHT)/2, that is 240 * 240 / 2*/HAL_DCMI_Start_DMA(phdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)camera_buff, (WIDTH * HEIGHT) / 2);/* OnError_Handler(hal_status != HAL_OK); */}
}void GC0329_CAMERA_FrameEventCallback(void)
{if (pCapFunc){pCapFunc();return;}if (camera_dis_on){HAL_DCMI_Suspend(phdcmi);camera_dispaly(camera_buff, (WIDTH * HEIGHT));HAL_DCMI_Start_DMA(phdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)camera_buff, (WIDTH * HEIGHT) / 2);HAL_DCMI_Resume(phdcmi);}
}/*** @brief  Frame event callback* @param  hdcmi: pointer to the DCMI handle* @retval None*/
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{GC0329_CAMERA_FrameEventCallback();
}int CameraHAL_Capture_Config(uint16_t w, uint16_t h)
{HAL_StatusTypeDef hal_status = HAL_OK;if (w > 640 || h > 480) return 0;camera_drv = &gc0329_drv;phdcmi = &hdcmi;gc0329_power_onoff(1);camera_drv->Init(GC0329_I2CADDR, CAMERA_R640x480);HAL_DCMI_ConfigCROP(phdcmi,(640 - w) >> 1,                 /* Crop in the middle of the VGA picture */(480 - h) >> 1,                 /* Same height (same number of lines: no need to crop vertically) */(w * 1) - 1,     /* 2 pixels clock needed to capture one pixel */(w * 1) - 1);    /* All 240 lines are captured */HAL_DCMI_EnableCROP(phdcmi);HAL_Delay(1000);__HAL_DCMI_DISABLE_IT(phdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC);return hal_status == HAL_OK;
}int CameraHAL_Capture_Start(uint8_t * buf, uint32_t len, void(*notify)())
{HAL_StatusTypeDef hal_status = HAL_OK;pCapFunc = notify;if (pCapFunc){hal_status = HAL_DCMI_Start_DMA(phdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)buf, len);}return hal_status == HAL_OK;
}

五、编辑及测试

        【1】在main.c转函数文件中,加入camera.h的引用

/* USER CODE BEGIN Includes */
#include "../../ICore/key/key.h"
#include "../../ICore/led/led.h"
#include "../../ICore/print/print.h"
#include "../../ICore/usart/usart.h"
#include "../../ICore/oled/oled.h"
#include "../../ICore/cam/camera.h"
/* USER CODE END Includes */

        在主函数内调用camera的初始函数

  /* USER CODE BEGIN 2 */ResetPrintInit(&hlpuart1);HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断HLPUSART_RX_STA = 0;//OLED_init();//CameraDEMO_Init();uint8_t flag = 0x00;uint8_t bkflag = 0X00;/* USER CODE END 2 */

        【2】在主函数循环体内,设置通过按键2开启或关闭摄像头抓取数据推送LCD屏幕显示的功能

 /* USER CODE BEGIN WHILE */while (1){if(HLPUSART_RX_STA&0xC000){//溢出或换行,重新开始//设置OLED蓝色背景显示if(!bkflag){BSP_LCD_Clear_DMA(LCD_DISP_BLUE);bkflag = 0x01;}
//		  printf("OLED_Clear_DMA\r\n");//printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);OLED_printf(10,10,"%.*s",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);HLPUSART_RX_STA=0;//接收错误,重新开始HAL_Delay(100);//等待}if(KEY_0()){BSP_LCD_login(24,108);bkflag = 0x00;}if(KEY_1()){BSP_LCD_img_DMA();bkflag = 0x00;}if(KEY_2()){flag = !flag;enable_camera_display(flag);bkflag = 0x00;}/* USER CODE END WHILE */

        【3】在运行按钮下拉选择,进入运行配置界面,新建运行配置,默认配置。

         【4】编译及下载

       【5】 按键2,测试视频显示输出

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...