[求助]68013+mt9m001连续采集图像有错

2020-01-26 12:57发布

本帖最后由 max 于 2012-4-21 13:17 编辑

没找到USB版,因为68013里有个增强的51,所以就发到51区了

根据本站一位网友的资料,使用68013+MT9M001制作了一个USB摄像头,按照网友的资料制作的是使MT9M001工作在snapshot模式,然后要采集图像的时候,通过USB的控制管道发命令来触发MT9M001采集一帧图片,在这种情况下,采集的图片的正常的。后来我使用libusb重写了上位机,测试时采集30帧使用了3秒时间。

然后我想连续采集,使MT9M001工作在连续模式,但这样采集的图片都是不正常的。尝试了一些方法,比如通过帧同步信号,在一帧结束的时候,再判断端点缓冲区空,然后通过中断通道向上位机发信号,上位机收到后再采集图片,这个方法得到的图片还是不正确的。然后又试了在一帧开始的时候发信号,上位机再接收,还是有问题。电路图与关键程序如下,请有熟悉的网友指点一下。谢谢
1.jpg (114.02 KB, 下载次数: 2) 下载附件 2012-4-21 13:12 上传
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
wye11083
1楼-- · 2020-01-26 16:08
 精彩回答 2  元偷偷看……
max
2楼-- · 2020-01-26 20:05
wye11083 发表于 2012-4-21 12:59
什么问题?你不说清楚什么问题,没人能帮得了你!

不好意思,忘了上传图片了,已经更新到楼顶
就是上位机得到的图片就像分屏似的
wye11083
3楼-- · 2020-01-27 00:23
有几个原因:第一,你没有在上位机分界。别指望用下位机分界,下位机只会把数据打包好,发给上位机;因此下位机的CPU Access可以考虑取消,即不用这个功能,在上位机要做好分界。这个没办法,我会用两个线程,一个就负责收,收到一个包插到链表中,然后另一个线程拼包,发现不满的包就认为是一个分界点,剩下的从下一个包开始拼。再一个,你的FIFO速度太快了吧,48MHz=48MB/s,这个速度除非你拿MAC机子上,否则我可以告诉你,WINDOWS系统最快只能达到40MB左右,而且是保证CPU空闲时。所以,第一,你没有分包,第二,速度跟不上。原理上你的方法是可行的,但是不要忘了USBH只能每次询问一个EP,所以你读EP2的时候就不能读EPIN。Windows还是有时间片的,说不定什么时候就给你卡那了。因此,你中间只要有一个包卡了,那后面的包肯定都乱了
我又看了看你的图和你的程序,你在启动SlaveFIFO之后没有立即开始收数据,反而删了一些数据(RESETFIFO),我认为这是你的最大的问题。你要把MTx的RESET接到PA0,1,3的任意一个管脚上,等上电复位RESETFIFO之后再把这个管脚拉高,这样就能实现同步了。就是说,在TD_Init()的开始让MTx复位,在最后让MTx启动。
wye11083
4楼-- · 2020-01-27 02:52
我们一起算算你丢了多少包:

        REVCTL = 0x03;
        SYNCDELAY;
        Rwuen = TRUE; // Enable remote-wakeup
         OED = 0xff;
        IOD = 0x80; //1000_0000, RESET=1, others=0
         PORTACFG |= 1; // enable PA0 as INT0#
        IT0 = 1; //When ITx = 1, INTx# is edge-sensitive and the EZ-USB sets the IEx flag when the INTx# pin is sampled high then low on consecutive samples.
        EX0 = 1;
        EP1OUTCFG = (EP1OUTCFG & 0x7F); // default values...
        SYNCDELAY;                    // see TRM section 15.14
        EP1INCFG = 0xB0;  // default values...en
        SYNCDELAY;                    // see TRM section 15.14
        EP2CFG = 0xE8; // enabled, quad buffered, 1024B, IN, bulk fifo
        SYNCDELAY;                    // see TRM section 15.14
        EP4CFG = (EP4CFG & 0x7F); // disabled...
        SYNCDELAY;                    // see TRM section 15.14
        EP6CFG = (EP6CFG & 0x7F); // disabled, quad buffered, 512B(?), OUT, bulk fifo
        SYNCDELAY;                    // see TRM section 15.14
        EP8CFG = (EP8CFG & 0x7F); // disabled...
        SYNCDELAY;
        EP2FIFOCFG = 0x08; // autoin, bytewide
        SYNCDELAY;                    // see TRM section 15.14
        SYNCDELAY;  
        EP4FIFOCFG = 0x00;
        SYNCDELAY;           
        SYNCDELAY;         
        EP6FIFOCFG = 0x00; // no-autoOUT, bytewide
        SYNCDELAY;        
        SYNCDELAY;         
        EP8FIFOCFG = 0x00;
        SYNCDELAY;        
        SYNCDELAY;         
        FIFOPINPOLAR = 0x0F; // set SLWR, FF & EF active high, others active low
        SYNCDELAY;
         EP2AUTOINLENH = 0x04; // EZ-USB automatically commits data in 1024-byte chunks
        SYNCDELAY;
        EP2AUTOINLENL = 0x00;
        SYNCDELAY;
       AUTOPTRSETUP |= 0x01;  
        FIFORESET = 0x80; // reset all FIFOs
        SYNCDELAY;
        FIFORESET = 0x02;
        SYNCDELAY;
        FIFORESET = 0x04;
        SYNCDELAY;
        FIFORESET = 0x06;
        SYNCDELAY;
        FIFORESET = 0x08;
        SYNCDELAY;
        FIFORESET = 0x00;
        SYNCDELAY;

一共44条C语句,CPU的指令周期最快12M,因此至少要用4us才能执行完这些指令(注意这只是C,汇编之后更多,估计起码要有60条指令,而且不乏双指令周期指令),因此按最保守的计算,一共需要5us时间。而这5us时间内有多少行数据会跑掉呢?可以算算,48MHz:5us=240。刚好是一个帧空白的长度。我上面分析了,不止60个指令周期,因此在你复位EP2管道时,可能已经有几行数据被弄丢了。因此,你会说,我同步了。我可以这样说,你没去读EP2的时候,EP2的数据你写再多它还在EP2中,根本没有出来!所以实际上你读EP2的时候,后面读的就是下一帧的内容了,然后你再读个EP1,你会发现一下子就返回了。因为EP2中已经填进去数据了!
rlogin
5楼-- · 2020-01-27 08:31
这个没看到,但是估计 以后有用
max
6楼-- · 2020-01-27 13:39
 精彩回答 2  元偷偷看……

一周热门 更多>