【cubemx】移植正点原子ov2640

一、前言

        这几天在用cubemx移植ov2640,数据输出到屏幕始终是蓝色的,百思不得其解,终于我找到了个大坑,那就是之前把lcd显示的方向改成了横屏(一定要设置成竖屏!),接下来进入正题,本文想实现的功能为将摄像头的数据显示到屏幕。

图1 LCD方向设置错误

二、前提条件

        如果你能搜到这篇文章,那么就默认你的lcd驱动是正常的,我这里采用FMC驱动屏幕,屏幕和摄像头的代码均从正点原子移植。

三、接线图

        原理图略过,直接看怎么接线。

        注意事项:

        1.3.3V 

        2.OV_SCL和OV_SDA 都用软件IIC驱动

        3.NC表示不用接

        4.其他引脚由cubemx配置

 图2 接线

四、cubemx配置

DCMI的配置参考这位哥的,之后生成工程

ov2640 cubemx配置

五、代码移植

参考正点原子例程,用到了如下驱动。我这边分享一下,大家可以自己去官方下载,可以下载stm32f429阿波罗开发板的资料-->摄像头实验,驱动刚刚更新过,比较规范。

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

ov2640驱动 提取码ov26

下面我来告诉大家需要修改的地方

1.sccb.h 修改这两个引脚,参考看上面原理图 排针3 排针5的位置,自己选择引脚驱动软件IIC

2. main.c USER CODE BEGIN 2的位置 进行ov2640初始化,看看是否初始化成功。

  while (ov2640_init()) /* 初始化OV2640 */
  {
    lcd_show_string(30, 130, 240, 24, 24, "OV2640 ERROR", RED);
    delay_ms(200);
    lcd_fill(30, 130, 239, 170, WHITE);
    delay_ms(200);
    LD2_Toggle;
  }
  lcd_show_string(30, 185, 200, 24, 24, "OV2640 OK", RED);
  ov2640_flash_intctrl(); /* 闪光灯控制 */

烧写!如果屏幕上显示OV2640 OK,则进行下一步。

3. main.c USER CODE BEGIN PV 添加

extern DCMI_HandleTypeDef g_dcmi_handle;

4. cubemx 生成的 dcmi.c USER CODE BEGIN 0

/* USER CODE BEGIN 0 */
#include "./lcd/lcd.h"
#include "./LED/bsp_led.h"
#include "stdio.h"

extern void jpeg_data_process(void);
/* USER CODE END 0 */

5.cubemx 生成的 dcmi.c 31行这里,把hdcmi替换成g_dcmi_handle(替换所有)

6. cubemx 生成的 dcmi.c USER CODE BEGIN 1

/* USER CODE BEGIN 1 */
/**
 * @brief       DCMI,启动传输
 * @param       无
 * @retval      无
 */
void dcmi_start(void)
{
  lcd_set_cursor(0, 0);         /* 设置坐标到原点 */
  lcd_write_ram_prepare();      /* 开始写入GRAM */
  __HAL_DMA_ENABLE(&hdma_dcmi); /* 使能DMA */
  DCMI->CR |= DCMI_CR_CAPTURE;  /* DCMI捕获使能 */
}

/**
 * @brief       DCMI中断回调服务函数
 * @param       g_dcmi_handle:DCMI句柄
 * @note        捕获到一帧图像处理
 * @retval      无
 */
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
	if(DCMI == hdcmi->Instance)
	{
		__HAL_DCMI_CLEAR_FLAG(&g_dcmi_handle, DCMI_FLAG_FRAMERI); /* 清除帧中断 */
		jpeg_data_process();                                      /* jpeg数据处理 */
		LD2_Toggle;                                               /* LED2闪烁 */
		// g_ov_frame++;

		/* 重新使能帧中断,因为HAL_DCMI_IRQHandler()函数会关闭帧中断 */
		__HAL_DCMI_ENABLE_IT(&g_dcmi_handle, DCMI_IT_FRAME);
	}
}

/* USER CODE END 1 */

7. main.c USER CODE BEGIN 0添加这两个函数

**
 * @brief     处理JPEG数据
 * @note      在DCMI_IRQHandler中断服务函数里面被调用
 *            RGB565模式只有下面这两句
 * @param     无
 * @retval    无
 */
void jpeg_data_process(void)
{
  lcd_set_cursor(0, 0);
  lcd_write_ram_prepare(); /* 开始写入GRAM */
}

/**
 * @brief     RGB565测试
 * @note      RGB数据直接显示在LCD上面
 * @retval    无
 */
void rgb565_test(void)
{
  ov2640_rgb565_mode();                                                                    /* RGB565模式 */
  DCMI->IER = 0x0;
  __HAL_DCMI_ENABLE_IT(&g_dcmi_handle, DCMI_IT_FRAME);        /* 使能帧中断 */
  __HAL_DCMI_ENABLE(&g_dcmi_handle);                          /* 使能DCMI */

  __HAL_DMA_DISABLE_IT(&hdma_dcmi, DMA_IT_TC);                										/* 先关闭DMA传输完成中断,否则在使用MCU屏幕的时候会出现花屏的情况 */
  __HAL_UNLOCK(&hdma_dcmi);
  HAL_DCMI_Start_DMA(&g_dcmi_handle,DCMI_MODE_CONTINUOUS,(uint32_t)&LCD->LCD_RAM,1);        //DCMI启动DMA通道
  HAL_DMA_Start(&hdma_dcmi, (uint32_t)&DCMI->DR, (uint32_t)&LCD->LCD_RAM, 1);
  ov2640_outsize_set(lcddev.width, lcddev.height);                                         /* 满屏缩放显示 */
  dcmi_start();                                                                            /* 启动传输 */
}

8.最后在主函数调用,我这里放在USER CODE END 2前面

 之后就移植完毕了,可以烧写看看运行结果。

六、程序优化

大家可以看到代码移植的第5步,我把cubemx生成的替换了,是因为DCMI的回调函数有个hdcmi参数,会冲突,目前我还不知道如何修改,知道的小伙伴可以在评论区留言......

帧率优化,参考b站的视频,我还没试成功。

stm32提高ov2640帧率

JPEG和帧率的显示大家再参考正点原子代码吧,可以看看b站视频。

正点原子ov2640 HAL库视频

七、结束语

设置竖屏在lcd_init的lcd_display_dir(0),一定要设置成竖屏!!! 

移植有问题的可以在评论区留言。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值