姓名:张猛
引用自:http://blog.csdn.net/u013985662/article/details/45575777
【嵌牛导读】:测试思想,对于自己的东西在使用前一定要确认他是好的,这时候要在用别的设备手段来进行测试,在这个项目为了知道自己画的ov9712相机好不好试,确保这一块没有问题,所以在秉火F429上进行了测试相机,还有在stm32上调试的一些过程以及对一些看着很简单,但是在在实际中做起了坑还比较多的东西的说明与简单的整理。
【嵌牛鼻子】:stm32 ov9712 测试 I2c
【嵌牛提问】:测试思想,对于自己的东西在使用前一定要确认他是好的,这时候要在用别的设备手段来进行测试,在这个项目为了知道自己画的ov9712相机好不好试,确保这一块没有问题,所以在秉火F429上进行了测试
【嵌牛正文】:对于一个陌生的图像传感器,我们应该采取什么样子的步骤来认识它,从而更好地使用它。
1 摄像头配置
用i2c总线往摄像头寄存器中写寄存器;
i2c总线为:一条时钟线,一条数据线,遵循i2c协议来写;
摄像头的sccb接口对应i2c接口;两协议类似;
其中涉及的主要内容是i2c协议读写数据的时序;开始信号、终止信号、设备地址;
写入信号后可以再用i2c读取信号的内容,以确定的确写入了;
用示波器测量摄像头的输入时钟(xclk)、输出像素时钟(pclk)、行同步信号(hs)、场同步信号(vs)、输出数据管脚;如果管脚和预期类似说明摄像头已经开始工作了;
gpio模仿i2c也很简单,就是符合协议的控制电平跳变;
2 摄像头数据读取
单片机的DCMI口对接摄像头的输出口;
摄像头配置的输出时序为数字摄像头时序;
摄像头接口也stm32的DCMI接口对接;
DCMI接口配置时要小心其读取视频数据的中断函数是高电平有效还是低电平有效;
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;//DCMI_VSPolarity_High;
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;//DCMI_HSPolarity_Low;
DCMI中的FIFO缓冲接收到的数据、重组数据;比如摄像头口是8位的,而DCMI的数据寄存器是32位的,FIFO将接受到的八位的数据缓存为32位的;而在液晶上显示的是rgb565的是16位的,在DMA传输时一次传输16为,数据才不会乱;这种情况下DMA传输的源数据宽度为32、目的数据宽度为16位;
DCMI有帧中断、行中断;其中断服务函数都指向DMA传输;
摄像头的原始数据是RGB RAW格式,这个原始数据的排列格式是 RGRG/GBGB排列的,我们叫做 Bayer pattern(这个最最常见)。
3 DMA传输视频数据到显存
DMA是从DCMI的数据寄存器(0x50050028)搬移数据到显存地址(液晶会自动显示该地址的内容);
DCMI中的FIFO缓冲接收到的数据、重组数据;比如摄像头口是8位的,而DCMI的数据寄存器是32位的,FIFO将接受到的八位的数据缓存为32位的;而在液晶上显示的是rgb565的是16位的,在DMA传输时一次传输16为,数据才不会乱;这种情况下DMA传输的源数据宽度为32、目的数据宽度为16位;一次传输16位(一个RGB)可以防止像素乱序;
我们在编程时一般都会明确指定一个传输数量,在完成一次数目传输后DMA_SxNDTR计数值就会自减,当达到零时就说明传输完成。
/*行中断到来时、一行一行将数据传输到显存,行中断来了一定是新一行的数据,FSMC_LCD_ADDRESS + lcd_width*2*line_num保证为液晶屏的新一行的开始地址;一行图像的字节为img_width*2/4;*/
OV2640_DMA_Config(FSMC_LCD_ADDRESS + lcd_width*2*line_num,img_width*2/4); // +(lcd_width*2*(lcd_height-line_num-1))
DCMI_ClearITPendingBit(DCMI_IT_LINE);
///液晶屏的分辨率
uint16_t lcd_width=800, lcd_height=480;
///摄像头采集图像的大小
uint16_t img_width=1280, img_height=800;