前段时间做了一块STM32H563的开发板。
· 其实这块板子还设置了其他更多的内容。

有一个板载OV2640接口用以进行图像捕获。

从STM32F407移植摄像头代码,但是一直不能使用。

利用板载DCMI接口使用DMA传输,但是发现DMA数据迟迟没有获取。
于是就开启了漫长的Debug之旅~
最开始怀疑的是硬件问题,因为板子是自己设计的并且是自己手焊的,难免会出现部分地方虚焊的现象。或者因为走线过于抽象导致信号出现问题等等。
但是我后来还制作了一块STM32H5的核心板,利用杜邦线的解法也无法使用,而且用万用表仔细检查过每一个引脚,依旧无法解决问题。

所以暂时初步排除是硬件问题。
于是着重检查代码部分。由于DMA检查起来较为复杂,我们首先通过轮询的方式检查摄像头是否能够工作。
OVMode = OV2640_Init();
if
(OVMode==
0
)
{
OV2640_RGB565_Mode();
OV2640_OutSize_Set(
240
,
240
);
DCMI->IER =
0x0
;
__HAL_DCMI_ENABLE_IT(&hdcmi, DCMI_IT_FRAME);
__HAL_DCMI_ENABLE(&hdcmi);
DCMI->CR |= DCMI_CR_CAPTURE;
// 启动捕获模式
//HAL_DMA_Start(hdcmi.DMA_Handle, (uint32_t)&hdcmi.Instance->DR, (uint32_t)frame_buffer, 240*240);
// HAL_DCMI_Start_DMA(&hdcmi,DCMI_MODE_CONTINUOUS,(uint32_t *)frame_buffer,240*240);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_8,
1
);
}

由于HAL库好像没有不使用DMA启动DCMI的函数,因此,我们查看参考手册,使用寄存器启动DCMI。

在DCMI的控制寄存器部分,第0位是启用捕获。因此只需要让第0位置1即可。
DCMI->CR |= DCMI_CR_CAPTURE; // 启动捕获模式

开启捕获模式之后 ,发现DR即数据寄存器的值有,但是不更新。SR在0,1到3之间跳跃。

查看SR寄存器的定义,大体讲的是VSYNC和HSYNC的状态。这是时钟同步,并没有什么问题、

CR寄存器的值是0x4029

这些对应控制寄存器:使能DCMI,PCKPOL位上升沿使能,JPEG模式使能。以及开启捕获使能。
这些也是没有问题的。
于是也不清楚到底发生了什么事情。
直到突然发现一件事。但是在手册中找到一句重要的话。

开启DCMI的时候,需要确保寄存器配置正常,既然控制寄存器配置是正常的,那么肯定是其他哪里有不正常的地方。

于是把除了CubeMX生成的代码之外的都给删掉。然后就莫名其妙的解决了问题。

不过,随着代码的运行又出现了运行,代码会运行着一会之后,DR的值又不更新了。
我们比较代码,发现RISR的第二位(x=0x1B)出现了异常。查看参考手册关于第二位的描述。

参考手册中描述到:如果这一位置1,则代表着数据FIFO已损坏。通过设置DCMI_ICR寄存器的OVR_ISC位来清除该位。
if
(hdcmi.Instance->RISR &
0x02
)
{
hdcmi.Instance->ICR =
0x02
;
//清除损坏位
}
在代码中添加清楚这一位的代码。
这样子直到一帧捕获完全数据一直在更新。

RIS寄存器中,第0位代表着数据捕获标记位,在ICR的设置,清楚标志位。
if
(hdcmi.Instance->RISR &
0x01
)
{
hdcmi.Instance->ICR =
0x01
;
//清除捕获位
DCMI->CR |= DCMI_CR_CAPTURE;
// 启动捕获模式
}
这样子就实现了轮询式代码实现。这说明我们摄像头是没有问题的,硬件也是没有问题的。启动流程和使用方法出现了问题。
下期再实现DMA的功能和屏幕显示。


登录 或 注册 后才可以进行评论哦!
还没有评论,抢个沙发!