搜索
bottom↓
回复: 13

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

[复制链接]

出0入0汤圆

发表于 2012-4-21 12:43:54 | 显示全部楼层 |阅读模式
本帖最后由 max 于 2012-4-21 13:17 编辑

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

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

然后我想连续采集,使MT9M001工作在连续模式,但这样采集的图片都是不正常的。尝试了一些方法,比如通过帧同步信号,在一帧结束的时候,再判断端点缓冲区空,然后通过中断通道向上位机发信号,上位机收到后再采集图片,这个方法得到的图片还是不正确的。然后又试了在一帧开始的时候发信号,上位机再接收,还是有问题。电路图与关键程序如下,请有熟悉的网友指点一下。谢谢


固件代码

  1. //初始化
  2. void TD_Init(void)             // Called once at startup
  3. {
  4.         // set the CPU clock to 48MHz
  5.         CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1 | bmCLKOE) ;
  6.         SYNCDELAY;

  7.         // set the slave FIFO interface to 48MHz
  8.         IFCONFIG = 0x43;
  9.         SYNCDELAY;
  10.         // configure REVCTL
  11.         REVCTL = 0x03;
  12.         SYNCDELAY;


  13.         Rwuen = TRUE; // Enable remote-wakeup

  14.         // Registers which require a synchronization delay, see section 15.14
  15.         // FIFORESET        FIFOPINPOLAR
  16.         // INPKTEND         OUTPKTEND
  17.         // EPxBCH:L         REVCTL
  18.         // GPIFTCB3         GPIFTCB2
  19.         // GPIFTCB1         GPIFTCB0
  20.         // EPxFIFOPFH:L     EPxAUTOINLENH:L
  21.         // EPxFIFOCFG       EPxGPIFFLGSEL
  22.         // PINFLAGSxx       EPxFIFOIRQ
  23.         // EPxFIFOIE        GPIFIRQ
  24.         // GPIFIE           GPIFADRH:L
  25.         // UDMACRCH:L       EPxGPIFTRIG
  26.         // GPIFTRIG
  27.   
  28.         // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
  29.         //      ...these have been replaced by GPIFTC[B3:B0] registers

  30.         // default: all endpoints have their VALID bit set
  31.         // default: TYPE1 = 1 and TYPE0 = 0 --> BULK  
  32.         // default: EP2 and EP4 DIR bits are 0 (OUT direction)
  33.         // default: EP6 and EP8 DIR bits are 1 (IN direction)
  34.         // default: EP2, EP4, EP6, and EP8 are double buffered

  35.         // configure the OEx registers
  36.         OED = 0xff;
  37.         IOD = 0x80; //1000_0000, RESET=1, others=0
  38.        
  39.         // enable external interrup 0
  40.         PORTACFG |= 1; // enable PA0 as INT0#
  41.         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.
  42.         EX0 = 1;

  43.         //EZUSB_InitI2C(); // Initialize the hardware I2C controller

  44.         //Set CMOS Sensor as Snapshot Mode
  45.         //i2cdata[0] = 0x1e; //address
  46.         //i2cdata[1] = 0x81; //1000_0001
  47.         //i2cdata[2] = 0x00; //0000_0000
  48.     //  EZUSB_WriteI2C(CAM_ADDR, 3, i2cdata);

  49.         // configure varies EndPoints
  50.         EP1OUTCFG = (EP1OUTCFG & 0x7F); // default values...
  51.         SYNCDELAY;                    // see TRM section 15.14
  52.         EP1INCFG = 0xB0;  // default values...en
  53.         SYNCDELAY;                    // see TRM section 15.14
  54.         EP2CFG = 0xE8; // enabled, quad buffered, 1024B, IN, bulk fifo
  55.         SYNCDELAY;                    // see TRM section 15.14
  56.         EP4CFG = (EP4CFG & 0x7F); // disabled...
  57.         SYNCDELAY;                    // see TRM section 15.14
  58.         EP6CFG = (EP6CFG & 0x7F); // disabled, quad buffered, 512B(?), OUT, bulk fifo
  59.         SYNCDELAY;                    // see TRM section 15.14
  60.         EP8CFG = (EP8CFG & 0x7F); // disabled...
  61.         SYNCDELAY;

  62.         // configure the EPxFIFOCFG
  63.         EP2FIFOCFG = 0x08; // autoin, bytewide
  64.         SYNCDELAY;                    // see TRM section 15.14
  65.         SYNCDELAY;  
  66.         EP4FIFOCFG = 0x00;
  67.         SYNCDELAY;           
  68.         SYNCDELAY;         
  69.         EP6FIFOCFG = 0x00; // no-autoOUT, bytewide
  70.         SYNCDELAY;        
  71.         SYNCDELAY;         
  72.         EP8FIFOCFG = 0x00;
  73.         SYNCDELAY;        
  74.         SYNCDELAY;         
  75.        
  76.         FIFOPINPOLAR = 0x0F; // set SLWR, FF & EF active high, others active low
  77.         SYNCDELAY;
  78.   
  79.         EP2AUTOINLENH = 0x04; // EZ-USB automatically commits data in 1024-byte chunks
  80.         SYNCDELAY;
  81.         EP2AUTOINLENL = 0x00;
  82.         SYNCDELAY;

  83.         // enable dual autopointer(s)
  84.         AUTOPTRSETUP |= 0x01;  

  85.         // flaga - pf, flagb - full flag, flagc - empty flag
  86.         //PINFLAGSAB = 0x8a;
  87.         //PINFLAGSCD = 0x08;

  88.                 // reset all fifos
  89.         FIFORESET = 0x80; // reset all FIFOs
  90.         SYNCDELAY;
  91.         FIFORESET = 0x02;
  92.         SYNCDELAY;
  93.         FIFORESET = 0x04;
  94.         SYNCDELAY;
  95.         FIFORESET = 0x06;
  96.         SYNCDELAY;
  97.         FIFORESET = 0x08;
  98.         SYNCDELAY;
  99.         FIFORESET = 0x00;
  100.         SYNCDELAY;
  101. }

  102. //使用帧同步发信号
  103. void external_intr0(void) interrupt INT0_VECT
  104. {
  105.     EP1INBUF[0] = 0;
  106.     EP1INBUF[1] = 0xFF;
  107.     EP1INBUF[2] = 0x88;
  108.     //EP1INBUF[3] = 0;
  109.     //EP1INBUF[4] = 0xFF;
  110.     EP1INBC = 5;
  111. }
