STM32读取OV2640ID始终为0问题

前言

最近在进行一个STM32和OV2640摄像头的项目,在项目最刚开始读取设备ID的初始阶段,读出来的ID始终是0x00,这个问题困扰了我3天,经过不懈努力,终于读出正确的ID号:0x26,在此记录以下我的调试历程。

硬件资源

极客STM32F429IGTB6开发版一块,该模块可以通过usb 5v供电,也可以通过3.3V直接供电,问题其实就出在这里,后面会详细解释,极客OV2640扩展版一块。ov2640通过杜邦线从开发板上供电,开发板通过ST-Link3.3V供电。

bug现象

STM32与OV2640是通过I2C协议进行通信的,最刚开始用的是STM32的硬件IIC去配置和读取OV2640寄存器信息。但是在写命令时,始终卡在EV6也就是这一句上while(!I2C_CheckEvent(CAMERA_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)),后来改为软件模拟IIC,不管主机发送什么,从机都应答0,正常情况下,如果没有这个地址,主机寻址,从机是不会应答的。

解决过程

再三确认我的软件模拟IIC过程是没有问题的,因此问题可能出在OV2640硬件扩展板上,一是扩展版电路问题,二是OV2640本身就坏了,先换了一个OV2640,发现不管用,那扩展版电路问题比较大。
于是查看扩展版电路,这是我的OV2640扩展版电路图
在这里插入图片描述
这个电路很简单,3.3V经过两个降压电路降到2.8V,和1.5V给OV2640供电,再就是一个晶振电路了。最初怀疑晶振坏了或者虚焊等,用电压表的蜂鸣档去量四个角,至少连接是正常的,没有虚焊,电压也正常。
在量电压过程中,突然发现,本应该供电3.3V,这时候只有3.0v左右,突发奇想是不是电压太低了供电不行,于是量了4引脚和10引脚,分别是2.6V,1.1-1.2V,再查OV2640的数据手册找到了如下的电路要求在这里插入图片描述
10号引脚最低电压是1.24,这里的供电电压只有1.1不到1.2,有没有可能是这里电压太低了,导致芯片无法正常启动!
果断换到USB口5V供电,再次读取ID
在这里插入图片描述
已经能正确读出0x26的设备ID了!!,也就是说,问题出在供电电压上。

另外改换成硬件IIC去通信,发现还是卡在EV6那里,这里也证实了STM32 硬件IIC确实有BUG,还是用软件模拟更靠谱一点。

### STM32 使用 OV2640 摄像头驱动配置教程 #### 1. 硬件连接 在使用 STM32 驱动 OV2640 摄像头模块时,硬件连接至关重要。OV2640 的 XCLK 引脚需要连接到 STM32 的 PA8 脚以提供外部时钟信号[^1]。这是因为 OV2640 不带 FIFO 缓冲区,因此需要通过外部时钟来触发其操作。 此外,STM32 的 DCMI 接口负责接收来自 OV2640 的图像数据流[^2]。确保将摄像头的数据线(D0-D7)、PCLK、HREF 和 VSYNC 正确连接至 STM32 对应的 GPIO 或专用功能引脚。 --- #### 2. 初始化 I2C 总线 为了与 OV2640 进行通信,需初始化 STM32 的 I2C 外设。以下是实现代码: ```c #include "stm32f4xx_hal.h" void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; // 设置 I2C 速度为 100kHz hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(&hi2c1); } ``` 此部分代码完成 I2C 的基本设置,允许后续对 OV2640 寄存器进行读写操作[^3]。 --- #### 3. 读取 OV2640 ID 验证摄像头是否正常工作的第一步是读取其芯片 ID。以下是一个简单的函数用于读取 OV2640 的 PID 和 VER 值: ```c uint8_t Read_OV2640_Reg(uint8_t reg_addr) { uint8_t data; HAL_I2C_Mem_Read(&hi2c1, OV2640_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY); return data; } bool Check_OV2640_ID() { uint8_t pid = Read_OV2640_Reg(0x0A); // Product ID (should be 0x26 for OV2640) uint8_t ver = Read_OV2640_Reg(0x0B); // Version number if ((pid == 0x26) && (ver == 0x40)) return true; return false; } ``` 如果 `Check_OV2640_ID()` 返回 `true`,则表明摄像头已成功识别。 --- #### 4. 配置 OV2640 工作模式 OV2640 提供多种分辨率和色彩格式选项。可以通过编写一组寄存器值来设定所需的工作模式。例如,以下代码片段展示了如何切换到 QVGA 分辨率下的 RGB565 输出模式: ```c const uint8_t ov2640_init_qvga_rgb[] = { 0xFF, 0x01, 0x2C, 0xDF, 0x2E, 0xC3, ... }; void Configure_OV2640_QVGA_RGB565() { for(int i=0;i<sizeof(ov2640_init_qvga_rgb)/2;i++) { Write_OV2640_Reg(ov2640_init_qvga_rgb[i*2], ov2640_init_qvga_rgb[i*2+1]); } } void Write_OV2640_Reg(uint8_t reg_addr, uint8_t value) { HAL_I2C_Mem_Write(&hi2c1, OV2640_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &value, 1, HAL_MAX_DELAY); } ``` 调用 `Configure_OV2640_QVGA_RGB565()` 即可完成相应配置[^3]。 --- #### 5. 启用 DCMI 并采集图像 最后一步是启用 STM32 的 DCMI 功能以捕获图像帧。下面是一段简化版的 DCMI 初始化代码: ```c void MX_DCMI_Init(void) { hdcmi.Instance = DCMI; hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME; hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW; hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH; hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING; hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; hdcmi.Init.DataWidth = DCMI_DATAWIDTH_8BITS; HAL_DCMI_Init(&hdcmi); __HAL_RCC_DMA2_CLK_ENABLE(); hdma_dcmi.Instance = DMA2_Stream1; hdma_dcmi.Init.Channel = DMA_CHANNEL_1; hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE; hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE; hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_dcmi.Init.Mode = DMA_CIRCULAR; hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_dcmi); __HAL_LINKDMA(&hdcmi,DMA_Handle,hdma_dcmi); } ``` 以上代码实现了 DCMI 的基础配置以及与其关联的 DMA 数据传输机制。 --- ### 结论 综上所述,要使 STM32 成功驱动 OV2640 摄像头模块,需依次完成硬件连线调整、I2C 初始配置、摄像头 ID 校验、工作模式定制化以及最终的 DCMI/DMA 图像抓取流程。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值