本帖最后由 DEMOK 于 2013-11-4 17:27 编辑
原文附件及程序附件:
更新说明:程序主频部分注释有误,已经更正 在《新手入门摄像头系列》的前几篇中,我们介绍到了OV7620数字摄像头的一些要点和图像处理的基础知识,在这一篇中,DEMOK教您如何用XS128写OV7620的驱动程序,现在开讲。 第一节:XS128如何处理像素中断信号PCLK 我们已经知道,对于OV7620来说,行信号HREF与场信号VSYN的时间比较长,XS12的单片机足以捕捉到;但是OV7620的像素同步信号PCLK只有73ns,而XS12单片机的稳定总线时钟只有25M,很难捕捉到PCLK这个像素同步信号;即使单片机主频倍频到60M以上能够捕捉到73ns的信号,而这其间还有采集这一步,很难做到既采集也判断是否有像素同步。 在以上方案不通的情况下,我们进行了一下论证。然而,我们是否真正的必须捕捉PCLK的信号,读回来的信号才是正确的呢?显然是否定的,对于XS12单片机,即使不用PCLK读回来图像也是正确的。为什么呢?原因是S12单片机的读取速度是有限的,曾经做过实验,在48M主频下,即使当行信号HERF到来的时候,单片机什么也不做,就去读取图像,程序用纯汇编写,而且不用循环判断语句,牺牲空间换取时间来采集,即使是这样,读到有效点数一行也只在450多左右,而OV7620的每行像素输出是640点,这说明单机的读取速度比CMOS的图像输出慢,但是已经可以读取到整行图像数据的大部分数据了。 那么,如果我们一行要读取120点,我们如何来确保隔像素采集平分640个点呢?方法很简单,就是延时,采集一点,延时一会,再采集,平均分为120点,如何去控制延时就得进行实验了,最好借助于示波器。有人会问,采集的这120点之中,难道就没有无效点吗,难道不会采集到PCLK的消隐区吗?不排除这种可能性,但是就算是无效,它能差很多吗?打个比方,采集到的这个点的前一个像素值为70,后一个像素值为78,那么即使采集此点的时候PCLK不是高电平,采集到的值也是在70-78之间;或许大家还有疑问,在黑线的边沿处,如果发生这种情况如何呢?请大家记住,即使在黑线的边沿,COMS的图像输出也不会少于5点,所以这个问题,也不用考虑了。 对于PCLK的具体用处,在用K60或K10采集的时候,就会显现出它的作用,在《新手入门摄像头系列》的后续篇章中,会介绍到。 另外,对于S12单片机,如果真的想捕捉到TCLK信号,也是可以的,必需地PCLK作一定的处理。通过写SCCB对PCLK分频,将PCLK降为微秒级就可以,基于SCCB的分频,DEMOK也做了实验,后续会在论坛逐一发布。 第二节:XS128如何采集每一行的图像像素 在第一节已经提到一个实验,就是不通过PCLK的同步,在行中断来临以后IO口不停地去读图像数据,这里有很多种实现方法。 第一种就是大家习惯用到的for循环,示例伪代码如下:
- interrupt 8 void HREF_Count(void) //行中断函数
- {
- TFLG1_C0F = 1; //清除中断标志
- for( i=0; i<列数; i++)
- ImageData[当前行数][i] = PORTA; //PORTA接摄像头数据口
- 当前行数++;
- }
复制代码
以上程序,在触发一个行中断信号以后,用for循环采集IO口的数据,从逻辑角度讲,实现了将此时IO口上的图像数据保存在图像数组的作用;但是从应用角度讲,这种方法是不可取的。 其实大家可以分析上面的程序,可以去掉不少东西,上面至少执行了以下代码,i的自加,i的比较,Image的寻址,还有每次一个for循环的程序指针的跳转等,这些都是需要时间去完成的,事实上在48M主频下,用for循环去读取一行的像素数据,只能读取几十个点,远远不能达到要求。或许大家会想到提到系统总线频率,以此来增大采集的点数,然后系统的总线频率经过倍频以后,会大大降低系统的稳定性,此法也是不可取的。 通过上面的分析,我们知道用for循环的方法,不可能提高采集的点数,提高CPU的频率将使系统变得不稳定,下面就用空间换取时间的做法去采集通过实验发现,在24M总线频率的前提下,我们用以下方法去采集,每行采集120个点足以将全行像素平分。
- interrupt 8 void HREF_Count(void) //行中断函数
- {
- TFLG1_C0F = 1; //清除中断标志
- Image_Data[Line_C][0] = PORTA;
- Image_Data[Line_C][1] = PORTA;
- Image_Data[Line_C][2] = PORTA;
- Image_Data[Line_C][3] = PORTA;
- Image_Data[Line_C][4] = PORTA;
- Image_Data[Line_C][5] = PORTA;
- Image_Data[Line_C][6] = PORTA;
- Image_Data[Line_C][7] = PORTA;
- Image_Data[Line_C][8] = PORTA;
- Image_Data[Line_C][9] = PORTA;
- Image_Data[Line_C][10] = PORTA;
- …….
- …….
- Image_Data[Line_C][110] = PORTA;
- Image_Data[Line_C][111] = PORTA;
- Image_Data[Line_C][112] = PORTA;
- Image_Data[Line_C][113] = PORTA;
- Image_Data[Line_C][114] = PORTA;
- Image_Data[Line_C][115] = PORTA;
- Image_Data[Line_C][116] = PORTA;
- Image_Data[Line_C][117] = PORTA;
- Image_Data[Line_C][118] = PORTA;
- Image_Data[Line_C][119] = PORTA; = PORTA;
- 当前行数++;
- }
复制代码
第三节:XS128如何驱动OV7620 XS128驱动OV7620的流程图非常简单,大家可以直接参考附件中的程序,自行进行研究分析。 OV7620图像采集程序_XS128_v1.3(见附件) 效果图:
第九届智能车摄像头技术交流群 群号:108190422(验证消息:智能车)
第九届智能车光电技术交流群 群号:1132879827(验证消息:智能车) 第九届智能车电磁技术交流群 群号:118404899(验证消息:智能车)
对号入座,欢迎加入!
10.29 新手入门摄像头-第一篇:智能车摄像头上位机的用法 11.14 新手入门摄像头-第二篇:OV7620与OV7670的区别与比较 11.21 新手入门摄像头-第三篇:智能车摄像头基础知识扫盲 11.30 新手入门摄像头-第四篇:OV7620数字摄像头时序剖析 12.30 新手入门摄像头-第五篇:如何使用XS128驱动OV7620 5.08 新手入门摄像头-第六篇:数字摄像头使用常见问题说明-FAQ 5.28 新手入门摄像头-第七篇:智能车循迹程序及手册
|