با سلام
چند روزی برای ایجاد ارتباط 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 ، کد ذیل عمل می کند:
همانطور که ذکر شد، مستر، شماره اندیس را به اسلیو می فرستد: در نتیجه با اجرای خط دستورالعمل ذیل:
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;"""""
: CPHA = 0 , CPOL = 1 : شرایط عملکرد صحیح می باشد.
2- در مود 2 (""""""""& quot;"""""""&qu ot;""""""
: CPHA = 1 , CPOL = 0 : شرایط عملکرد صحیح نیست.
3- در مود 3 (""""""""& quot;"""""""&qu ot;""""""
: 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 اسلیو را داشته باشیم.
با سپاس
چند روزی برای ایجاد ارتباط 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;"""""

2- در مود 2 (""""""""& quot;"""""""&qu ot;""""""

3- در مود 3 (""""""""& quot;"""""""&qu ot;""""""

در دو مود 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 اسلیو را داشته باشیم.
با سپاس
دیدگاه