اطلاعیه

Collapse
No announcement yet.

پردازش تصویر با FPGA از صفر تا انتها

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    پردازش تصویر با FPGA از صفر تا انتها

    سلام
    قصد دارم در آبنده به اتفاق هم به پیاده سازی پردازش تصویر بر روی FPGA بپردازم.
    قرار هست در ابتدا تصویر رو از یک دوربین دریافت کنیم و سپس اون رو برای نمایش به یک مانیتور یا LCD بفرستیم. FPGA که قرار هست باهاش کار کنیم از خانواده Xilinx هست و قراره که بوردشو خودمون طراحی کنیم. همچنین از دوربین OV7670 استفاده خواهیم کرد که در فروشگاه همین سایت هم موجوده. برای LCD هم از LCD2.8 اینچی که اون هم در فروشگاه سایت موجود هست استفاده می کنیم. برای ارتباط با مانیتور هم یک سوکت VGA بر روی بورد در نظر می گیریم. من قبلا همین دوربین رو با آرم راه انداختم، می دونم که قطعا در این زمینه خیلی بیشتر از من تجربه دارید. همچنین پیش از این برای ال سی دی مذکور هم درایور نوشتم که در این زمینه هم مطلب توی همین سایت زیاد هست هم از من واردتر هستین. اتصال FPGA به مانیتور و نمایش یک گرافیک ساده کاری نداره. پیش از این تجربه اش رو داشتم. ولی انتقال تصویر دوربین به مانیتور قطعا کمی کار داره و مقداری سخته.
    برای شروع سیگنال های دوربین و ال سی دی و غیره رو با هم بررسی می کنیم. در مورد پردازش تصویر و مبانی اون برای پیاده سازی در FPGA هم قدری با هم صحبت می کنیم.

    پیروز و سربلند باشید.

    اضافه شده در تاریخ :
    معمولا هدف از اتصال یک دوربین به FPGA انجام پردازش تصویر هست. البته دوربین های مختلفی وجود دارند که می شه اون ها رو به FPGA وصل کرد. مثلا CMUCAM که هم می شه از طریق پورت سریال بهش دسترسی داشت هم این که می شه مستقیم به پایه هاش دسترسی داشت و دیتا رد و بدل کرد.
    موضوعی که توی این پروژه مد نظرم هست اینه که به طور مستقیم به دوربین دسترسی داشته باشیم نه با واسط دلیلش استفاده از حداکثر سرعت دسترسی هست. می دونم دوربینی که قصد استفاده ازش رو دارم شاید خیلی خیلی خوب نباشه ولی دلیل انتخابش سهولت در تهیه هم از نظر قیمت و هم از نظر دسترسی است همچنین سورس های خوبی هم توی اینترنت در موردش هم با آرم و هم با AVR وجود داره.
    البته بگم که قبلا این دوربین رو با آرم پیاده سازی کردم. ولی موقع پیاده سازی اونقدر به ریز جزییات دقت نکردم که مثلا در زمان فلان سیگنال فلان ارسال می شه و غیره...
    حالا وقتشه که به دقت همه موارد بررسی بشن.


    اضافه شده در تاریخ :
    می خواهم یه دوربین نسبتا خوبی رو هم بهتون معرفی کنم. این دوربین رو با آرم راه انداختم قبلا. اگه بورد های آموزشی FriendlyArm رو داشته باشین برای این دوربین جا در نظر گرفته شده. وقتی وصلش می کنین توی اندروید یا هر OS دیگه ای می تونین تصویر رو بدون هیچ دغدغه ای ببینید. علاوه بر اون می تونین توی همون OS کدی برای پردازش تصویر بزنین بدون این که دغدغه راه اندازی دوربین رو داشته باشین.
    در تصویر زیر نمایی از ماژول دوربین رو مشاهده می کنید. به این ماژول CAM130 می گن.



    نام پایه هاش رو در زیر مشاهده می کنید.



    این دوربین 1.3 مگا پیگسل با رزولوشن 640 در 480 سی فریمی با چیپ OV9650 هست. البته یه جا نوشته 640X480/1280X1024 و 30/15 fps. حالا منظورش نمی دونم نوع دیگه از این دوربین با قابلیت بهتر هست یا این که منظورش این بود که همین دوربین قابلیت سوییچ بین دو حالت کاری رو داره. مطمئن نیستم باید بیشتر بگردم. می دونم اون موقعی که با آرم راهش انداختم توی حالت 640 در 480 ازش استفاده کردم. اون موقع اصلا به این توجه نکردم که حالت دیگه ای هم داره یا نه. می بینم قضیه چیه می گم براتون.
    آدمی از عالم خاکی نمی آید بدست

    عالمی دیگر بباید ساخت و از نو آدمی
    پردازش تصویر با FPGA از صفر تا انتها
    http://www.eca.ir/forum2/index.php?topic=74299.0

    #2
    پاسخ : اتصال دوربین OV9650 به Spartan3

    سلام پویا جان خیلی عالیه ادامه بدید لطفا :applause:
    فقط می تونی یکم در مورد راه اندازی VGA هم صحبت کنی؟
    از خود FPGA استفاده میکنی یا از یک ای سی راه انداز؟
    خداوند جهاد را برای سرافرازی اسلام واجب کرد.
    حضرت فاطمه (س)

    دیدگاه


      #3
      پاسخ : اتصال دوربین OV9650 به Spartan3

      خواهش می کنم دوست عزیز حتما ادامه می دم البته ممکنه یه کمی تا عید نتونم درست و حسابی روش وقت بذارم ولی خوب بعدش حتما ادامه می دم.
      در مورد VGA لازم نیست حتما از یک آی سی رابطه استفاده کنی می تونی با خود FPGA سیگنال ها رو بسازی فقط کافیه قدری به زمان بندی VGA آشنا باشی. در مورد راه اندازی VGA با FPGA نمونه کد خیلی هست هم به Verilog و هم با VHDL. دو تا پایه برای کنترل سیگنال های عمودی و افقی و نه تا پایه هم برای تولید رنگ. یعنی رنگ های قرمز و سبز و آبی هر کدوم سه سیگنال. البته بعضی جاها هم دیدم که برای هر کدوم از چهار تا سیگنال استفاده می کنن. این سیگنال ها هم سه به سه با یه مقاومت به هم وصل می شوند و به مانیتور ارسال می شوند. یعنی آبی ها باهم و قرمزها با هم و غیره ...



      با استفاده از این سیگنال ها می تونی هر سطر و ستونی رو پر کنی. اگه عجله نداری من انتهای کار می خواهم تصویر دوربین رو از طریق FPGA به مانیتور منتقل کنم. بعدش هم ببینم می تونم یه الگوریتم ساده پردازش تصویر روش پیاده سازی کنم یا نه. کل هدف از این پروژه همینه.
      آدمی از عالم خاکی نمی آید بدست

      عالمی دیگر بباید ساخت و از نو آدمی
      پردازش تصویر با FPGA از صفر تا انتها
      http://www.eca.ir/forum2/index.php?topic=74299.0

      دیدگاه


        #4
        پاسخ : اتصال دوربین OV9650 به Spartan3

        تا جایی که یادم هست کابر محترم اقای محمد حسینی در این مورد کار کرده اند و توضیحاتی را هم ارائه داده اند .

        دیدگاه


          #5
          پاسخ : اتصال دوربین OV9650 به Spartan3

          سلام
          مرسی دوست عزیز، فکر می کنم تاپیکی مد نظرتون این باشه

          http://www.eca.ir/forum2/index.php?topic=69199.msg438894#msg438894

          برای استفاده دوستان قرار دادم. ایشون تزشون پیاده سازی پردازش تصویر بر روی FPGA بوده که کار رو به نحو احسن و حرفه ای انجام دادن. از ایشون دعوت می کنم اگر تمایل دارند تجربیاتشون رو برای پر بار شدن این تاپیک ارائه بدهند.
          من کار رو به این نحو ادامه می دم که اول فایل هایی که در تاپیک بالا بود رو مطالعه می کنم. بعد یه سری جمع بندی رو همراه سیگنال های مورد نیاز برای درایو کردن دوربین در آینده خدمتتون می گم. البته این نکته توی ذهنم هست که از آن جایی که دوستان دیگه شاید دوربین های متفاوتی داشته باشند شیوه درایور نویسی رو به نحوی شرح خواهم داد که مثل "یاد دادن ماهیگیری باشه".


          اضافه شده در تاریخ :
          قبل از هر چیز اول ببینیم دوربینی که می خواهیم باهاش کار کنیم چه پایه هایی داره و هر یک از پایه های آن چه وظیفه ای بر عهده دارند.



          در بالا هر پایه رو به همراه توضیح مختصری در مورد هر یک از آن ها مشاهده می کنید. یه توضیخ مختصر هم من الان بدم در موردشون در آینده به طور مفصل در مورد اون ها حرف می زنیم.
          این نکته رو باید بگم که برای مثال پایه های OV7670 رو با هم بررسی می کنیم. توی دوربین های دیگه هم دیدم تقریبا همین طوری بود مگر این که برخی تفاوت های جزیی داشت. مثلا در این جا برای برقراری ارتباط با درایور دوربین از ارتباط I2C استفاده می شه. درست مثل OV9650. از این اینترفیس برای خواندن یا نوشتن بر روی رجیسترهای و انجام برخی تنظیمات دوربین استفاده می شه. مثلا یه موقع می خواهیم کل تصویر به اندازه یک چهارم کوچکتر بشه یا دوربین به مد پردازش سیگنال بره یا مثلا فرمت خروجی RGB رو به YUV تغییر بدیم یا مثلا تعیین کنیم اول 5 تا آبی در خروجی ظاهر بشه بعدش 4 تا قرمز و غیره... . اینا البته مثال بود توی دوربین های مختلف مقادیر و توانایی هاش فرق می کنه. یعنی شما از این به بعد یه دوربین دیگه داشتین و خواستین راهش بندازین می دونین اگه بخواهین چیزی رو تنظیم کنیم در وهله نخست باید بگردین دنبال یه Interface. حالا این که چه دستورهایی رو باید ارسال کنیم و چه مقادیری رو باید تنظیم کنیم در آینده بهتون می گم.
          یه جا توی جدول نوشته ولتاژ مرجع برای تراشه دوربین. توی این نوع دوربینی که داریم بررسیش می کنیم یه واحد مبدل آنالوگ به دیجیتال وجود داره که دیاگرام اون رو در زیر می بینید.



          دوربین برای پردازش های آنالوگ یه بخش مبدل آنالوگ به دیجتال داره که باید طبیعتا یه ولتاژ مرجع هم داشته باشه.
          خروجی تراشه درایور دوربین دو تا سیگنال همسان ساز داره. یکی VSYNC و دیگری HREF. هر دو سیگنال در تمام مدتی که مشغول گرفتن تصویر از دوربین هستین پیوسته در حال تغییر هستند. البته نخوه تغییر اون رو هم می تونین تنظیم کنین.
          سیگنال HREF وقتی Valid هست که داده ها آماده باشند، اگر داده ای وجود نداشته باشه مقدار سیگنال یا صفره یا یک. یک یا صفر بودن اون بستگی به پلاریته ای داره که توی تنظیماتش انتخاب می کنین. شاید این نکته توی ذهنتون بیاد که اگر FPGA بخش اینتراپت داشت خوب می شد، اون وقت این پایه رو وصل می کردیم به تراشه و هر موقع داده آماده بود می خوندیم. ولی خوب FPGA یه همچین بخشی نداره و خودمون باید ایجادش کنیم. اولین کاری که به ذهنمون می رسه طراحی یه بخشی که قابلیت En شدن داشته باشه تا هر وقت داده آماده شد باقی کارها انجام بشه. مثل یک بافر سه حالته که هر وقت یک شد داده رو عبور بده. تا همین جا این موضوع توی ذهنتون باشه وقتی خواستیم طراحی کنیم بیشتر بررسیش کنیم.
          VSYNC مخفف عبارته Vertical Sync Signal هست و HREF مخفف Horizontal Refrence Signal.
          برای سنکرون کردن داده های خروجی و فهمیدن این که هر پالس خروجی برای کدوم بخش از داده های تصویر هست از سیگنال های VSYNC و HSYNC استفاده می کنیم. جای HREF و HSYNC رو می شه با هم عوض کرد.
          تا این جا به طور خلاصه فهمیدیم که هر پایه چه وظیفه ای بر عهده داره. در آینده دقیق تر بررسیشون می کنیم.

          اضافه شده در تاریخ :
          خوب حالا بریم سراغ راه اندازی دوربین.
          اولش لازمه تا دوربین رو ریست کنیم. این کار رو به دو طریق می تونیم انجام بدیم. از طریق پایه ریست دوربین و اتصال اون به FPGA و دیگری از طریق I2C و به صورت نرم افزاری.
          احتمال داره هنگامی که در زمینه راه اندازی این نوع دوربین یا دوربین های مشابه دیگر که از باس I2C برای برقراری ارتباط استفاده می کنن با واژه SCCB زیاد برخورد کنین. این واژه خلاصه عبارت Serial Camera Control Bus هست. در حقیقت اشاره به یک باس سریالی برای برقراری ارتباط با دوربین داره که در این جا منظور I2C هست.
          یکی از بلوک هایی که در FPGA باید پیاده سازی کنیم بخشی هست که بتونیم فرکانس های کاری دلخواهمون رو بسازیم. برای این که بتونیم با دوربین کار کنیم نیاز داریم تا یه کلاک 10 تا 48 مگاهرتزی رو به پایه XCLK وصل کنیم. هر موقع که داده ها در دوربین برای ارسال به FPGA آماده شدند یه کلاکی روی پایه PCLK ظاهر می شه که فرکانسش نصف فرکانس XCLK هست.
          حالا جدای از این که به صورت سخت افزاری دوربین رو ریست کنیم یا به صورت نرم افزاری باید بتونیم I2C رو با استفاده از FPGA پیاده سازی کنیم. خوب قدم بعدی درک سیگنال های I2C برای برقراری ارتباط با دوربین هست.

          اضافه شده در تاریخ :
          می خواهیم سیگنال های پروتکل SCCB رو با هم بررسی کنیم
          مرحله اول Start SCCB



          برای شروع برقراری ارتباط با دوربین باید ابتدا خط دیتا اینترفیس رو یک کنیم مدتی صبر کنیم سپس خط کلاک اینترفیس رو یک کنیم باز مدتی صبر کنیم و در انتهای خط داده و دنبال اون خط کلاک رو با فاصله از هم صفر کنیم و باز هم قدری صبر کنیم.
          میزان صبر کردن ها بستگی به کلاکی داره که به سیستم میدیم. برای مثال توی میکروی آرم که میزان فرکانس XCLK دوازده مگاهرتز تعیین شده بود مقدار تاخیرها حدوده سه میکرو ثانیه لحاظ شده بود.
          خوب پس از این به بعد هر جا خواستیم با باس دوربین ارتباط برقرار کنیم حالا چه به منظور خواندن یا نوشتن بر روی رجیسترها دوربین و یا برای ریست کردن آن، اول Start SCCB می کنیم. پس هرجا این پروسه نام برده شده از این به بعد می دونیم به چه نحو زمانبندی می شه.

          اضافه شده در تاریخ :
          خاطرتون هست که گفتیم برای این که دوربین راه اندازی اولیه بشه باید اول اون رو ریست کنیم. این کارو از طریق I2C انجام میدیم. پس اولین مرحله همون طور که می دونین Start SCCB هست.
          بعد از اون برای ریست کردن دوربین مراحل زیادی رو باید انجام بدیم. سیگنال هاش یه کمی پیچیده می شه ولی سعی می کنم با شکل مفهوم ترش کنم. لازمه که قبلش حتما تاکید کنم اگر هر یک از مراحل به درستی انجام نشد و دوربین جوابی رو که می خواهیم برنگردوند دوباره باز از نو همه مراحل انجام بشه. پس این نکته هم توی ذهنمون می مونه که موقع پیاده سازی مدام جواب دوربین باید چک بشه تا به جواب مورد نظر برسیم.

          خوب مرحله بعدی بعد از S-SCCB برای ریست کردن دوربین نوشتن یک مقدار در یک رجیستر خاص هست. پی قبل از این کار اول باید به دوربین بگیم که روی یکی از رجیسترهات می خواهیم بنویسم. طبق عکس زیر که از دیتاشیت دوربین اقتباس شده:



          برای خوندن رجیسترها عدد 0x43 و برای نوشتن بر روی رجیسترها عدد 0x42 رو باید ارسال کنیم. در حقیقت این اعداد آدرس اسلیو برای نوشتن و خواندن هستند. حالا از کجا فهمیدیم که باید مقداری خاص روی رجیستری خاص بنویسم تا دوربین ریست بشه؟ این نکته رو دقیقا توی دیتاشیت می تونین پیدا کنین. وقتی رسیدیم بهش بهتون می گم حتما.
          پس از این به بعد هر دوربین دیگه ای رو هم که بخواهین با همین نوع باس راه اندازی کنین می دونین که اول باید آدرس اسلیو اون رو از داخل دیتاشیت پیدا کنین.
          خوب حالا سوال این جاست که چطوری می شه عدد 0x42 رو با رعایت پروتکل SCCB ارسال کرد؟
          جواب ساده است. همونطور که احتمالا خودتون هم بهش رسیدین قضیه از این قراره که ابتدا این عدد رو به فرم باینری می نویسیم بعدش به ازای یک ها سیگنال داده اینترفیس رو یک می کنیم و به ازای صفر ها هم صفر می ذاریم و یه کلاک روی سیگنال اینترفیس می دیم. پیاده سازی همین عبارت ساده به همین سادگی هم نیست. این کار توی هشت مرحله انجام می شه به این ترتیبی که خدمتتون عرض می کنم.

          اول مقدار باینری عدد 0x42 رو محاسبه کنیم که می شه 0b0100-0010
          And این عدد رو با 0b1000-0000 محاسبه می کنیم. جواب می شه صفر
          5 میکرو ثانیه صبر می کنیم، سپس روی خط داده اینترفیس می نویسم صفر. 5 میکروثانیه صبر می کنیم کلاک رو یک می کنیم دوباره Delay .کلاک رو صفر می کنیم و در انتها 5 میکرو ثانیه صبر می کنیم.
          عدد 0b0100-0010 رو یه دونه به سمت چپ شیفت می دیم که می شه 0b10000100
          حاصل رو And می کنیم با 0b1000-0000 که می شه یک.
          5 میکرو ثانیه صبر می کنیم، سپس روی خط داده اینترفیس می نویسم یک. دوباره Delay. کلاک رو یک می کنیم باز هم Delay کلاک رو صفر می کنیم و در انتها 5 میکرو ثانیه صبر می کنیم. (منظورم از Delay 5 میکروثانیه هست.)

          این کار رو هشت بار باید انجام بدیم. چون داده ها هشت بیتی هستند و برای هر بیت باید این روند تکرار بشه. توی این هشت مرحله لازم نیست وضعیت دوربین چک بشه. منظور این که پشت سر هم ارسال می کنیم. به هر حال باید چرخه داده ها در I2C تکمیل بشه تا بعدش به ACK گرفتن یا نگرفتن فکر کنیم.
          البته برای پیاده سازی توی FPGA راه های مختلف دیگه ای هم وجود داره. مثلا می شه با استفاده از XOR یا هر روش دیگه ای این روند رو پیاده سازی کرد. حتما لازم نیست عین همین رو پیاده سازی کنین و حتما هم لازم نیست هشت مرحله برای اون طی بشه، ولی بدیهیه که حتما لازم هست همین سیگنال رو بسازیم.

          بعد از این که عدد 0x42 ارسال شد، حالا لازمه که وضعیت دوربین چک بشه. اول شش میکروثانیه صبر می کنیم. کلاک رو یک می کنیم. یک میکرو ثانیه به دوربین مهلت می دهیم. سپس خط داده اینترفیس رو چک می کنیم اگه صفر بود دوربین داده رو دریافت کرده. اگه هم صفر نبود که دوباره همه چی از نو ولی به ترتیبی که می گم بهتون.
          به هر حال در هر دو حالت چه مقدار برگشتی صفر باشه چه نباشه، کلاک رو صفر می کنیم اول. 5 میکروثانیه صبر می کنیم. اگر مقدار برگشتی صفر بود که می ریم به تاپیک های بعدی تا ادامه سیگنال ها رو با هم بررسی کنیم اگر هم که از بخت بد یک بود باید Stop SCCB رو ارسال کنیم و دوباره همه مراحلی که گفته شد رو انجام بدیم.
          سیگنال Stop SCCB هم ساده است. اول خط داده رو صفر می کنیم. 5 میکرو ثانیه صبر می کنیم و سپس خط کلاک رو یک می کنیم. دوباره همین میزان صبر و در نهایت خط داده رو یک می کنیم و دوباره 5 میکرو ثانیه صبر و تمام.

          شاید به نظرتون پیاده سازی یه همچین سیگنالی با استفاده از FPGA سخت باشه ولی وقتی قدری به مباحثی که از پیش آموختین و مسایل آشنا و جدول کارنو و غیره فکر کنین راه حل رو پیدا می کنین. اگه هم پیدا نکردین ایرادی نداره در انتهای این بحث ها قراره که با هم کد راه اندازیشو بنویسم. تازه قراره یه سخت افزار هم براش طراحی کنیم. حالا حالاها کار داریم :biggrin:

          همه سیگنال هایی که در این تاپیک بحث شد رو به صورت گرافیکی می کشم می ذارم.
          آدمی از عالم خاکی نمی آید بدست

          عالمی دیگر بباید ساخت و از نو آدمی
          پردازش تصویر با FPGA از صفر تا انتها
          http://www.eca.ir/forum2/index.php?topic=74299.0

          دیدگاه


            #6
            پاسخ : اتصال دوربین OV7670 به Spartan3

            ارسال عدد 0x42 به دوربین



            اضافه شده در تاریخ :
            ارسال Stop SCCB برای اعلام پایان ارسال داده



            اضافه شده در تاریخ :
            یه دوره کوچیک با هم بکنیم.
            می خواستیم دوربین رو راه اندازی اولیه بکنیم. اولین کاری که قرار بود انجام بدیم ریست کردن دوربین. تصمیم گرفتیم از طریق نرم افزار دوربین رو ریست کنیم. پس اولین کاری که کردیم Start SCCB بود. بعدش گفتیم برای این که دوربین رو ریست کنیم باید روی یه رجیستر خاص یه مقدار خاص رو بنویسم. حالا که قراره چیزی روی رجیستری نوشته بشه پس قبلش باید 0x42رو ارسال کنیم. اگر ACK مورد نظرمون برگشت می ریم سراغ قسمت بعدی یعنی نوشتن مقدار خاص روی رجیستر خاص اگه نه که Stop SCCB می کنیم و دوباره از نو.

            خوب الان فرض می کنیم همه چی رو به راهه و می خواهیم روی رجیستر خاص مقداری خاص رو بنویسم. اولین کاری که می کنیم اینه که مقداری به دوربین فرصت می دهیم. حدود یک میکروثانیه. بعد رجیستری رو که می خواهیم روش بنویسم صدا می کنیم. حالا از کجا بفهمیم کدوم رجیستر رو باید صدا کنیم؟



            در تصویر بالا که از دیتاشیت دوربین نقل شده، می بینین که نوشته برای ریست کردن دوربین روی رجیستر 0x12 مقدار 0x80 رو بنویسید.
            فکر کنم بدونین چطوری می شه رجیستر 0x12 رو صدا زد. بله دقیقا طبق همون هشت مرحله ای که برای 0x42 سپری شد به انضمام کلاک های بعدش. در این جا هم بعد از ارسال 0x12 بررسی می کنیم که آیا ACK مورد نظر برگشت یا نه. اگه که برگشت می ریم سراغ قسمت بعدی اگه نه که Stop SCCB رو ارسال می کنیم و دوباره روز از نو و روزی از نو.

            نکته: موقع ارسال کردن 0x12 لازم نیست که Start SCCB کنیم و اگر ACK مورد نظر هم برگشت لازم نیست که Stop SCCB کنیم. همون اول یه بار Start SCCB کردیم توی هر مرحله اگر ACK مورد نظر برنگشت Stop SCCB می کنیم. می دونین Start و Stop کردن رو مثل یک پرانتز دور یک عبارت خاص در میان هزارها عبارت و جمله یک مقاله در نظر بگیرید که قراره از عبارت ها و جمله هایی که همراش هستند متمایز بشه. مثل کاری که الان داریم انجام می دیم. (دوربین ریست شو). پرانتز باز: Start SCCB، دوربین ریست شو: که دقیقا الان وسط همین کار هستیم، پرانتز بسته: Stop SCCB

            در ادامه فرض می کنیم همه چی رو به راهه و ACK مورد نظرمون هم برگشته. دوباره حدوده یک میکرو ثانیه به دوربین فرصت می دیم. قرار بود روی رجیستر 0x12 عدد 0x80 رو بنویسیم. الان دیگه نوشتن این عدد روی باس برای شما نباید کاری داشته باشه. بله درسته همان هشت مرحله به انضمام کلاک های بعدش. وقتی روی باس آدرس یک رجیستر رو می نویسید، دوربین مدتی منتظر می مونه تا عدد بعدی رو که ارسال می کنین دریافت کنه و مقدارش رو با مقدار قبلی رجیستر جا به جا کنه.
            در این مرحله هم مثل گذشته اگه ACK مورد نظر رو دریافت کردین که میریم به مرحله بعد اگه نه که دوباره Stop SCCB و دوباره مرحله یک.

            و اما مرحله بعدی و مرحله آخر: اگر تمام ACK هایی که دریافت کردین معتبر بود Stop SCCB کنین و مطمئن باشین که دوربین ریست شده است.


            اضافه شده در تاریخ :
            بیایید فرض کنیم یه کوچولو در ارسال دستور ریست اشتباه کردیم و متوجه نشدیم و فکر کردیم همه چی رو به راهه و ACK ها مقدار درست دارند.
            برای این که مطمئن بشیم که دوربین ریست شده است یا نه، مقدار رجیستر 0x12 رو بررسی می کنیم. برای این کار لازمه که با زمانبدی سیگنال SSCB برای خواندن مقدار آشنا باشیم. مقدار رجیستر مذکور باید صفر باشه. مشکلی که وجود داره اینه که اگر من مقدار صفر رو بخونم از کجا متوجه بشم واقعا مقدارش صفره یا چون دوربین هیچی برای من ارسال نکرده مقدار صفر رو خوندم. خوب پس اول لازمه یه رجیستری که یه مقدار فقط خواندنی داره رو بخونیم و با دیتاشیت مقایسه اش کنیم تا مطمئن بشیم زمانبندی سیگنال ها رو به نحو مناسب پیاده سازی کردیم.
            مثلا رجیسترهای ID و Ver. هر دو رجیستر فقط خواندنی هستند اولی مقدار اولیه اش 0x76 هست و به صورت MSB ارسال می کنه و دومی 0x73 و LSB. آدرس رجیستر اول 0x0a و دومی 0x0b هست. طبق دیتاشیت.



            خوب اولین کاری که باید بکنیم چیه؟
            بله درسته اول از هر کاری باید Start SCCB کنیم. این شد مرحله اول.
            در تاپیک های قبلی گفتیم هر بار که می خواهیم بخونیم 0x43 و هر بار که می خواهیم بنویسم 0x42 رو ارسال می کنیم. البته روندش با یک روند معمولی که در وهله اول به ذهنمون می آد یکسان نیست و قدری فرق می کنه. فرقش رو بهتون می گم.

            مرحله دوم: مقدار 0x42 را بنویسد. (فرقی که در موردش گفتم همینه. قبل از این که رجیستری رو بخونیم اول باید صداش بزنیم. برای یونیک موندن شیوه آدرس دهی و ارسال مقادیر، برای صدا زدن یک رجیستر همیشه اول می ریم روی مد نوشتن، آدرس رجیستر رو صدا می زنی و ...). اکر مثل قبل ACK مورد نظر برگشت که خیلی عالی، به مرحله بعدی می ریم اگه نه که Stop و روز از نو و ...

            مرحله سه: آدرس رجیستر رو صدا می زنیم. در این جا منظور 0x0a هست. اگر مقدار برگشتی مناسب بود که می ریم مرحله بعد اگه نه که خودتون الان دیگه بهتر می دونین.

            مرحله چهارم: Stop

            مرحله پنجم: مقدار صبر می کنیم. در حدود یک میکروثانیه و دوباره Start

            مرحله ششم: مقدار 0x43 رو روی باس می نویسیم.
            تا این جا به دوربین گفتیم که می خواهیم مقدار رجیستر 0x0a رو بخونیم. در این جا هم باید مقدار برگشتی بررسی بشه.

            مرحله هفتم: قدری صبر، به میزان تقریبا یازده میکروثانیه و بعدش دوربین شروع می کنه به ارسال مقدار. خوندن مقدار رجیستر در هشت مرحله انجام می شه چون قراره که هشت بیت رو بخونیم. یعنی روند زیر رو هشت بار تکرار می کنیم تا بتونیم به بایت بخونیم.
            1- کلاک رو یک می کنیم.
            2- 5 میکروثانیه صبر.
            3- یک بیت از داده رو می خونیم.
            4- کلاک رو صفر می کنیم.
            5- ده میکروثانیه صبر.

            حالا باید NACK رو به دوربین ارسال کنیم. اول خط داده رو یک می کنیم 5 میکرو ثانیه صبر، خط کلاک رو یک می کنیم و باز هم صبر، خط کلاک رو صفر می کنیم و در آخر بعد از 5 میکروثانیه خط داده رو هم صفر می کنم و باز هم صبر می کنیم.

            برای اتمام سیگنال خواندن Stop می کنیم.

            لازم به ذکر است برای سهولت در نوشتار از این به بعد شرط می ذاریم که هر بار که ذکر شد Start یا Stop منظور همون Start Sccb و Stop SCCB هست. و هر جا هم که ذکر شد صبر می کنیم یا Delay منظور به میزان آخرین باری که گفته شده است.


            اضافه شده در تاریخ :
            آخرین مرحله برای راه اندازی اولیه دوربین نوشتن یه سری مقادیر در آدرس های مختلف هست. این تنظیمات دلخواه هستند. اگر این تنظیمات با موفقیت انجام شوند دوربین آمده می شه تا اولین تصویر رو برای ما ارسال کنه. هر کدوم رو که خواستین تغییر بدین کافیه آدرس اون رجیستر رو به همراه مقدارش برای دوربین بفرستین، سپس مقادیر برگشتی رو بررسی کنین و صحت ارسال دستور مطمئن بشین. بعد از این که همه پارامترها رو ست کردین به دوربین حدود 200 میلی ثانیه فرصت بدین تا همه تنظیمات ست شوند. لازم نیست برای اعمال هر تنظیم این مدت زمان صبر کنین، بعد از این که تمام تنظیمات رو انجام دادین یک بار در انتها 200 میلی ثانیه صبر کنین.

            تا این جا راه اندازی اولیه دوربین رو یاد گرفتیم. حالا آماده ایم تا از دوربین اولین تصویرمون رو بگیریم

            اضافه شده در تاریخ :
            دوربینی که می خواهیم باهاش کار کنیم با هر نوع دوربین دیگه دارای فرمت های خروجی تعریف شده ای هستند. مثلا در OV7670 چهار فرمت خروجی وجود داره که در جدول زیر می بینین. نخستین تفاوت بین فرمت های دوربین، اندازه تصاویر آن ها هستند. اولن قدم در گرفتن یک تصویر از دوربین تنظیم این فرمت برای دوربین است. طبق دیتاشیت دوربین هر تنظیمی که لازم بود رو می تونین به همون روش هایی که خدمتتون گفتم اعمال کنین.



            آدمی از عالم خاکی نمی آید بدست

            عالمی دیگر بباید ساخت و از نو آدمی
            پردازش تصویر با FPGA از صفر تا انتها
            http://www.eca.ir/forum2/index.php?topic=74299.0

            دیدگاه


              #7
              پاسخ : پردازش تصویر با FPGA از صفر تا انتها

              تشکر بابت تاپیک آموزنده ای که ایجاد کردید.
              در مورد پردازش تصویر real time با fpga روشهای زیادی وجود داره که هدف حداقل کردن هزینه و بالا بردن کارایی می باشد در خیلی از تاپیک ها این بحث مطرحه که برای کارهای پردازش تصویر real time با fpga باید از fpga های مخصوص پردازش تصویر استفاده شود که قیمت خیلی بالایی دارند (مثلا FPGA های سری Virtex-4 SX) حالا اینجا چندتا سوال برای من ایجاد شده...
              آیا واقعا باید حتما از یه fpga مخصوص پردازش تصویر استفاده کرد؟ و از fpga های سری spartan III نمیشه استفاده کرد؟(برای real time )
              با توجه به تعداد logic cell مورد نیاز آیا fpgaهای سری spartan در این مورد محدودیت دارند؟
              آیا میشه با یک طراحی مناسب سخت افزاری با حداقل هزینه یک سیستم پردازش تصویر realtime ایجاد کرد؟(با fpga های ارزان)

              در تاپیک زیر در این رابطه بحث شده:
              http://www.eca.ir/forum2/index.php?topic=10647.15

              دیدگاه


                #8
                پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                سلام و تشکر فراوان .واقعا خسته نباشید.مطلبی که شروع کردین بسیار خوب و آموزنده هست و امیدواریم که ادامه پیدا کنه.واقعا ممنون.منتظر مطالب جدیدتون هستیم

                دیدگاه


                  #9
                  پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                  حالا یک کم بریم سراغ پورت VGA سیگنال هاشو با هم بررسی کنیم. بعدش هم می ریم سراغ ال سی دی و ...
                  پورت VGA به صورت استاندارد از 15 پین تشکیل شده. سه تا پین اول برای سیگنال های رنگی است که به ترتیب قرمز و سبز و آبی هستند. یه تعداد پایه زمین، یه تعدادی هم تغذیه و یه تعدادی هم برای سنکرون کردن سیگنال های عمودی و افقی صفحه نمایش. البته دو تا پایه هم می مونه که برای تعیین آی دی مانیتور هست.
                  وصل کردن یه پورت VGA به FPGA خیلی ساده هست. کافیه پایه های یک و دو سه رو با یه مقاومت 270 اهمی وصل کنین به پایه های دلخواه FPGA. البته تو یه سری رفرنس ها می بینین که به جای یه مقاومت روی هر خط سه یا چهار مقاومت وجود داره که دلیلش رو به زودی می گم.
                  پایه های 6 و 11 و 7 و 8 و 10 رو هم به زمین وصل می کنین. دو تا پایه سنکرون ساز عمودی و افقی رو هم با یه مقاومت 82.5 اهمی وصل می کنین به پایه های دلخواه FPGA، باقی پایه ها رو هم رها می کنین. کلا با همین پنج تا پایه می خواهیم یه مانیتور رو کنترل بکنیم.
                  سیگنال هایی که مختص رنگ هستند هر کدوم یک بیت هستند. با این سه بیت می شه هشت رنگ رو ساخت. مثلا اگه هر سه تا بیت صفر باشه رنگ سیاه منتقل می شه. حالا این که چطوری می شه 256 تا رنگ رو توی مانیتور تولید کرد یا حتی بیشتر از این حرفا، مطلبی هست که به زودی بهش می پردازیم.

                  اضافه شده در تاریخ :
                  نخستین چیزی که لازم داریم یه سیگنال 25 مگاهرتزی هست. قراره تمام تغییراتی که رخ بده با صفر و یک شدن این سیگنال توام بشه.
                  کد:
                  process (clk_in) 
                  begin 
                  	if clk_in'event and clk_in='1' then 
                  	 if (Clk25 = '0')then 
                  	  Clk25 <= '1' after 2 ns; 
                  	 else 
                  	  Clk25 <= '0' after 2 ns; 
                  		end if; 
                  	end if; 
                  end process;
                  در بالا یه تکه کد که به زبان VHDL هست رو ملاحظه می کنید. درک کد نباید زیاد سخت باشه. یه توضیح مختصر بدم که هر بار که CLK_In تغییر کرد بدنه پروسس اجرا می شه. توی بدنه پروسس مقدار Clk25 بررسی می شه. اگر یک بود بعد از 2 نانو ثانیه صفر می شه و بالعکس. تمام این صفر و یک شدن ها هم وقتی باید رخ بده که Clk_in یک باشه. نتیجه تولید یه سیگنال 25 مگاهرتزی هست. کلاک ورودی برای هدایت کل روند کار و فعال کردن یا غیر فعال کردن اون ها قرار داده شده. بنا به ضرورت می شه حذفش کرد یا به نحو دیگه ای کد نوشت.

                  اضافه شده در تاریخ :
                  در زیر سیگنال VGA رو مشاهده می کنید.



                  می دانیم تصویری که قصد نمایش آن بر روی مانیتور را داریم باید با یک سیگنال مبنا همزمان باشد، تا یک تصویر بی حرکت بوجود آید. این وظیفه را سیگنال های سنکرون کننده بر عهده دارند. این سیگنال ها از لحظاتی پیش از ورودی به محدوده تصویر آغاز می شوند و تا لحظاتی پس از آن نیز ادامه می یابند و دوباره به مقدار اولیه خود باز می گردند. می توان با شمارش دقیق این سیگنال های دیجیتالی، داده های مورد نظر را در مختصات های مختلف صفحه نمایش قرار داد.
                  سیگنال VGA از چند مرحله تشکیل شده. شرح زمانبندی به این ترتیب هست:
                  "سیگنال همسان ساز از یک مقدار کمینه پیش از مختصات صفحه نمایش آغاز می شود تا به لبه سمت چپ صفحه نمایش برسد، سپس کل عرض صفحه نمایش را از سمت چپ به راست پیمایش می کند. از سمت راست صفحه نمایش تا یک مقدار بیشینه پیش می رود، در انتها از مقدار بیشینه به کمینه تغییر می کند."
                  یه سری اصطلاحات برای زمانبندی سیگنال های VGA وجود داره که هر کدوم که مهمتر باشه رو می گم براتون. مکان ها و مختصات هایی که در مورد اون صحبت می شه جنبه مفهومی داره و واقعی نیستند. منظورم اینه که در زمانی که مثلا اشاره می کنیم "سیگنال همسان ساز به صفحه نمایش رسیده و در عرض آن در حال گذر است" منظورمان این است که در این زمان می توانیم داده ها به مانیتور برای نمایش منتقل کنیم.

                  Tbp: مدت زمان بین لحظه شروع مجدد تا ورودی به محدوده صفحه نمایش
                  Tpw: لحظه پایان سیگنال تا شروع مجدد
                  Tdisp: لحظه بین ورود سیگنال به صفحه نمایش تا خروج آن
                  Ts: زمان پریود سیگنال همسانساز
                  Tfp: لحظه خروجی سیگنال از صفحه نمایش تا انتهای سیگنال

                  آدمی از عالم خاکی نمی آید بدست

                  عالمی دیگر بباید ساخت و از نو آدمی
                  پردازش تصویر با FPGA از صفر تا انتها
                  http://www.eca.ir/forum2/index.php?topic=74299.0

                  دیدگاه


                    #10
                    پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                    سلام آقا پویا.خیلی ممنون از مطالب مفیدی که گذاشتی.یه سوالی ازت داشتم.تو دیتاشیت ov7670 نوشته پین PCLK یک پین خروجیه.میخواستم بدونم وصل نبودن PCLK به سوکت vgaمشکلی در ایجاد تصویر در مانیتور نمیکنه؟اخه اگه وصل نباشه مانیتور چجوری میفهمه کی باید نمونه برداری کنه واینکه داده ها ی تصویر کی معتبرن تا تصویرو تشکیل بده؟

                    دیدگاه


                      #11
                      پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                      سلام دوست عزیز. خواهش می کنم
                      نه مشکلی ایجاد نمی کنه. مدیریت سیگنال سنکرون ساز دست خودته. حالا می تونی با FPGA سیگنال ها رو از دوربین بخونی هر موقع خواستی داده مناسب رو به مانیتور ارسال کنی. در این میان مهم مدیریت سیگنال هاست که توسط شما و در داخل FPGA صورت می گیرد.

                      پیروز و سربلند باشید

                      اضافه شده در تاریخ :
                      حالا اگر زمانبدی سیگنال رو بدونین به سادگی می تونین بر روی مانیتور نقاطی رو روشن و یا خاموشی کنین. کل زمان سیگنال همسانساز افقی 521 و عمودی 800 کلاک هست. اگر تصویر 640 در 480 پیکسل باشه زمان سیگنال عمودی نمایش داده، 480 و افقی 640 کلاک خواهد بود. دو کلاک طول می کشه تا سیگنال VGA از بیشترین مقدار به کمترین مقدار خود برسد.
                      تا این جا اطلاعات اولیه برای شروع برنامه نویسی برای پورت VGA رو کسب کردین. باقی موارد مربوط به بخش کد نویسی است که به طور مفصل در بخش های آینده در موردش بحث می کنیم. اگر جدای روند این بحث می خواهید مطالعه کنین پیشنهاد می کند فایل های مثال هایی که در این زمینه هست رو مطالعه کنین. اساس کار پورت VGA به همین ترتیبی بود که خدمتتون گفتم. تنها تفاوت در بین مانیتورهای مختلف و یا کدهای مختلف، زمانبندی و کلاک ها و غیره هست. یه کوچولو زمانبدی های دیگه ای هم وجود داره که با مطالعه مثالهایی در این زمینه می تونین با توجه به اطلاعات اولیه ای که کسب کردین اون ها رو به سادگی درک کنین.

                      خوب پس به طور خلاصه این طوری شد که: سیگنال های همسانساز صفحه رو به صورت عمودی و افقی پیمایش می کنن، شما هم شروع می کنین به شمارش این سیگنال ها، هرجا که رسیدین به مختصات مورد نظرتون همون جا سیگنال های رنگی رو مقدار دهی می کنین.

                      اضافه شده در تاریخ :
                      خوب حالا وقتشه که بریم سراغ راه انداری ال سی دی. بعدش هم شروع می کنیم به طراحی یه بورد مناسب که بتونیم مطالبی رو که تا الان روش بحث کردیم پیاده سازی و تست کنیم. راه اندازی ال سی دی با FPGA خیلی سخت تر و طولانی تر از مطالبیه که تا الان بررسی کردیم.
                      آدمی از عالم خاکی نمی آید بدست

                      عالمی دیگر بباید ساخت و از نو آدمی
                      پردازش تصویر با FPGA از صفر تا انتها
                      http://www.eca.ir/forum2/index.php?topic=74299.0

                      دیدگاه


                        #12
                        پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                        سلام اقاپویا.یه سوالی در مورد شکل صفحه اول داشتم.(شکل سوکت vga).همونطورکه میدونی ov7670 هشت بیت خروجی داره d0-d7 و اینکه در سوکت vga سیگنالهای rو gو b سیگنالهای آنالوگ هستن.اگه فرمت تصویر خروجیم مثلا rgb888 یا rgb565 باشه چجوری باید از این16یا24 بیت تصویر خروجی ,سیگنالهای rو gو b انالوگ رو بوجود بیارم؟اصلا این کارلازمه,یامانیتور خودش این کارو میکنه؟

                        دیدگاه


                          #13
                          پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                          نوشته اصلی توسط ilia20
                          سلام اقاپویا.یه سوالی در مورد شکل صفحه اول داشتم.(شکل سوکت vga).همونطورکه میدونی ov7670 هشت بیت خروجی داره d0-d7 و اینکه در سوکت vga سیگنالهای rو gو b سیگنالهای آنالوگ هستن.اگه فرمت تصویر خروجیم مثلا rgb888 یا rgb565 باشه چجوری باید از این16یا24 بیت تصویر خروجی ,سیگنالهای rو gو b انالوگ رو بوجود بیارم؟اصلا این کارلازمه,یامانیتور خودش این کارو میکنه؟
                          سلام دوست عزیز
                          اصلا لازم نیست که دوربین رو مستقیم به VGA وصل کنیم. این وسط یه واسطی وجود داره که می تونین با هر تبدیل دلخواه سیگنالهای خوانده شده از دوربین رو به VGA منتقل کنین. این واسط همون FPGA هست. حالا فقط کافیه از سیگنال های دریافتی رنگ ها رو داخل FPGA جدا کنی بعدش هر رنگ رو به سیگنال مورد نظرش روی VGA انتقال بدی. مثلا اگر فرمت تصویر 565 بود از کل پکتی که دریافت می کنی 5 بیت اولش برای رنگ قرمز هست. اون رو جدا می کنی از پکت و سیگنال مورد نظر رو به پورت قرمز VGA ارسال می کنی. فقط مساله ای که می مونه خواندن و تولید تعداد رنگ های برابر است. مثلا اگه دوربین می تونه تا 256 رنگ رو از هم تفکیک کنه، توی طراحیمون هم باید این نکته رو مد نظر قرار بدیم که سیگنال های VGA هم باید همین مقدار رنگ رو تولید کنند. چون با سه بیت می شه هشت رنگ رو تولید کرد. برای این که بشه تعداد رنگ های بیشتری تولید کرد موضوعی است که بستگی خیلی زیادی به سخت افزار داره. عموما با سه مقاومت موازی با مقدارهای مشخص بر روی پورت های VGA می شه 512 رنگ رو تولید کرد.

                          پیروز و سربلند باشید
                          آدمی از عالم خاکی نمی آید بدست

                          عالمی دیگر بباید ساخت و از نو آدمی
                          پردازش تصویر با FPGA از صفر تا انتها
                          http://www.eca.ir/forum2/index.php?topic=74299.0

                          دیدگاه


                            #14
                            پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                            آقا پویا.سلام. خیلی ممنون که این بحث رو شروع کردی. موفق باشی
                            از دوستان علاقمند هم خواهش دارم سوالهای خارج از موضوع رو اینجا نپرسین. واقعا حیفه که موضوع به این قشنگی به حاشیه بره. ممنون از همه تون

                            دیدگاه


                              #15
                              پاسخ : پردازش تصویر با FPGA از صفر تا انتها

                              سلام مهندس پویا دمت گرم عالی بود
                              مهندس فقط اگه VGA رو برامون بیشتر موشکافی کنید ممنون میشم چون کارم گیرشه
                              خداوند جهاد را برای سرافرازی اسلام واجب کرد.
                              حضرت فاطمه (س)

                              دیدگاه

                              لطفا صبر کنید...
                              X