اطلاعیه

Collapse
No announcement yet.

نکاتی از SPI در ATMEGA88PA

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

    نکاتی از SPI در ATMEGA88PA

    با سلام
    چند روزی برای ایجاد ارتباط SPI مناسب بین یک ATMEGA88PA به عنوان slave ,
    و یک AT91SAM7X256 به عنوان مستر ، در تلاش و کلنجار بودم.
    چند نکته برای کاربرد خاصی که مد نظر بود ، آشکار شد،
    برای جلوگیری از دوباره کاری و سر درگمی دوستان، نتایج را در این پست ارایه می نمایم.

    شرایط ارتباط SPI:

    1- هدف ، دریافت 64 بایت اطلاعات از ATMEGA88PA که نقش کمکی برای پردازنده اصلی را دارد ، می باشد.
    این 64 بایت که شامل مقادیر A2D از 8 کانال و تعدادی ورودی و خروجی دیجیتال می باشند که در آرایه برای هر دو طرف تعریف شده اند.

    2- تعداد دفعات مبادله ( بسته 64 بایتی داده ) ، 125 بار در ثانیه است. = 8000 بایت در ثانیه. = هر 8mS یک بسته 64 بایتی

    3- در طی مبادله 64 بایت ، SS/ توسط مستر ، در حالت LOW نگه داشته می شود.( بدون HIGH شدن در انتهای انتقال هر بایت بلکه در انتهای ارسال 64 بایت ، HIGH می شود)

    4- مستر ، محتوی بایتهای ارسالی به اسلیو را ( DUMMY DATA ) ، برای سهولت عملیات در اسلیو ، به صورت اندیسهای از 64 تا 127 در نظر گرفته و ارسال می کند.

    5- فرکانس کریستال ATMEGA88PA را 20 مگاهرتز قرار داده ایم.

    6- فرکانس SPCK را از طرف مستر ، 240KHZ قرار داده ایم.( 33 میکرو ثانیه برای انتقال 8 بیت )

    7- مدت ارسال یک بسته 64 بایتی نزدیک به 2.25mS می باشد.( با زمانهای تاخیر بین بایتها )

    8- در اسلیو ATMEGA88PA دو پایه INT0 , INT1 نیز برای اینتراپت خارجی منظور شده اند و برنامه اینتراپت برای هر کدام منظور شده است.

    9- برنامه دریافت SPI SLAVE به صورت اینتراپتی منظور شده است.

    10- با هر بار رسیدن یک بایت داده به اسلیو و فعال شدن SPIF ، کد ذیل عمل می کند:

    کد:
    interrupt [SPI_STC] void spi_isr(void)
    {
    // Place your code here
       
      spi_incoming = SPDR ;            // read the input data
    
      SPDR = spi_output_record[ (spi_incoming+1) & 0x3f ] ; // spi_buf_ptr ;  
      
    }
    
    
    از برنامه MAIN()
    
    PORTB=0x3F;
    DDRB=0x12;
    
    // SPI initialization
    // SPI Type: Slave
    // SPI Clock Phase: Cycle Start/half
    // SPI Clock Polarity: high/Low
    // SPI Data Order: MSB First
    
    //DDR_SPI = (1<<DD_MISO);
    //PORTB |= (1<<DD_MISO);
    //DDRB |= (1<<DD_MISO);
    
    SPCR=(1<<SPIE)|(1<<SPE)|(0<<DORD)|(0<<MSTR)|(0<CPOL)|(0<<CPHA)|(0<<SPR1) ;// 0xC0; // fosc/4 = 5 Mhz(for master only)
    SPSR=0x00;
    
    // Clear the SPI interrupt flag
    #asm
      in  r30,spsr
      in  r30,spdr
    #endasm
    همانطور که ذکر شد، مستر، شماره اندیس را به اسلیو می فرستد: در نتیجه با اجرای خط دستورالعمل ذیل:
    spi_incoming = SPDR ; // read the input data
    مقادیر متوالی spi_incoming : و64 و 65 و 66 و 67 و.....125 و 126 و 127 خواهند بود.

    و چون همواره اسلیو ، یک بایت عقب تر از مستر حرکت می کند ، شمارنده بافر یا آرایه 64 بایتی: (spi_incoming+1) & 0x3f
    = 1 و 2 و 3 و 4 و..... و 62 و 63 و 0 : ملاحظه می فرمایید که اندیس صفر ( اولین محل از آرایه ) در آخر آمده ،
    لذا ، داده موجود در خانه صفر از آرایه 64 بایتی را یک مقدار ثابت دایمی در نظر گرفتیم.

    با این خط:
    SPDR = spi_output_record[ (spi_incoming+1) & 0x3f ] ; // spi_buf_ptr ;
    داده مناسب از آرایه برداشته شده و در SPDR خروجی قرار می گیرد. و همزمان با شروع دریافت بایت بعدی ، به مستر ارسال می شود.

    نتیجه آزمون 4 مود :

    0- در مود 0 ( هر دو ، مستر و اسلیو ) : CPHA = 0 , CPOL = 0 : شرایط عملکرد صحیح می باشد.
    1- در مود 1 ( """"""""&q uot;"""""""&quo t;""""&quot : CPHA = 0 , CPOL = 1 : شرایط عملکرد صحیح می باشد.

    2- در مود 2 (""""""""& quot;"""""""&qu ot;"""""&quot : CPHA = 1 , CPOL = 0 : شرایط عملکرد صحیح نیست.
    3- در مود 3 (""""""""& quot;"""""""&qu ot;"""""&quot : CPHA = 1 , CPOL = 1 : شرایط عملکرد صحیح نیست.

    در دو مود 2 و 3 برای اطمینان ، اسلیو جداسازی شد و با اتصال MISO , MOSI در سمت مستر ، داده ارسالی به خوبی ، دریافت شد.( مستر سالم عمل می کند )


    در مود 2 و 3 ، اسلیو ، به جای داده صحیح که باید داده صحیح را از آرایه 64 تایی داخلی خود ، به شیفت رجیستر تحویل دهد ،!!!
    بایت دریافتی قبلی ، از مستر را ، با یک شیفت به چپ = ضربدر2 ، به مستر ارسال می کند!!!
    مانند: 128 و 130 و 132 و 134 و 136 و .... و 252 و 254 !!!

    یعنی انگار ، اصلا این خط وجود ندارد :
    SPDR = spi_output_record[ (spi_incoming+1) & 0x3f ] ; // spi_buf_ptr ;
    و احتمالا درون مدارات SPI خطای سخت افزاری وجود دارد! ( دوستان گرامی ، لطفا تجربیات خود را در این مورد مطرح فرمایند )




    11- در CODEVISION 2.05.3 همان چند خط کد سرویس اینتراپت ، 23 خط اسمبلی را شامل می شود.( حداقل 23 کلاک )
    در صورتیکه سایر اینتراپتها هر کدام بیش از 10 تا 15 خط اسمبلی را شامل باشند و تعداد دفعات رخداد آنها زیاد باشد،
    احتمال گم شدن داده به دلیل عدم پاسخ دهی سریع به اینتراپت SPI ، وجود دارد.( برای ورود و برگشت به سرویس اینتراپت نیز 8 کلاک لازم است )
    با رجوع به لینک ذیل و چند پست جناب طراح و جناب PERFECT باید امکان سرویس دهی به اینتراپت SPI را به صورت مناسب فراهم نمود.
    http://www.eca.ir/forum2/index.php?t...2177#msg272177
    http://www.eca.ir/forum2/index.php?t...9073#msg239073

    12- در مستر ، تا حد امکان تاخیرات پیش از ارسال هر بایت و پس از ارسال هر بایت ، منظور شده تا اسلیو فرصت بیشتری برای پردازش داشته باشد.


    چکیده:

    - SPI مود 0 و 1 ، قابل اطمینان تر است، مود 2 و 3 ، اشکال دارد.( در حالت سرویس اینتراپتی آزمایش شده )
    - اگر تعدادی اینتراپت پر تکرار و پر حجم در ATMEGA داریم ، باید تمهید مناسب برای سرعت در سرویس دهی به SPI اسلیو را داشته باشیم.

    با سپاس
    فایل های پیوست شده
    گشتی در لاله زار
    http://www.eca.ir/forum2/index.php?topic=76138.0

    http://www.eca.ir/forum2/index.php?topic=76141

    #2
    پاسخ : نکاتی از SPI در ATMEGA88PA

    اقا ممنون فقط نفهمیدم چرا فرمت عکسها jpeg هنگام باز کردن png شد با 6 برابر حجم اعلام شده یعنی در مجموع یک مگا.

    دیدگاه

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