STM32F103C8T6+OV7670(有FIFO和无FIFO版本)入门教程/使用总结(待续写,有问题可发在评论区中)
前言:本文为第一遍草稿,错误会有点多(指技术性的东西会叫错等等,欢迎纠正),有需要可以先看看。OV7670还没有完全弄清楚,目前已成功出图(指测试图像八色彩条和勉强看得过去的实测拍照得到的图像)(有无FIFO的版本都有),计划暑假继续研究并补充本文。
一、器材介绍
器材 |
用途/备注 |
||
开发板 |
STM32F103C8T6 |
/ |
|
摄像头模块 |
OV7670 (带FIFO或不带FIFO版本) |
带FIFO和不带FIFO版本的都测试过了,都会在文中提及 |
|
调试工具 |
OLED |
用于调试,用来打印过程中的变量,这个是非必须的,可以用其它的调试工具 |
|
其他 |
ST-LINK |
仿真器,用于烧录代码 |
|
USB转TTL串口模块 |
将图片数据通过串口上传至电脑的调式软件来显示图像 |
||
扩展坞 |
ST-LINK烧录和串口都需要一个USB接口,电脑USB接口不够的建议入手 |
||
4.7kΩ电阻两个 |
本文选择的SCCB通信修改寄存器的代码书写方式特殊,SCL(SIO_C)和SDA(SIO_D)需要两个外接电阻。 |
||
面包板&若干杜邦线 |
/ |
二、实例
STM32F03C8T6+带FIFO的OV7670实例见:
STM32F103C8T6+带FIFO的OV7670的输出测试图像实例代码_不会游泳的企鹅的博客-CSDN博客
STM32F03C8T6+带FIFO的OV7670实例见:
STM32F103C8T6+无FIFO的OV7670的输出测试图像实例代码_不会游泳的企鹅的博客-CSDN博客
下面对一些已知寄存器的功能稍微进行解释:
/* 设置输出颜色模式,这里设置的是图像输出RGB565 */
OV7670_WriteReg(0x12, 0x14);//QVGA,Bayer Raw
OV7670_WriteReg(0x40, 0x10);//RGB565
OV7670_WriteReg(0x8C, 0x00);//失能RGB444
/* 设置窗口大小(分辨率) */
/* 这里还没有弄清楚,网上还有另外一个版本的解释,建议先去看看,见:http://www.51hei.com/bbs/dpj-92272-1.html */
//H:240=0100 0001 111 - 0010 0011 111 -> 0x17:0x23 0x18:0x41 0x32: 1011 1111 =0xBF
OV7670_WriteReg(0x17, 0x23);
OV7670_WriteReg(0x18, 0x41);
OV7670_WriteReg(0x32, 0xbf);
//V:320=328-8=0101 0010 00 - 0000 0010 00 -> 0x19:0x02 0x1a:0x52 0x03:0x00
OV7670_WriteReg(0x19, 0x02);
OV7670_WriteReg(0x1a, 0x52);
OV7670_WriteReg(0x03, 0x00);
/*设置测试图案输出 这里设置的是输出八色彩条*/
OV7670_WriteReg(0x70, 0x3A);
OV7670_WriteReg(0x71, 0xB5);
/*个人认为,应当是数据手册有误,数据手册里写的是:
(0x70[7],0x71[7])=(1,0)输出的是八色彩条 ×
(0x70[7],0x71[7])=(0,1)输出的是Shifting “1” ×
而实际上是反过来的
(0x70[7],0x71[7])=(1,0)输出的是Shifting “1” ✓
(0x70[7],0x71[7])=(0,1)输出的是八色彩条 ✓
*/
//红蓝通道增益控制(如果输出的图像发蓝或者发红就试着调一下这两个寄存器)
OV7670_WriteReg(0x01, 0x00);//蓝
OV7670_WriteReg(0x02, 0x00);//红
//VS负有效关闭
OV7670_WriteReg(0x15, 0x00);
//网上的一些寄存器设置中有的设置了这个寄存器将VSYNC反相了(也就是原本VSYNC应该输出高电平的地方会变成输出低电平)
//VSYNC反相影响到了时序,
//数据手册中给出的时序是VSYNC反相前的时序,VSYNC为低电平时接收帧图像数据
//如果反向了就会变成VSYNC为高电平时接收图像数据
OV7670_WriteReg(0x11, 0x9F);/* 设置输入时钟分频,这里设置成了32分频 */
OV7670_WriteReg(0x6B, 0x00);/* 设置输入时钟倍频,这里设置成了1倍频 */
三、注意事项
-
SCCB通信
-
SCCB和I2C通信不完全相同!!!写函数可以直接套用I2C的写函数,但是读函数有一些不同。(区别是红色加黑部分,其余都相同)
SCCB通信
SCCB和I2C通信不完全相同!!!写函数可以直接套用I2C的写函数,但是读函数有一些不同。(区别是红色加黑部分,其余都相同)
I2C:
发送开始信号->发送从机地址(写)->接收从机应答->发送寄存器地址->接收从机应答->
发送起始信号->发送从机地址(读)->接收从机应答->接收从机数据->主机发送应答->发送停止信号
SCCB:
发送开始信号->发送从机地址(写)->接收从机应答->发送寄存器地址->接收从机应答->
发送停止信号->
发送起始信号->发送从机地址(读)->接收从机应答->接收从机数据->主机发送应答->发送停止信号
b.从机发送应答,应答位为0说明从机接收数据成功,主机发送应答时实际上应说为:“发送NA”,但一般也是发送高电平,和I2C相同,因此照搬I2C函数时可不修改此处。
-
对于有FIFO的OV7670
(1)已自带12MHz晶振,不需外加时钟输入
(2)因为FIFO是在RCLK低电平时输出数据的,读FIFO时钟-RCLK设置引脚为推挽输出后要拉高,不然会丢失第一个字节的数据
(3)
(4)STM32引脚直接连接到OV7670的WEN,而WEN并不是FIFO的写使能,写使能是WE,从电路图中看,WE=(WEN*HERF)的非(WEN和OV7670的HREF通过与非门得到FIFO的WE)。WE低电平写使能,HREF高电平时有数据输出,而WE=(WEN*HERF)的非,因而要将写控制权给HREF时应时WEN拉高,因此要设置写使能时要拉高WEN。
-
对于无FIFO的OV7670
首先无FIFO的OV7670坑很多,建议直接转有FIFO的OV7670.
(1)无FIFO的OV7670没有自带时钟,因此必须外加时钟输入MCLK才能开始运行。(没有时钟输入SCCB修改寄存器也无法进行)时钟输入可以用MCO时钟输出或者貌似可以用PWM输出(没试过。。。),用MCO输出低速时钟时可能导致STM32系统时钟变慢,影响读取图像的速度。
(2)RST和PWNN正常使用RST接高电平,PWNN接低电平即可。
未完待续。。。