NOTICE توجه: این یک موضوع قدیمی است که آخرین پست ارسالی آن مربوط به 4423 روز قبل است . لطفا فقط پاسخ ها ، سوالات و درخواست های 100 درصد مرتبط را به آن ارسال کنید و برای درخواست ها و سوالات جدید موضوع جدیدی را ایجاد کنید
نمایش نتایج: از 1 به 15 از 15

موضوع: کار با پورت usb میکرو at90usb162

  1. #1
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض کار با پورت usb میکرو at90usb162

    با سلام
    میخواستم با ابن پورت USB میکرو AT90USB162 کار کنم رفتم توی دیتا شیت یه چرخی زدم دیدم نه کار ما نیست بهتره برم دنبال یه کتابخونه ای چیزی یه سرچی کردم خوردم به این کتابخونه LUFA ، کار آقای Dean Camera هست این لینک سایتشون و صفحه ای که لینک آخرین ورژن این کتابخونه رو قرار میدن هست :
    Four Walled Cubicle - LUFA (Formerly MyUSB)
    کتابخونه رو دانلود کردم یه نگاه بهش کردم آخه این چیه ! سرش کجاس؟ تهش کجاس؟ اینکه یه مجموعه کتابخونه اس کدومش مال USB ایه؟ با خودم گفتم برم همون دیتا شیت رو بخونم بهتره !
    توی آموزش تحت وبگی که گزاشته بودن دیدم که میکرو های زیر رو از AVR 8 بیتی ساپورت میکنه :

    یکم دیگه که دقت کردم دیدم که بله عجب چیزه کاملیه برای ارتباط با همه دستگاه USB کتابخونه داره وقتم رو روی این بزارم خیلی بهتره اما چه فایده وقتی حتی هنوز نمیدونم کدومش مال ارتباط با کامپیوتر هست ! (ماشالله منم که اینگلیسی فول!)
    خوب من یک چیزایی در مورد پورت USB و نحوه عملکرداش میدونم با این خواسته های استاندارد و توصیفگرها هم تقریبا آشنا هستم
    چیزی که به نظرم اینجا لازمه به دوقسمت تقسیم میشه یکی نوشتن برنامه میکرو و دومی نوشتن یک برنامه ویژوال برای ارتباط با USB که برای دومی من توی مجله PMM6,7 مثالی رو دیدم که با وی بی و C# نوشته بودند که به نظرم همون نیازم رو برطرف کنه البته یه سوال از کسانی که با این کتابخونه کار کردن داخل این مجموعه، نرمافزاری برای این کار وجود نداره؟ (من چیزی ندیدم)
    پس اینجا چیزی که بیشتر نیاز به تامل ، تاخر و تعقل داره به نظر همین مجموعه LUFA هست .
    خلاصه از تمامی دوستانی که با این کتابخونه کار کردن درخواست دارم تا بنده رو کمک کنند اگه میشه بفرمایید اصلا از کجاش باید شروع کنم !

    خوب من یه چیزایی فهمیدم
    آقا من فهمیدم که این کتاخونه اصلی یعنی هدر usb.h توی مسیر زیر هست که با ایکلود کردن اون بقیه کتابخونه های مورد نیاز اینکلود میشن

    ...\LUFA-111009_3\LUFA-111009\LUFA\Drivers\USB

    /** \file
    * \brief Master include file for the library USB functionality.
    *
    * Master include file for the library USB functionality.
    *
    * This file should be included in all user projects making use of the USB portions of the library, instead of
    * the individual USB driver submodule headers.
    */


    فعلا فقط همین ! (واقعا خسته نباشم )
    حالا باید چی کار کنم ؟ برای یه ارتباط ساده با usb باید چه تنظیماتی انجام بشه ؟
    ممنون از توجهتون

  2. کاربران : 2 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  3. # ADS
    Circuit advertisement
    تاریخ عضویت
    Always
    نام
    Advertising world
    نوشته ها
    Many
     

  4. #2
    مدیرکل انجمنها
    تاریخ عضویت
    May 2011
    نام
    احسان صفامنش
    نوشته ها
    1,763
    تشکر
    919
    تشکر شده 2,261 بار در 1,056 پست

    پیش فرض

    اگه شما میخواهید که از دیتا شیت استفاده کنید یک مطلب هست که خود پورت usb میکرو میتونه نوع اطلاعات token و data و ... رو تشخیص بده و پرچم ها و وقفه های لازم رو ایجاد کنه که در دیتا شیت ذکر شده. اما آیا خود پورت usb میکرو میتونه عملیات شناسایی خودش رو با کامپیوتر راه بندازه. یعنی عملیات discriptor رو بدون برنامه نویسی انجام بده. یا برای عملیات شناسایی باید برنامه نوشته بشه.
    اگه به برنامه نیاز باشه که از کجا روش رو میدونین تا خودتون بنویسین. پس باید از کتابخونه ای استفاده کرد که عملیات discriptor رو خودکار انجام بده

  5. کاربران : 2 تشکر کرده اند از شما esisafa برای ارسال این پست سودمند:


  6. #3
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    ممنون
    قرار شد که با کلاس cdc کار کنم و فعلا روی یک مثال آماده از همین مجموعه lufa کنم

  7. تشکرها از این نوشته :


  8. #4
    مدیرکل انجمنها
    تاریخ عضویت
    May 2011
    نام
    احسان صفامنش
    نوشته ها
    1,763
    تشکر
    919
    تشکر شده 2,261 بار در 1,056 پست

    پیش فرض

    ببخشید مگه cdc برای میکرو های بدون usb نیست؟؟؟؟؟؟
    من یک پروژه ی cdc دیدم واسه atmega8
    شاید تشابه اسمیه
    ویرایش توسط esisafa : 18-10-2011 در ساعت 03:06

  9. تشکرها از این نوشته :


  10. #5
    مدیرکل سایت kavir آواتار ها
    تاریخ عضویت
    Jun 2007
    نام
    زارعی
    نوشته ها
    3,547
    تشکر
    1,218
    تشکر شده 5,684 بار در 1,801 پست

    پیش فرض

    نقل قول نوشته اصلی توسط esisafa نمایش پست ها
    ببخشید مگه cdc برای میکرو های بدون usb نیست؟؟؟؟؟؟
    من یک پروژه ی cdc دیدم واسه atmega8
    شاید تشابه اسمیه
    خیر cdc کلا پورتکل همون usb2serial هست که حتی برا ی آرم 7 و سری کرتکس هم تست کردیم و یک ارتباط عالی هست که بخواین از پورت یو اس بی به سادگی استفاده کنید
    کویر ویدئو راه اندازی شد

    اگر چه دیر ولی برگشتم به جمع دوستان قدیمی....

  11. کاربران : 3 تشکر کرده اند از شما kavir برای ارسال این پست سودمند:


  12. #6
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    در واقع (البته منظورم دمویی هست که داخل مجموعه lufa هست ) USBtoSerial به عنوان یکجایگزین برای ic مبدل usb به سریال طراحی شده یعنی در داخلش یک بافر fifo هست برای ارسال و دریافت به و از یک usart سخت افزاری
    ویرایش توسط mojtaba_led : 18-10-2011 در ساعت 18:01

  13. تشکرها از این نوشته :


  14. #7
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    وب من بالاخره تونستم با استفاده از این مثال اتمل که داخل AVR-USB-162-CDCهست با پورت usb ارتباط برقرار کنم و یکسری رشته رو به هایپر ترمینال بفرستم ، در واقع این مثال برای بورد آموزشی stk525 و stk526 نوشته شده که تمام پیکره بندی های سخت افزارش در فایل stk_526.h که میتونیم مطابق اون سخت افزار رو تهیه و یا مطابق نظر خودمون اصلاحش کنیم البته این رو هم بگم سورس اس برای iar , avrgcc نوشته شده که من فعلا با نسخه iar دارم کار میکنم البته میشه با انجام یکسری تنظیمات در فایل compiler.h میشه از اون در کامپایلر های دیگه مثل کدویژن استفاده کرد.


    خوب اگر دوستان مایل هستید این تایپیک رو فعلا در وحله اول اختصاص بدیم به بررسی appnote های avr272 و avr276 که برای استفاده از کلاس cdc نوشته شدند .بعد از اتمام کار بریم سراغ lufa ، من اینکار رو توی یک انجمن دیگه شروع کردم گفتم اینجا هم انجام بدم تا بتونم از اساتید این انجمن هم کمک بگیرم

    ممنون از توجهتون

  15. تشکرها از این نوشته :


  16. #8
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    avr272
    USB CDC Demonstration UART to USB Bridge

    کلا هدف از ارائه این appnote از اونجا که توی pc های امروزی ویا مثلا لپ تاب ها دیگه پورت rs232 حذف شده و جای خودش رو به پورت usb داده و از طرفی اگر بخواهیم تجهیزاتی که با uart کار میکنند به usb منتقل کنیم هم در توسعه برنامه pc و هم توسعه دستگاه کار دشواری به نظر میاد توی اینجا اتمل امده یک راه حل ساده رو برای رفع این مسئله پیشنهاد کرده که از طریق کلاس cdc که یک توضیح مختصری در موردش در پست قبل گفتم ارائه کرده از ویژگی های این روش :
    1. عدم نیاز به تغییر در برنامه pc
    2. تغییرات اندک در برنامه دستگاه usb



    در مورد پروگرامر ، به غیر پروگرامر های خود اتمل پروگرامری که این میکرو رو ساپروت میکنه یکیش AVR910 هست که من خودم از این استفاده میکنم و البته میتونید با پروگرامر کردن بوت لودر مربوط به میکروتون بدون نیاز به پروگرامر اون رو با نرم افزار FLIP پروگرام کنید روش کارش هم در انجمن TATLY AVR توضیح داده شده

    خوب برای شروع کار مثال اتمل رو با IAR یا GCC باز کنید و برنامه رو کامپایل و فایل هگز رو داخل میکرو بریزید (اگر با FLIP کار میکنید کافیه که بر روی START APPLICATION کلیک کنید ) پس از شروع کار میکرو دستگاه USB توسط کامپیوتر شناخته میشه حالا باید درایور مربوطه رو نصب کنید برای این کار آدرس زیر رو به ویزارد نصب درایور بدید AVR-USB-162-CDC\Atmel\at90usb162-cdc-1_0_1\at90usb162\demo\cdc\...\...
    پس از نصب درایور (انجام مراحل سرشماری ) دستگاه USB به عنوان یک پورت کام مجازی با نام AT90USBxxx CDC USB to UART MGM شناخته میشه به ترتیبی که در شکل زیر مشاهده میکنید

    بعد روش کلیک راست کنید و به قسمت PROPERTIES برید و بعد در برگه PORT SETTINGS بود ریت رو برابر با 38400 انتخاب کنید( این بود ریتی هست که بصورت پیشفرض در فایل config.h انتخاب شده میتونید مقدارش رو عوض کنید) بعد تغییرات رو ذخیره کنید .
    حالا هایپر ترمینال رو باز کنید (اگر ویندوزتون هایپر ترمینال نداره و از کدویژن و یا بسکام استفاده میکنید میتونید از ترمینال ایمولاتور اون ها هم استفاده کنید ) در ابتدا تنظیمات ترمینال رو مطابق با تنظیمات برگه PORT SETTINGS انجام بدیدو پروت کام متناظر رو انتخاب و باز کنید .
    در این حالت با توجه به سخت افزار و فایل stk_526.h با صفر کردن به ترتیب PB0 ,PB4,PB5,PB6,PB7,PD7 در هایپر ترمینال موارد زیر رو مشاهده میکنید که به نمایش در می آیند :


    پایان قسمت اول
    ویرایش توسط mojtaba_led : 11-11-2011 در ساعت 01:32

  17. کاربران : 2 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  18. #9
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    application overview :

    در واقع اینجا CDC به کاربر این امکان رو میده تا پورت RS232 رو با پورت USB به عنوان سخت افزار شبیه سازی کنه بنابراین دستگاه در قالب یک پورت کام مجازی به جای دستگاه USB در دیوایس منیجر ویندوز ظاهر میشه و این مسئله این امکان رو به کار بر میده تا از برنامه نوشته شده برای پورت RS232 با استفاده از USB بدون تغییر در برنامه PC استفاده کند .
    در شکل زیر ساختار کلی نحوه برقراری ارتباط بین یک مجموعه برنامه نوشته شده در دستگاه و برنامه PC از طریق دو پورت RS232 و USB نشان داده شده

    همونطور که در شکل فوق مشاهده میشود در ارتباط USB درایور UART در قسمت دستگاه جای خودش رو به درایور UART-USB داده پس کاربر باید برای ارتباط با PC از توابع UART-USB به جای توابع UART استفاده نماید

    در اینجا تنها یک بار دستگاه USB توسط PC طی مراحل شمارش شناسایی شده و بعد از ان برنامه CDC یک ارتباط دو طرفه (FULL DUPLEX) بین PC و دستگاه تامین میکنه

    Firmware :
    در شکل زیر نمایی از معماری USB CDC نشان داده شده :

    خوب چیزی که من متوجه شدم در ابتدای کار تابع main اجرا میشه توی این تابع مطابق با اونچه که در فایل main.c نوشته شده :

    [ltR]
    کد:
    int main(void)
    {
    
      Usb_enable_regulator();
    
    #ifndef  AVRGCC
       Wdt_off();
    #else
       wdt_reset();
       Wdt_clear_flag();
       Wdt_change_enable();
       Wdt_stop();
    #endif
       Clear_prescaler();
       scheduler();
       while(1){
         
       }
       return 0;
    }
    [/ltR]

    در ابتدا از آنجا که معمولا پیکره بندی تغذیه میکرو به صورت زیر انجام میشه (اینجا حداقل با توجه به بورد stk525,526) برای تغذیه USB Pad ها به ولتاژ 3.3 ولت نیاز داریم باید از رگولاتور داخلی میکرو استفاده کنیم برای این منظور باید همواره بیت REGDIS از رجیستر REGCR صفر شود که این کار با استفاده از ماکرو Usb_enable_regulator() که بدون ورودی و خروجی میباشد انجام میگردد .

    توجه : با یک کردن بیت REGDIS از رجیستر REGCR رگولاتور داخلی بای پس میشه و باید برای اجتناب از مصرف توان اضافی در صورت استفاده از پیکره بندی 3.3 ولت غیر فعال گردد برای اینکار میتوان از ماکروی Usb_disable_regulator ( ) استفاده کرد از طرفی بعد از ریست شدن برنامه این بیت صفر شده باید برنامه به گونه ای باشد که بتواند این بیت رو بعد از هرگونه ریست یک کند
    برای چک کردن صفر بودن این بیت یا به عبارت بهتر فعال بودن رگولاتور داخلی می توان از ماکروی Is_usb_regulator_enabled ( ) استفاده نمود .

    پس از فعال کردن رگولاتور داخلی پرسکالر داخلی فرکانس اوسیلاتور با استفاده از ماکروی Clear_prescaler ( ) ریست میشه و مقدار پرسکالر برابر با 1 میشود .

    سپس با اجرای تابع scheduler() ابتدا تنظیمات مربوط به زمانبندی اجرای تمام task ها انجام شده و سپس اجرا می گردد .
    -----------------------------------------------
    خوب اونچه من متوجه شدم اینه که اینجا ما یک سیستم داریم که از یک مجموعه task تشکیل شده که با استفاده از زمانبند"scheduler" کل زمان اجرا application بین شون تقسیم میشه که فکر میکنم این همون مفهوم سیستم های embedded باشه .
    _______________________________________
    به این ترتیب بعد از انجام تنظیمات زمانبند و اجرای اون میکرو وارد فاز اجرایی اصلی میشه که در ابتدا با انجام شمارش پورت usb توسط pc شناسایی شده و سپس ادامه کار سیستم به ترتیبی که usb_task مطابق اونچه که من از عکس بالا متوجه میشم وظیفه انجام مراحل شمارش و cdc_task وظیفه انجام عملیات cdc رو برعهده داره .

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

    مطابق اونچه در این فایل آمده :

    [ltR]
    کد:
    void cdc_task_init(void)
    {
       uart_init();
       Leds_init();
       Joy_init();
       Hwb_button_init();
       Usb_enable_sof_interrupt();
    #ifdef AVRGCC
     	fdevopen(uart_usb_putchar,uart_usb_getchar); //for printf redirection 
    #endif
    }
    
    
    
    //! @brief Entry point of the uart cdc management
    //!
    //! This function links the uart and the USB bus.
    //!
    //! @param none
    //!
    //! @return none
    void cdc_task(void)
    {
       if(Is_device_enumerated()) //Enumeration processs OK ?
       {
          if(cpt_sof>=NB_MS_BEFORE_FLUSH && tx_counter!=0 )  //Flush buffer in Timeout
          {
       	   cpt_sof=0;
    		   uart_usb_flush();
          }
          
    	   if (uart_test_hit())    //Something on USART ?
      	   {
      		   uart_usb_putchar(uart_getchar());   // Loop back, USART to USB
             Led0_toggle();
      	   }
       
          if (Uart_tx_ready())    //USART free ?
          {
             if (uart_usb_test_hit())   // Something received from the USB ?
    	      {
    	 	      while (rx_counter)
    		      {
    			      uart_putchar(uart_usb_getchar());   // loop back USB to USART
                   Led3_toggle();
    		      }
    	      }
          }
    
          if ( cpt_sof>=REPEAT_KEY_PRESSED)   //Debounce joystick events
          {
           
            
          
             if (Is_joy_select())
             printf ("Select Pressed !\r\n");
    
             if (Is_joy_right())
             printf ("Right Pressed !\r\n");
       
             if (Is_joy_left())
             printf ("Left Pressed !\r\n");
    
             if (Is_joy_down())
             printf ("Down Pressed !\r\n");
    
             if (Is_joy_up())
             printf ("Up Pressed !\r\n");
    
             if(Is_hwb())
             printf("Hello from AT90USBXXX !\r\n");
          }
       }
       
    }
    [/ltR]


    cdc_task_init : این تابع آماده سازی سخت افزار های جانبی که به دستگاه متصل شدند و همچنین مقدار دهی اولیه پارامتر های cdc رو برعهده داد .

    cdc_task : این تابع وظیفه مدیریت ارسال داده رو از دو طریق پروت کام مجازی و uart to usb bridge برعهده داره


    پایان قسمت دوم

  19. کاربران : 2 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  20. #10
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    uart_usb_lib :

    کاری که در این فایل انجام میشه کنترل توابع UART USB هست که شامل توابع زیر میشه :

    1.(void uart_usb_init (void : این تابع با مقدار دهی متغیرهای مورد استفاده در کتابخانه uart_usb وظیفه آماده سازی رو برعهده دارد به ترتیبی که در کد زیر مشاهده میکنید :
    [ltR]
    کد:
    00033 void uart_usb_init(void)
    00034 {
    00035   tx_counter = 0;
    00036   rx_counter = 0;
    00037 }
    [/ltR]
    توجه : متغیر های tx_counter و rx_counter در تمام مکان ها از نوع unsigned char تعریف شده اند .

    2.(bit uart_usb_test_hit (void : این تابع این مسئله را چک میکند که آیا اصلا اطلاعاتی بر روی باس usb دریافت شده یا خیر که اگر یک بایت داده آماده خواندن باشد خروجی تابع true خواهد بود .

    3. (char uart_usb_getchar(void : این تابع یک بایت داده رو از روی usb bus میخونه به این ترتیب که اگر یک بایت داده داخل بافر usb fifo موجود باشه تابع ابن بایت رو برمی گردونه و اگر داخل بافر داده برای خوندن آماده نباشه با توجه به(while (!uart_usb_test_hit()منتظر ممیونه تا داده بر روی باس قرار بگیره و آماده خوندن بشه و پس از آماده شدن داده اون رو برمیگردونه

    4. (bit uart_usb_tx_ready(void : این تابع چک میکنه که آیا یک بایت داده میتونه داخل اندپوینت fifo ورودی نوشته بشود یا خیر که اگر خروجی این تابع true باشه یعنی برنامه میتونه یک بایت داده جدید رو داخل اندپوینت ورودی برای ارسال بنویسه .

    5.(int uart_usb_putchar(int data_to_send : این تابع بایت رو در قالب پارامتر داخل اندپیونت ورودی مینویسد در واقع این تابع بعد از آماده شدن اندپوینت برای نوشتن داده اون رو داخل اندپوینت قرار میده و بعد ارسال میکنه برای انجام این کار ابتدا توسط تابع (Usb_write_byte(data_to_send داده ها داخل اندپوینت قرار گرفته همزمان برای خالی کردن بافر و فرستادن آن برای ارسال داده ها تابع uart_usb_flush() رو قبل از اتمام انتظار برای اتمام ارسال داده انجام میده .
    توجه : این تابع با استفاده از تعریف #define uart_usb_putchar putchar داخل فایل uart_usb_lib.h به جای تابع putchar عمل خواهد کرد بنابراین یاز هم میتوان از تابعی مثل printf که بر مبنای این تابع نوشته شده برای ارسال داده استفاده نمود مانند آنچه که در فایل cdc_task.c وجود دارد که برای ارسال مثلا رشته Hello from AT90USBXXX ! از تابع printf به صورت زیر استفاده کرده .
    [ltR]
    if(Is_hwb())
    printf("Hello from AT90USBXXX !\r\n");
    [/ltR]

    6.(void uart_usb_flush (void : این تابع داده های ذخیره شده داخل اندپوینت ورودی رو ارسال میکنه .

    پایان قسمت سوم

    پایان avr272


    4.

  21. کاربران : 3 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  22. #11
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    AVR276
    USB Software Library for AT90USBxxx
    Microcontrollers

    در ابتدا چند تا اصطلاح و چند مورد که در سریع تر خوندن کد ها کمک میکنه معرفی شده :

    1. VID: USB Vendor Identifier ( شماره مشخصه فروشنده )
    2. PID: USB Product Identifier ( شماره مشخصه محصول )

    در تمام فایل ها ثوابت با حروف بزرگ تعریف شده اند مانند فرکانس کار میکرو :
    #define FOSC 8000

    توابعی ماکرو تنها حرف اولشان با حروف بزرگ تعریف شده اند مانند تابع زیر :
    #define Is_usb_sof() ((UDINT & MSK_SOFI) ? TRUE: FALSE)

    برنامه کاربر میتونه یکسری توابع خاصی رو که نیاز به زمان کوتاهی برای اجرا دارند رو همزمان با اجرای یکسری رخ دادهای usb که لیست اون ها رو در زیر میبینید رو اجرا کنه :
    کد:
    #define Usb_sof_action()       
    #define Usb_wake_up_action()
    #define Usb_resume_action()
    #define Usb_suspend_action()
    #define Usb_reset_action()
    #define Usb_vbus_on_action()
    #define Usb_vbus_off_action()
    #define Usb_set_configuration_action()
    به عنوان مثال :
    کد:
    #define Usb_sof_action()         sof_action();
    توجه : این تعاریف در فایل conf_usb.h انجام میشوند .

    برای تغییر هر کدام از توصیف گر های رشته باید از تابع ماکروی Usb_unicode() استفاده نمود به عنوان مثال :
    کد:
    #define USB_PRODUCT_NAME \
    { Usb_unicode('A') \
     ,Usb_unicode('V') \
     ,Usb_unicode('R') \
     ,Usb_unicode(' ') \
     ,Usb_unicode('U') \
     ,Usb_unicode('S') \
     ,Usb_unicode('B') \
     ,Usb_unicode(' ') \
     ,Usb_unicode('C') \
     ,Usb_unicode('D') \
     ,Usb_unicode('C') \
     ,Usb_unicode(' ') \
     ,Usb_unicode('D') \
     ,Usb_unicode('E') \
     ,Usb_unicode('M') \
     ,Usb_unicode('O') \
    }
    USB Bus :

    Bus topology :

    دستگاه usb مطابق شکل زیر میتونند به دو صورت روی باس usb قرار بگیرند :


    1.USB Host :
    در سیستم usb تنها یک میزبان (host) وجود دارد و به عنوان مستر عمل میکنه . ارتباط سیستم usb با میزبان توسط یک کنترل کننده (USB interface) انجام میشود که توسط نرم افزار و سخت افزار قابل پیاده سازی است .

    2. USB Device :
    دستگاه usb که حداکثر میتوانند 127 وسیله باشند به عنوان اسلیو روی باس usb عمل میکنند و هر وسیله دارای یک آدرس مشخص میباشد .

    که در اینجا میکرو های سری at90usb میتونند در دو مد USB Device و USB Host کار کند که البته در مد USB Host درستر هست که بگیم در مد USB Host تقلیل یافته چرا که reduced host controller تنها یک پورت usb منحصر بفرد دارد و نمیتواند با استفاده از هاب چندین دستگاه usb دیگر را میزبانی کنید . این به این معنی که reduced host controller تنها برای یک ارتباط منحصر بفرد بین دو نقطه از طریق یک پورت usb طراحی شده.
    توجه کنید که reduced host controller تنها دستگاه هایی را که VIDو PID آنها در لیست VID/PID برنامه موجود باشند ساپورت میکگنه و میتواند آنها رو شناسایی کند .
    همچنین AT90USBxxx USB software library قادر است که لیست CLASS/SUBCLASS/PROTOCOL از دستگاه usb مورد نظر را که در لیست VID/PID برنامه موجود باشند ساپورت نماید .

    در شکل زیر توپولوژی یک سیستم usb با میزبان تقلیل یافته نمایش داده شده است :


    به این ترتیب AT90USBxxx software library میتونه برای کار در سه مد زیر پیکره بندی بشه :
    1. USB device
    2. USB reduced host
    3. USB dual role device

    در مد سوم دو مد قبلی ساپورت میشوند و اینکه دستگاه در کدام مد کار میکند به این بستگی دارد که پایه ID در کانکتور USB به زمین متصل شده است یا خیر در صورتی که به زمین ومتصل باشد یا به عبارتی از کانکتور MiniA دستگاه در مد reduced host عمل خواهد کرد و در صورتی که به زمین متصل نشده باشد یا به عبارت دیگر از کانکتور mini B استفاده شده باشد دستگاه در مد device عمل خواهد کرد .
    در مورد انواع کانکتور های USB و نحوه اتصالات پایه های هر کدام به عکس زیر دقت بفرمایید :


    پایان قسمت اول

  23. کاربران : 4 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  24. #12
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    USB Descriptors :
    در طول مراحل سرشماری میزبان چندتا از توصیفگرهای دستگاه رو از اون درخواست میکنه تا بتونه اون رو به درستی شناسایی و درایور درست رو برای راه اندازیش لود بکنه . به طور کلی هر دستگاه USB باید توصیفگرهای نشان داده شده در شکل زیر رو دارا باشه تا توسط میزبان قابل شناسایی باشه و اون رو شناسایی کنه


    مشکلترین قسمت کار نوشتن برنامه برای ارتباط با پورت USB اینه که بتونه تعیین کنه توصیفگرهای دستگاه باید چی باشند هر دستگاه USB برای اتصال به میزبان نیاز به فرایندی داره که سرشماری (enumeration) نامیده میشه .که البته AT90USBxxx software library تمام مراحل انجام سرشماری رو برای هر دو مد device و reduced host فراهم میکنه و به این ترتیب طی مراحل سرشماری توصیفگرهای دستگاه به میزبان ارسال میشه طوری که هر توصیفگر معادل یک آدرس منحصر به فرد هست .

    توصیفگرهای دستگاه (Device Descriptor) :

    هر دستگاه USB تنها میتونه یک توصیفگر دستگاه باشه ، این توصیفگر اطلاعاتی در رابطه با ورژن USB ، ماکزیمم اندازه هر بسته اطلاعات اندپوینت صفر ، VID ، PID ، ورژن دستگاه ، تعداد پیکره بندی های ممکن که دستگاه اون ها رو شامل میشه و چند توصیفگر دیگر در جدول زیر فرمت این توصیفگر نشان داده شده است :


    توصیفگر پیکره بندی (Configuration Descriptor) :
    هر دستگاه usb میتواند بیشتر از یک توصیفگر پیکره بندی داشته باشد البته اکثر دستگاه های usb تنها دارای یک توصیفگر پیکره بندی میباشند . این توصیفگر همونطور که از اسمش پیداس برای مواردی چون مد تغذیه دستگاه ، اینکه دستگاه خود بایاس باشه یعنی از تغذیه روی باس USB استفاده نمی کنه و یا اینکه از تغذیه باس استفاده میکنه ، اگر دستگاه خود بایاس هست حداکثر توانی که میتونه از باس دریافت کنه (ماکزیمم جریان دریافتی از باس ) چقدر هست ، تعدا واسط های موجود ، اندازه کل بایت های داده بازگشتی از دستگاه که شامل مجموع بایت های توصیفگرهای پیکره بندی ، واسط و اندپوینت می باشد و چند مورد دیگر که در جدول زیر به اختصار توضیح داده شده اند :



    توصیفگر واسط (Interface Descriptor ) :
    هر دستگاه میتواند بیش از یک واسط داشته باشد اطلاعات اصلی که توسط این توصیفگر منتقل می شود تعداد اندپوینت های دستگاه به غیر از اندپوینت صفر و همچنین اینکه usb تو چه کلاس و زیر کلاسی داره کار میکنه و موارد دیگه که در جدول زیر به اختصار توضیح داده شده اند :



    توصیفگر اندپوینت (Endpoint Descriptor) :
    این توصیفگر برای توصیف پارامترهای اندپوینت دستگاه استفاده میشه مانند : جهت اندپوینت اینکه ورودی هست یا خروجی ، آدرس اندپوینت ، نوع ارسال داده اینکه ارسال کنترلی ، توده ای ، وقفه ای و یا اینکه همزمان هست .حداکثر اندازه بسته ای که اندپوینت در یک ترنزکشن پشتیبانس میکنه ، فاصله زمانی مابین انتقال داده ها در مد ارسال وقفه ای و موارد دیگر که به اختصار در جدول زیر توضیح داده شده اند :




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


    پایان قسمت دوم (AVR276)

  25. کاربران : 6 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  26. #13
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    آقا من راستش دیگه با این مثال اتمل حال نکردم رفتم سراغ همون LUFA ، خوب این چند تا مزیت داره اولا اینکه برای کار تو کلاس ها مختلف مثال داره دومم اینکه خود آقا DEAN CAMERA حی و حاضر اند و هر سوالی داشتیم از خودشون میتونیم بپرسیم .


    پس از این جا به بعد این تاپیک متمرکز میشه به "کار با LUFA "؛
    کار با LUFA
    قسمت اول
    اجرای VirtualSerial

    با یه مثال که برای کار با کلاس CDC هست شروع میکنم :
    اما کسایی که میخوان استفاده کنند:
    1. اول آخرین ورژن LUFA رو از سایت آقای Dean Camera

    (Four Walled Cubicle - LUFA (Formerly MyUSB


    2. برای کار با LUFA یا از WINAVR یا AVRSTUDIO استفاده میکنیم .
    3. برای شروع از مثال VirtualSerial استفاده میکنیم این مثال تو مسیر زیر واقع شده :
    \LUFA-120219\Demos\Device\ClassDriver\VirtualSerial
    4.بعد makefile اش رو بازمیکنید و اگه میکروتون با پیشفرض فرق داشت اسم میکرو رو عوض میکنید ، اینجا :
    کد:
    # MCU name
    MCU = at90usb162
    5. برنامه برای at90usb1287 نوشته شده و پیکره بندی سخت افزارش هم با توجه به پایه های این میکرو در بورد USBKEY انجام شده از این جهت اگه میکرو رو عوض کنید احتمال داره که پایه هایی که تو پیکره بندی سخت افزار ازشون استفاده شده تو میکرو جدید موجود نباشند که موقع کامپایل دقیقا با کلیک بر روی ارور مربوطه میتونید به اون جا که اون پایه تعریف شده مراجعه کنید و اون رو تغییر بدید مثلا من با at90usb162 کار میکنم بعد از کامپایل به من میگه که میکرو شما porte نداره و بعد من هم امدم فایل Joystick.h که تو مسیر : LUFA-120219\LUFA\Drivers\Board\AVR8\USBKEY قرار گرفته رو به صورت زیر اصلاح کردم تا بتونم مثال خودش رو اجرا کنم ؛
    [ltr]
    کد:
    /* Private Interface - For use in library only: */
        #if !defined(__DOXYGEN__)
            /* Macros: */
                #define JOY_BMASK                 ((1 << 2) | (1 << 3) | (1 << 4))
                #define JOY_EMASK                 ((1 << 1) | (1 << 0))
    
                #define JOY_PORTE_MASK_SHIFT      0
        #endif
    
        /* Public Interface - May be used in end-application: */
            /* Macros: */
                /** Mask for the joystick being pushed in the left direction. */
                #define JOY_LEFT                  (1 << 0)
    
                /** Mask for the joystick being pushed in the right direction. */
                #define JOY_RIGHT                ((1 << 1) >> JOY_PORTE_MASK_SHIFT)
    
                /** Mask for the joystick being pushed in the upward direction. */
                #define JOY_UP                    (1 << 2)
    
                /** Mask for the joystick being pushed in the downward direction. */
                #define JOY_DOWN                 ((1 << 3) >> JOY_PORTE_MASK_SHIFT)
    
                /** Mask for the joystick being pushed inward. */
                #define JOY_PRESS                 (1 << 4)
    
            /* Inline Functions: */
            #if !defined(__DOXYGEN__)
                static inline void Joystick_Init(void)
                {
                    DDRB  &= ~JOY_BMASK;
                    DDRB  &= ~JOY_EMASK;
    
                    PORTB |=  JOY_BMASK;
                    PORTB |=  JOY_EMASK;
                }
    
                static inline void Joystick_Disable(void)
                {
                    DDRB  &= ~JOY_BMASK;
                    DDRB  &= ~JOY_EMASK;
    
                    PORTB &= ~JOY_BMASK;
                    PORTB &= ~JOY_EMASK;
                }
    
                static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
                static inline uint8_t Joystick_GetStatus(void)
                {
                    return (((uint8_t)~PINB & JOY_BMASK) | (((uint8_t)~PINB & JOY_EMASK) >> JOY_PORTE_MASK_SHIFT));
                }
            #endif
    6. بعد پروزه رو کامپایل میکنید .
    7. من برای پروگرام کردن از flip استفاده میکنم ،اگه شما هم میخوایید با flip کار کنید و اگه فلیپ رو ندارید اون رو از سایت اتمل دانلود و نصبش کنید و درایورش رو هم نصب کنید .

    8. حالا میکرو رو با فیلیپ پروگرام میکنیم بعد روی start کلیک میکنیم بعداز چند لحظه میکرو به عنوان یه device توسط pc با عنوان "lufa cdc demo" شناسایی میشه .

    9. حالا باید درایور device جدید رو نصب کنیم برای اینکار درایور که تو مسیر : \LUFA-120219\Demos\Device\ClassDriver\VirtualSerial رو انتخاب و نصب میکنید.

    10. به این ترتیب device جدید با عنوان "Communications Port" شناخته میشه .

    11. حالا برای تست یه نرم افزار برای ارتبط با پورت سریال تهیه کنید بعد تنظیمات اون رو متناسب با تنظیمات device مون انجام بدید بعد هم کانکت بشید ،اگه فایل Joystick.h رو طوری که من گفتم پیکره بندی کرده باشید
    با صفر شدن به ترتیب پایه های : PB0 , PB1 , PB2 ,PB3 , PB4 تو محیط ترمینال به ترتیب موارد زیر به نمایش در میان :

    کد:
    Joystick Left
    
    Joystick Right
    
    Joystick Up
    
    Joystick Down
    
    Joystick Pressed
    انشالله تو قسمت بعدی برنامه این مثال و توابع و تعارفی که در این مثال استفاده شده رو مورد بررسی قرار میدیم .

    پایان قسمت اول کار با LUFA

  27. کاربران : 2 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  28. #14
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    2.بررسی مثال VirtualSerial (بخش اول)
    خوب بیایید فایل سورس برنامه رو ببینیم توش چه خبره ،

    خوب اولش که امده VirtualSerial.h رو اینکلود کرده ، پس بریم ببینیم تو این چه خبره ،
    تو فایل هدر VirtualSerial.h اول امده فایل های هدر معمول مورد نیاز که تو دایرکتوری اصلی نرم افزار هستند رو اینکلود کرده ، به ترتیب زیر :

    کد:
    #include <avr/io.h>
            #include <avr/wdt.h>
            #include <avr/power.h>
            #include <avr/interrupt.h>
            #include <string.h>
            #include <stdio.h>
    بعد فایل هدر Descriptors.h رو اینکلود کرده تو این فایل همونطور که قبلا تو چند پست پیش گفته شد تنظیمات مربوط به توصیفگرها انجام شده ، پسر خوبیه کاری به کارش نداریم
    که به صورت زیر اینکلود شده :

    کد:
    ##include "Descriptors.h"
    بعد از این هدر مربوط به ورژن lufa هست که در اون اطلاعات مربوط به ورژن ، روز ،ماه و سال انتشار قرار گرفته و به صورت زیر اینکلود شده :

    کد:
    #include <LUFA/Version.h>
    بعد از این فایل های هدر مربوط به پیکره بندی سخت افزار مورد استفاده قرا گرفته که به قرار زیر هستند :

    کد:
        #include <LUFA/Drivers/Board/LEDs.h>
            #include <LUFA/Drivers/Board/Joystick.h>
    تو فایل هدر اول اطلاعات مربوط به پیکره بندی led ها قرار گرفته و تو فایل دوم اطلاعات مربوط بهJoystick که یه صفحه کلید 5 کلیدی هست .
    تو فایل اول رو که نگاه کنید میبیند که میاد با توجه به سخت افزار انتخاب شده تو میک فایل سخت افزار مورد استفاده رو تشخیص میده و بعد میره به فایل هدر مربوط به پیکره بندی led های اون سخت افزار و پیکره بندی اون رو برای اعمال دستور ات برنامه به پورت ها جهت خاموش و روشن کردن led ها در نظر میگره ،خوب تو اینجا به صورت پیشفرض چون تو میک فایل سخت افزار مورد نظر USBKEY انتخاب شده ،تو این قسمت از میک فایل :

    کد:
    # Target board (see library "Board Types" documentation, NONE for projects not requiring
    # LUFA board drivers). If USER is selected, put custom board drivers in a directory called
    # "Board" inside the application directory.
    BOARD = USBKEY
    تنظیمات بورد توسعه USBKEY اعمال میشه . البته میتونیم فایل هدر سخت افزار خودمون رو درست کنیم و اون رو وارد فایل هدر کنیم و تو میک فایل اون رو انتخاب کنیم ، اما من اینجا از همین استفاده میکنم و تنظیمات خودم رو تو همون اعمال میکنم مثلا پورت هایی که led ها از شماره یک تا سه به اون متصل هستند رو پورت d و پین های صفر تا سه انتخاب کردم ، به صورت زیر :
    تنظیمات اعمال شده در فایل هدر به آدرس : LUFA-120219\LUFA\Drivers\Board\AVR8\USBKEY

    کد:
    /* Public Interface - May be used in end-application: */
            /* Macros: */
                /** LED mask for the first LED on the board. */
                #define LEDS_LED1        (1 << 0)
    
                /** LED mask for the second LED on the board. */
                #define LEDS_LED2        (1 << 1)
    
                /** LED mask for the third LED on the board. */
                #define LEDS_LED3        (1 << 2)
    
                /** LED mask for the fourth LED on the board. */
                #define LEDS_LED4        (1 << 3)
    
                /** LED mask for all the LEDs on the board. */
                #define LEDS_ALL_LEDS    (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4)
    
                /** LED mask for none of the board LEDs. */
                #define LEDS_NO_LEDS     0
                
                ,
                
                static inline void LEDs_Init(void)
                {
                    DDRD  |=  LEDS_ALL_LEDS;
                    PORTD &= ~LEDS_ALL_LEDS;
                }
    
                static inline void LEDs_Disable(void)
                {
                    DDRD  &= ~LEDS_ALL_LEDS;
                    PORTD &= ~LEDS_ALL_LEDS;
                }
    
                static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
                {
                    PORTD |= LEDMask;
                }
    
                static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
                {
                    PORTD &= ~LEDMask;
                }
    
                static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
                {
                    PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask);
                }
    
                static inline void LEDs_ChangeLEDs(const uint8_t LEDMask,
                                                   const uint8_t ActiveMask)
                {
                    PORTD = ((PORTD & ~LEDMask) | ActiveMask);
                }
    
                static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
                {
                    PORTD ^= LEDMask;
                }
    
                static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
                static inline uint8_t LEDs_GetLEDs(void)
                {
                    return (PORTD & LEDS_ALL_LEDS);
                }
    و به همین ترتیب تنظیمات مربوط به Joystick در فایل هدر Joystick.h قرار گرفته ، که من تنظیمات خودم رو به صورت زیر تو فایل هدر مربوط به بورد توسعهusbkey رو به صورت زیر اعمال کردم :
    LUFA-120219\LUFA\Drivers\Board\AVR8\USBKEY

    کد:
    /* Private Interface - For use in library only: */
        #if !defined(__DOXYGEN__)
            /* Macros: */
                #define JOY_BMASK                 ((1 << 2) | (1 << 3) | (1 << 4))
                #define JOY_EMASK                 ((1 << 1) | (1 << 0))
    
                #define JOY_PORTE_MASK_SHIFT      0
        #endif
    
        /* Public Interface - May be used in end-application: */
            /* Macros: */
                /** Mask for the joystick being pushed in the left direction. */
                #define JOY_LEFT                  (1 << 0)
    
                /** Mask for the joystick being pushed in the right direction. */
                #define JOY_RIGHT                ((1 << 1) >> JOY_PORTE_MASK_SHIFT)
    
                /** Mask for the joystick being pushed in the upward direction. */
                #define JOY_UP                    (1 << 2)
    
                /** Mask for the joystick being pushed in the downward direction. */
                #define JOY_DOWN                 ((1 << 3) >> JOY_PORTE_MASK_SHIFT)
    
                /** Mask for the joystick being pushed inward. */
                #define JOY_PRESS                 (1 << 4)
    
            /* Inline Functions: */
            #if !defined(__DOXYGEN__)
                static inline void Joystick_Init(void)
                {
                    DDRB  &= ~JOY_BMASK;
                    DDRB  &= ~JOY_EMASK;
    
                    PORTB |=  JOY_BMASK;
                    PORTB |=  JOY_EMASK;
                }
    
                static inline void Joystick_Disable(void)
                {
                    DDRB  &= ~JOY_BMASK;
                    DDRB  &= ~JOY_EMASK;
    
                    PORTB &= ~JOY_BMASK;
                    PORTB &= ~JOY_EMASK;
                }
    
                static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
                static inline uint8_t Joystick_GetStatus(void)
                {
                    return (((uint8_t)~PINB & JOY_BMASK) | (((uint8_t)~PINB & JOY_EMASK) >> JOY_PORTE_MASK_SHIFT));
                }
            #endif
    بعد از این فایل هدر USB.h به ترتیب زیر اینکلود شده :

    کد:
    #include <LUFA/Drivers/USB/USB.h>
    تو این فایل هدر ، هدر تمامی کتابخانه های مورد نیاز برای کار با پورت usb تو تمامی کلاس ها اینکلود شده و دیگه نیازی نیست که برای مثلا یک کار خاص فایل های هدر مورد نیاز رو به صورت جداگانه اینکلود کنیم ، به این ترتیب در صورت استفاده از پورت usb باید در ابتدای برنامه اینکلود بشه .
    بعد از اینها 4 تا ماکرو داریم به قرار زیر:

    کد:
    /* Macros: */
            /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
            #define LEDMASK_USB_NOTREADY      LEDS_LED1
    
            /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
            #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
    
            /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
            #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
    
            /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
            #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
    ماکرو اول میاد led شماره یک رو روشن میکنه ، خوب روشن شدن این ماکرو تو برنامه تو جایی استفاده شده که با روشن کردن led شماره یک به ما اطلاع میده که پورت usb قابل استفاده نیست و ارتباط برقرار نشده .

    تو ماکرو دوم led های 2 و 3 روشن میشن ، خوب روشن شدن این دو led با هم به این معنی هست که دستگاه ما در حال انجام مرحله سرشماری هست و هنوز ارتباط برقرار نشده .
    ماکرو سوم led های 2 و 4 رو روشن میکنه و روشن شدن این دو با هم به معنی اتمام سرشماری و برقراری ارتباط موفق با پورت کام هست و میشه با pc از طریق یه اینترفیس با میکرو ارتباط برقرار کرد .
    ماکروی چهارم led 1 و 3 روشن میکنه روشن شدن این دو led با هم یعنی اینکه مراحل سرشماری تمام شده اما موقع برقرای ارتباط با مشکل مواجه شده و عیب رو باید در این مرحله جستجو کرد.

    خوب بعد از این ماکرو ها پروتوتایپ توابعی که البته 4 تای آخر رخداد هستند که تو برنامه استفاده شدند نوشته شده اند که به قرار زیر هستند :

    کد:
    /* Function Prototypes: */
            void SetupHardware(void);
            void CheckJoystickMovement(void);
    
            void EVENT_USB_Device_Connect(void);
            void EVENT_USB_Device_Disconnect(void);
            void EVENT_USB_Device_ConfigurationChanged(void);
            void EVENT_USB_Device_ControlRequest(void);
    خوب اول اینکه تمام توابع و رخدادها بدون ورودی و خروجی هستند .

    تابع اول ،SetupHardware :
    با فراخونی این تابع تنظیمات سخت افزاری میکرو و بورد انجام میشه .

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

    خوب قبل از اینکه رخداد ها رو بررسی کنیم ،هر کدام از این رخداد ها یا به اصطلاح USB Events مربوط به یک از اتفاقات جاری در پورت usb هستند مثل متصل شدن ، قطع شدن ، سرشماری و... .

    رخداد اول ، EVENT_USB_Device_Connect :
    این رخداد موقع اتصال میکرو به پورت usb فراخونی میشه و هرچی داخل اون باشه اجرا میشه
    توجه کنید که این رخداد time-critical هست و نباید اجرای اون بیشتر از 2 ثانیه طول بکشه ، در غیر اینصورت مراحل سرشماری بدرستی انجام نمیشه.

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

    رخداد سوم، EVENT_USB_Device_ConfigurationChanged :
    این رخداد زمانی رخ میده که شماره پیکره بندی تغییر کنه ، با وقوع این تغییر این رخداد به وقوع می پیونده و باید در روال اون کلاسی که میخواهیم میکرو در اون کار کنه رو انتخاب کنیم و توسط تابع CDC_Device_ConfigureEndpoints پیکره بندی مورد نظر رو بروی اندپوینت ها انجام بدیم که اگر درست اجرا بشه خروجی این تابع "TRUE" و در غیر این صورت "FALSE" خواهد بود .
    توجه کنید که این رخداد time-critical هست و نباید اجرای اون بیشتر از 1 ثانیه طول بکشه ، در غیر اینصورت مراحل سرشماری بدرستی انجام نمیشه.

    رخداد چهارم ، EVENT_USB_Device_ControlRequest :
    این رخداد زمانی که میزبان یه درخواست رو برای اندپوینت کنترلی دستگاه USB ارسال میکنه رخ میده . تو این رخداد باید درخواست ارسالی با استفاده از تابع CDC_Device_ProcessControlRequest بررسی بشه ، ورودی این تابع کلاسی هست که توش کار میکنیم .
    توجه کنید که این رخداد time-critical هست و نباید اجرای اون بیشتر از 50ms طول بکشه ، در غیر اینصورت مراحل سرشماری بدرستی انجام نمیشه.

    پایان قسمت دوم

  29. کاربران : 3 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


  30. #15
    کاربر علاقه مند
    تاریخ عضویت
    Feb 2010
    نام
    eslamshahr
    نوشته ها
    21
    تشکر
    23
    تشکر شده 33 بار در 15 پست

    پیش فرض

    3.بررسی مثال VirtualSerial (بخش دوم )

    خوب حالا برمیگردیم داخل فایل سورس اصلی برنامه یعنی ، VirtualSerial.c :

    در ادامه فایل چیزی که میبینیم یه داده داریم که به صورت Structure که اون هم به صورت لانه ای تعریف شده ( چقدر خفنه !) که به قرار زیر هست :

    کد:
    typedef struct
                {
                    struct
                    {
                        uint8_t  ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
    
                        uint8_t  DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint. */
                        uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint. */
                        bool     DataINEndpointDoubleBank; /**< Indicates if the CDC interface's IN data endpoint should use double banking. */
    
                        uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint. */
                        uint16_t DataOUTEndpointSize;  /**< Size in bytes of the CDC interface's OUT data endpoint. */
                        bool     DataOUTEndpointDoubleBank; /**< Indicates if the CDC interface's OUT data endpoint should use double banking. */
    
                        uint8_t  NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used. */
                        uint16_t NotificationEndpointSize;  /**< Size in bytes of the CDC interface's IN notification endpoint, if used. */
                        bool     NotificationEndpointDoubleBank; /**< Indicates if the CDC interface's notification endpoint should use double banking. */
                    } Config; /**< Config data for the USB class interface within the device. All elements in this section
                               *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
                               */
                    struct
                    {
                        struct
                        {
                            uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_*
                                                    *   masks. This value is updated each time \ref CDC_Device_USBTask() is called.
                                                    */
                            uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_*
                                                    *   masks - to notify the host of changes to these values, call the
                                                    *   \ref CDC_Device_SendControlLineStateChange() function.
                                                    */
                        } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
    
                        CDC_LineEncoding_t LineEncoding; /** Line encoding used in the virtual serial port, for the device's information.
                                                          *  This is generally only used if the virtual serial port data is to be
                                                          *  reconstructed on a physical UART.
                                                          */
                    } State; /**< State data for the USB class interface within the device. All elements in this section
                              *   are reset to their defaults when the interface is enumerated.
                              */
                } USB_ClassInfo_CDC_Device_t;
    خوب اول ،
    مختصری در مورد Structure

    خوب ببینید ما تو زبان سی انواع داده داریم مثل char, int , float ,unsigned char,unsigned iint,long in و ... که همونطور که میدونید میتونیم با استفاده از پیشوندها ترکیبات جدید بسازیم اما اینها همگی به یک نوع داده خاص دلالت میکنند ، یعنی ما نمیتونیم تو یه داده از نوع int هم کاراکتر بریزیم هم عدد !

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

    خوب حالا این به خودش میگه چی میشد من یه متغیر داشتم که به اندازه آدم ها آرایه داشت و تو همون متغیر اطلاعات رو وارد میکردم . خوب این آقا چیزی که میخواد اینه که یه نوع داده باشه ، 120 بایتی ، که تو مثلا 100 بایت اولش بشه کارکتر گذاشت تو 20 بایت بعدش عدد بعد هم به صورت آرایه تک بعدی باشه و بعدش هم به اندازه تمام آدم ها باشه .

    خوب همونطور که میدونید ما همچین چیزی تو زبان سی نداریم ، پس باید این "نوع داده جدید رو ایجاد کنیم " این کار با استفاده از دستور struct به فرم کلی زیر انجام میشه :


    کد:
    struct "اسم نوع داده جدید"{
    
    لیست عناصر داده ;
    };
    مثلا فرض کنید میخواییم همین نوع داده ای که سازمان ثبت احوال لازم داره رو ایجاد کنیم ،مینویسیم :

    کد:
    struct personal{
    
    char first_name[20];
    char last_name[20];
    char father_name[20];
    int date_of_birth;
      
    };
    خوب این از نوع داده جدید .

    اما ما که صرفا نمیخواییم فقط یه نوع داده تعریف کنیم ،مگه نه !؟

    چیزی که سازمان ثبت احوال میخواست "یه متغیر با یه نوع داده جدید" بود.

    پس باید متغیر هامون رو هم با نوع داده جدید تعریف کنیم تا بتونیم ازشون برای کاری که می خواهیم استفاده کنیم .

    فرم کلی تعریف متغیر مثل تعریف متغیر های معمولی هست که به قرار زیر هست :

    کد:
    struct "اسم متغیر" "اسم نوع داده جدید"
    یا مثلا همون موقع که نوع رو ایجاد میکنیم ، پشت بندش متغیر ها مون رو هم تعریف میکنیم ، تو این حالت در صورت عدم نیاز به این نوع داده جدید برای تعریف متغیر هایی از این جنس داده در مکان های دیگه میتونیم از اسم نوع داده جدید فاکتور بگیریم و حذفش کنیم ، به صورت زیر :

    کد:
    struct {
    
    لیست عناصر داده ;
    } "اسم متغیر"
    خوب حالا میتونیم یه متغیر با اون نوع داده ای که سازمان ثبت احوال میخواست ایجاد کنیم ، اسم متغیر رو هم person میزاریم و از نوع personal(که قبلا این توع داده رو تعریفش کردیم) رو به صورت یه متغیر مثلا 1000 درایه ای که قراره تو هر داریه مشخصات یه نفر قرار بگیره ، به صورت زیر تعریف میکنیم :

    کد:
    struct personal person[1000];
    یا :


    کد:
    struct {
    
    char first_name[20];
    char last_name[20];
    char father's_name[20];
    int date_of_birth;
      
    }person[1000];
    خوب حالا برای دسترسی به هر کدوم از عناصر متغیر جدید مون که به صورت ساختمان داده هست باید از "." استفاده کنیم .

    مثلا فرض کنید که میخواییم اطلاعات شخص شماره 20 رو برای سازمان ثبت احوال ثبت کنیم ، داریم :

    کد:
    person[20].first_name="ali";
    person[20].last_name="taghipour";
    person[20].father_name="hasan";
    person[20].date_of_birth=1370;
    خوب حالا فرض کنید که سازمان احوال بخواد اطلاعات رو برحسب آدرس که شامل استان ، شهر ، خیابان ،کوچه و پلاک محل زندگی افراد sort کنه و همینطور تاریخ تولید افراد ، روز ، ماه و سالش هم مشخص باشه .

    خوب به نظرتون باید اینجا چه کار کرد !؟

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

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

    1. بیاییم اول ساختمان داده آدرس که شامل عناصر : استان ، شهر خیابان ، کوچه و پلاک هست به صورت زیر تعریف کنیم :

    کد:
    struct address {
    char town[20];
    char city[20];
    char street[20];
    char alley[20];
    int  no;
     
     };
    2. بیاییم ساختمان داده تاریخ رو با عناصر روز ، ماه و سال به صورت زیر تعریف کنیم :

    کد:
     struct date{
     
     int day;
     int month;
     int year;
     
     };
    3. حالا بیاییم ساختمان داده اصلی که متغیر مشخصات افراد از اون نوع تعیین میشه به صورت زیر بنویسیم :

    کد:
    struct {
    
    char first_name[20];
    char last_name[20];
    char father_name[20];
    struct  address addr;
    struct  date birth;  
    }person[1000];
    حالا بجای اینکه بیاییم جدا جدا ساختمان داده رو تعریف کنیم و بعد بیاییم از اون ساختمان دادهذ برای تعریف یه متغیر جدید داخل یه ساختمان داده دیگه استفاده کنیم اون ساختمان داده و متغیر از اون جنس رو هم داخل همون ساختمان داده اصلی تعریف میکنیم مثلا برای مثال قبل داریم :

    کد:
    struct {
    
        char first_name[20];
        char last_name[20];
        char father_name[20];
    
            struct {
                char town[20];
                char city[20];
                char street[20];
                char alley[20];
                int  no;
                }addr;
            
            struct{ 
                int day;
                int month;
                int year;
                }birth; 
     
    }person[1000];
    خوب حالا بیایید مثلا مشخصات همون نفر 20 ام رو دوباره وارد کنیم :

    کد:
    person[20].first_name="ali";
    person[20].last_name="taghipour";
    person[20].father_name="hasan";
    person[20].birth.day=31;
    person[20].birth.month=6;
    person[20].birth.year=1370;
    person[20].addr.town="Tehran";
    person[20].addr.city="Eslamshahr";
    person[20].addr.street="Emam khomyni";
    person[20].addr.alley="Shahid kazemi";
    person[20].addr.no=51;

    خوب تا همین جا از مبحث Structure برای کار ما تو اینجا کافیه .


    دوستان ببخشید دیگه کم آوردم ادامه باشه برای پست بعدی!انشالله.

    پایان قسمت سوم

  31. کاربران : 3 تشکر کرده اند از شما mojtaba_led برای ارسال این پست سودمند:


موضوعات مشابه

  1. مشکل با پورت usb مارس
    توسط roohlla در انجمن Cortex-a8-a9 arm9-11
    پاسخ: 3
    آخرين نوشته: 15-12-2013, 02:14
  2. مشکل پورت شبکه مارس بورد
    توسط m0h3n در انجمن Cortex-a8-a9 arm9-11
    پاسخ: 8
    آخرين نوشته: 20-05-2013, 15:25
  3. ارتباط با پورت usb
    توسط mostafay در انجمن AT91 series (ATMEL)
    پاسخ: 2
    آخرين نوشته: 24-04-2013, 17:15
  4. مشکل با وقفه ی پورت کام
    توسط mehdiit در انجمن AVR
    پاسخ: 4
    آخرين نوشته: 29-03-2013, 21:53
  5. خواندن از پورتهای ورودی
    توسط naruto در انجمن میکرو کنترلر های 32 بیتی(arm)
    پاسخ: 4
    آخرين نوشته: 02-03-2011, 22:50

مجوز های ارسال و ویرایش

  • شما نمیتوانید موضوع جدیدی ارسال کنید
  • شما امکان ارسال پاسخ را ندارید
  • شما نمیتوانید فایل پیوست کنید.
  • شما نمیتوانید پست های خود را ویرایش کنید
  •