复制代码
libusb上位机程序

  1.     unsigned char f_buf[5];
  2.     //接收一帧开始的信号
  3.     r = libusb_interrupt_transfer(devh, EP_INT, f_buf,5, &actual_length, 0);
  4.     if (r < 0) {
  5.         fprintf(stderr, "libusb interrupt transfer fail\n", r);
  6.         goto out;
  7.     }
  8.     if (actual_length == 5 && f_buf[0] == 0 && f_buf[1] == 0xFF && f_buf[2] == 0x88/* && f_buf[3] == 0 && f_buf[4] == 0xFF */) {
  9.         printf("frame header ok.\n");
  10.     }
  11.    
  12.     //开始接收图像数据      
  13.     r = libusb_bulk_transfer(devh, EP_IN, ((struct my_bmp *)(bmp + 2))->data,1310720, &actual_length, 0);
复制代码
得到的图片如下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入442汤圆

发表于 2012-4-21 12:59:46 | 显示全部楼层
什么问题?你不说清楚什么问题,没人能帮得了你!

出0入0汤圆

 楼主| 发表于 2012-4-21 13:14:05 | 显示全部楼层
wye11083 发表于 2012-4-21 12:59
什么问题?你不说清楚什么问题,没人能帮得了你!

不好意思,忘了上传图片了,已经更新到楼顶
就是上位机得到的图片就像分屏似的

出0入442汤圆

发表于 2012-4-21 15:50:07 | 显示全部楼层
有几个原因:第一,你没有在上位机分界。别指望用下位机分界,下位机只会把数据打包好,发给上位机;因此下位机的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启动。

出0入442汤圆

发表于 2012-4-21 16:01:59 | 显示全部楼层
我们一起算算你丢了多少包:

        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中已经填进去数据了!

出0入0汤圆

发表于 2012-4-21 16:50:09 | 显示全部楼层
这个没看到,但是估计 以后有用

出0入0汤圆

 楼主| 发表于 2012-4-21 18:46:40 | 显示全部楼层
本帖最后由 max 于 2012-4-21 18:49 编辑
wye11083 发表于 2012-4-21 15:50
有几个原因:第一,你没有在上位机分界。别指望用下位机分界,下位机只会把数据打包好,发给上位机;因此下 ...


关于分界,由于CMOS输出的尺寸是1024×1280,而我设置的包长度刚好是1024,加上我以为能通过读EP1的信号来判断一帧的开始,然后直接读1024×1280个字节的数据就会是完整一帧的数据。我回头试试设置一个包长度使得一帧最后一个包的长度小于设置的长度,然后通过上位机来分界。

至于FIFO的速度,因为市面上已经有一个相同配置的摄像头能以30FPS的速度输出1024×1280的图片,按照这样算,速度也已经是37.5M了。我试一下使用68013内部的30M时钟先试试看看会不会好些

初始化部分,你这样一说,的确有问题,但我尝试过在每一帧结束的时候复位FIFO,出来的图片还是跟顶楼的一样,从一帧结束到一帧的开始,起码有820us时间,所以,应该可以保证在下一帧到来的时候FIFOBUF里没有数据了吧

谢谢wye11083,我再改一下

出0入442汤圆

发表于 2012-4-21 19:28:49 | 显示全部楼层
mg,我不是跟你说清楚了吗,你在每一帧结束的时候复位FIFO,但是你往EP1里写数据时,这个数据并不会立刻被主机收到!只有上位机收到1024*1280这么多字节数据之后才会去收你的EP1!因此你必须在初始化之前把MT复位,初始化准备接收了再打开MT,这样就不会错位了。

出0入0汤圆

发表于 2012-5-5 11:38:24 | 显示全部楼层
mark 拜读   

出0入0汤圆

发表于 2013-1-28 14:45:39 | 显示全部楼层
MG,现在你的这个问题解决没有?达到1280*1024 30FPS输出吗

出0入0汤圆

发表于 2013-6-4 14:34:46 | 显示全部楼层
学习了,刚开始学习68013,

出0入0汤圆

发表于 2013-6-4 19:06:07 来自手机 | 显示全部楼层
什么都不讲你上位机读的速度太慢

出0入0汤圆

发表于 2013-10-11 21:26:07 | 显示全部楼层
楼主,你好,68013+mt9m001连续采集图像有错这个问题你解决了没,我现在在做这个项目也遇到这个问题,可以的话,指导一下

出0入0汤圆

发表于 2013-10-11 23:15:35 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表