SPI مخفف عبارت “Serial Peripheral Interface” به معنای “رابط وسایل جانبی سریال” می باشد. در SPI، یک Master و یک یا چند Slave داریم. Master همواره یک میکروکنترلر است و Slave نیز می تواند میکروکنترلر یا وسایل جانبی دیگر باشد. در این نوع ارتباط، Master تعیین کنندۀ Slave مورد نظر برای تبادل اطلاعات است. Master با صفر کردن یکی از پایه های Slave مورد نظر، با آن Slave به تبادل اطلاعات می پردازد. نوع انتقال اطلاعات در این نوع ارتباط، تمام دوطرفه (Full duplex) می باشد. SPI در ارتباط بین میکروکنترلر و وسایل جانبی دیگر (که از SPI پشتیبانی می کنند) مانند حافظه های SD (SD Card)، سنسورها، ADC های خارجی، نمایشگرها، ماژول های فرستنده و گیرندۀ رادیویی و …، در فواصل نزدیک کاربرد دارد. ارتباط SPI را ارتباط سه سیمه نیز می نامند. در SPI چهار پایه وجود دارد که برای انتقال اطلاعات و انتخاب Slave مورد استفاده می شوند: MOSI، MISO، SS و SCK. پایه های MISO و MOSI برای انتقال دیتا، پایۀ SS برای انتخاب Slave و پایۀ SCK نیز برای انتقال کلاک همزمان سازی از Master به Slave می باشد. برای این پایه ها ممکن است نام های دیگری در نظر بگیرند.
فیلم آموزش میکروکنترلرهای AVR مقدماتی
تصویر 1 – شبکۀ SPI و ارتباط بین Master و Slaveها
ویدئوی 1 – راه اندازی SPI در AVR و شرح نمونه کد Slave
در این نوشته می خواهیم به آموزش ارتباط SPI در AVR بپردازیم. برای این کار ارتباط SPI میکروکنترلرهای AVR را برای میکروکنترلر ATmega128 بررسی می کنیم. پروتکل SPI در میکروکنترلرهای AVR دارای امکانات و ویژگی هایی است که در ادامه مورد بررسی قرار می گیرند. در این نوشته علاوه بر پرداختن به مباحث تئوری ارتباط SPI میکروکنترلرهای AVR، دو تمرین برای درک بهتر موضوع SPI در میکروکنترلرهای AVR طرح کرده ایم. در این دو تمرین به کار با پروتکل SPI در CodeVisionAVR و همچنین استفاده از توابع SPI در کدویژن پرداخته شده است.
SPI در میکروکنترلر ATmega128
در میکروکنترلر ATmega128 یک واحد SPI با ویژگی های زیر وجود دارد:
- انتقال اطلاعات به صورت سنکرون سه سیمه و تمام دو طرفه؛
- عملکرد Master یا Slave؛
- انتقال دیتای 8 بیتی به دو صورت قابل انتخاب: ابتدا بیت پر ارزش و در آخر بیت کم ارزش و یا ابتدا بیت کم ارزش و در آخر بیت پر ارزش؛
- نرخ انتقال قابل برنامه ریزی؛
- وقفۀ اتمام انتقال؛
- پرچم تداخل دیتا؛
- بیدار شدن میکروکنترلر از مد Idle؛
- انتقال دیتا با سرعت دو برابر در مد Master.
بلوک دیاگرام SPI را در شکل زیر مشاهده می کنید.
تصویر 2 – بلوک دیاگرام واحد پروتکل SPI میکروکنترلر AVR ATmega128
شیفت رجیستر (Shift Register) یا رجیستر انتقالی
شیفت رجیسترها مجموعه ای از فلیپ فلاپ ها هستند که در کنار هم قرار گرفته اند و کار ذخیره و انتقال داده را انجام می دهند. داده ها (صفر و یک ها) با یک سیگنال کلاک از یک طبقۀ شیفت رجیستر به طبقه ای دیگر به ترتیب منتقل می شوند که به این عمل شیفت می گویند. چهار نوع کلی شیفت رجیستر وجود دارد که عبارتند از:
- شیفت رجیستر ورودی-سری، خروجی-سری (Serial-In , Serial-Out): در این شیفت رجیستر، داده ها با هر پالس سیگنال کلاک به صورت سری از ورودی وارد می شوند و به صورت سری از خروجی خارج می شوند.
- شیفت رجیستر ورودی-سری، خروجی-موازی (Serial-In , Parallel-Out): در این شیفت رجیستر، داده ها با هر پالس سیگنال کلاک به صورت سری از ورودی وارد می شوند و با یک پالس کلاک به صورت موازی از خروجی خارج می شوند.
- شیفت رجیستر ورودی-موازی، خروجی-سری (Parallel-In , Serial-Out): در این شیفت رجیستر، داده ها با یک پالس کلاک به صورت موازی از ورودی وارد می شوند و با هر پالس کلاک به صورت سری از خروجی خارج می شوند.
- شیفت رجیستر ورودی-موازی، خروجی-موازی (Parallel-In , Parallel-Out): در این شیفت رجیستر، داده ها با یک پالس کلاک به صورت موازی از ورودی وارد می شوند و با یک پالس کلاک به صورت موازی از خروجی خارج می شوند.
تصویر 3 – انواع شیفت رجیستر از لحاظ ورودی و خروجی
نحوه انتقال داده با SPI
در ارتباط SPI، انتقال داده به این صورت است که ابتدا Master که یک میکروکنترلر است، یک Slave را انتخاب می کند. برای این منظور یک پایه از چند پایۀ پورت I/O که به پایۀ SS هر Slave متصل است، صفر می شود. با صفر شدن پایۀ SS یک Slave، آن Slave انتخاب می شود. در Master و Slave یک شیفت رجیستر وجود دارد که داده ها به صورت موازی در آن ها قرار می گیرد و به صورت سریال از آنها خارج می شوند. پس از نوشتن یک بایت داده در رجیستر دادۀ Master، یک سیگنال کلاک روی پایۀ SCK تولید می شود. این کلاک توسط پایۀ SCK هر Slave دریافت می شود. با هر پالس کلاک، یک بیت از Master به Slave (روی پایۀ MOSI) منتقل می شود و همچنین به طور همزمان با انتقال یک بیت از Master به Slave، یک بیت از Slave به Master (روی پایۀ MISO) منتقل می شود. به این ترتیب دیتای Master در Slave و دیتای Slave در Master قرار می گیرد. در پایان نیز دیتای منتقل شده از دو شیفت رجیستر خوانده می شود. پس از خوانده شدن داده ها، می توان ارتباط را ادامه داد و یا آن را قطع کرد. برای قطع کردن ارتباط، کافی است پس از تبادل داده، پایۀ SS از Slave را در سطح منطقی 1 قرار داد.
نحوه انتقال داده در SPI میکروکنترلرهای AVR
در میکروکنترلرهای AVR و در ATmega128، ابتدا یک پایه از پورت I/O صفر می شود تا Slave مورد نظر انتخاب شود. سپس با نوشته شدن یک بایت داده در رجیستر دادۀ SPI، سیگنال کلاک روی پایۀ SCK تولید می شود و با هر پالس، یک بیت از Master به Slave و همچنین یک بیت از Slave به Master انتقال می یابد. انتقال دادۀ Master از پایۀ MOSI میکروکنترلر Master به سمت همان پایه از Slave و انتقال دادۀ Slave از پایۀ MISO المان Slave به سمت همان پایه از Master می باشد. پس از انتقال 8 بیت داده، تولید کلاک روی SCK متوقف می شود و پرچم SPIF (پرچم وقفۀ اتمام انتقال)، یک می شود. در این جا Master پایۀ SS المان Slave را یک می کند و آن را از حالت تبادل داده خارج می کند. در حالت ارسال تا موقعی که داده به طور کامل از رجیستر دادۀ SPI فرستاده نشود، نمی توان در آن مقدار جدیدی نوشت. و در حالت دریافت، باید داده را بلافاصله خواند تا داده های جدید روی آن نوشته نشوند. تصویر زیر تبادل داده را بین Master و Slave نشان میدهد.
تصویر 4 – مدار داخلی و نحوه انتقال داده در پروتکل SPI میکروکنترلر AVR ATmega128
نکته: میکروکنترلرهای AVR می توانند در مد Slave نیز باشند. در این صورت با یک میکروکنترلر Master به تبادل داده می پردازند. پایۀ SS در میکروکنترلرهای AVR نیز برای انتخاب شدن آنها توسط Master برای تبادل داده می باشد.
نکته: پروتکل SPI یک پروتکل 8 بیتی است. زیرا شیفت رجیستر آن 8 بیتی است. برای انتقال تعداد بیت های بیشتر باید چند بار تبادل داده را انجام داد.
پایه های مورد استفاده در SPI
در ارتباط SPI چهار پایه (به جز GND) استفاده می شوند:
MISO (SPI Bus Master Input / Slave Output): این پایه برای انتقال داده از Slave به Master است. در ATmega128 این پایه روی PB3 قرار دارد.
MOSI (SPI Bus Master Output / Slave Input): این پایه برای انتقال داده از Master به Slave است. در ATmega128 این پایه روی PB2 قرار دارد.
SCK (SPI Bus Serial Clock): این پایه برای انتقال کلاک از Master به Slave است. در ATmega128 این پایه روی PB1 قرار دارد.
SS(SPI Slave Select input): هنگامی که میکروکنترلر در مد Slave باشد، این پایه برای انتخاب شدن آن برای تبادل داده با Master است. همان طور که گفته شد، میکروکنترلر می تواند در مد Slave نیز باشد و با یک میکروکنترلر Master به تبادل داده بپردازد. در ATmega128 این پایه روی PB0 قرار دارد.
پایه های مورد استفاده در SPI به جز SS همگی به پایۀ هم نام خود وصل می شوند. یعنی در Master و Slave، پایۀ MISO به MISO، پایۀ MOSI به MOSI و پایۀ SCK به SCK وصل می شود. پایۀ SS در Slave باید به یکی از پایه های پورت I/O میکروکنترلر Master وصل شود. این پایه در Master نیز می تواند خروجی باشد و به SS المان Slave وصل شود و Slave را انتخاب کند و یا ورودی باشد که در این صورت باید پول آپ شود.
تعیین ورودی/خروجی بودن پایه های SPI در میکروکنترلر AVR
برای استفاده از SPI باید مطابق جدول زیر، پایه های SPI را ورودی یا خروجی کرد. ورودی یا خروجی بودن پایه های SPI، زمانی که میکروکنترلر در مد Master باشد با زمانی که در مد Slave باشد، متفاوت است. به جدول زیر توجه کنید.
توضیحات بعد از جدول آورده شده است.
ورودی یا خروجی بودن در مد Slave | ورودی یا خروجی بودن در مد Master | پایه |
ورودی | کاربر تعیین می کند | MOSI |
کاربر تعیین می کند | ورودی | MISO |
ورودی | کاربر تعیین می کند | SCK |
ورودی | کاربر تعیین می کند | SS |
جدول 1 – ورودی یا خروجی بودن پایه های SPI
این جدول بیانگر این است که:
الف) هنگامی که SPI در مد Master فعال می شود، سخت افزار فقط پایۀ MISO را ورودی می کند. کاربر باید در برنامه ورودی یا خروجی بودن پایه های دیگر را تعیین کند. پایه های MOSI و SCK باید خروجی شوند و پایۀ SS نیز می تواند ورودی یا خروجی باشد.
ب) هنگامی که SPI در مد Slave فعال می شود، سخت افزار پایه های MOSI، SCK و SS را ورودی می کند. کاربر باید در برنامه تعیین کند که پایۀ MISO خروجی باشد.
پس ورودی یا خروجی بودن پایه های SPI باید مطابق جدول زیر باشد.
ورودی یا خروجی بودن در مد Slave | ورودی یا خروجی بودن در مد Master | پایه |
ورودی | خروجی | MOSI |
خروجی | ورودی | MISO |
ورودی | خروجی | SCK |
ورودی | ورودی یا خروجی | SS |
جدول 2 – ورودی/خروجی بودن پایه های SPI
عملکرد SPI در مد Master
در این مد، میکروکنترلر Master است و با Slave ها به تبادل داده می پردازد. پایۀ SS هر Slave به پایه های پورت I/O میکروکنترلر Master متصل هستند. در Master پایه های پورت I/O خروجی می شوند و در سطح منطقی 1 قرار می گیرند. هرگاه میکروکنترلر Master بخواهد با یک Slave تبادل داده کند، پایۀ خروجی را که به SS آن Slave متصل است صفر می کند تا آن Slave برای تبادل داده آماده شود.
هنگامی که میکروکنترلر در مد Master است، پایۀ SS می تواند خروجی تعریف شود و به وسیلۀ آن، یک Slave انتخاب شود. این امر در عملکرد در مد Master تأثیری ندارد.
در مد Master پایۀ SS می تواند ورودی هم باشد، اما باید با یک مقاومت پول آپ شود تا میکروکنترلر در مد Master بماند و در عملکرد Master اخلالی ایجاد نشود. اگر این پایه وقتی که ورودی است به هر دلیلی، از خارج صفر شود، میکروکنترلر وارد مد Slave می شود و به عنوان Slave آمادۀ تبادل داده می شود. در این صورت دو اتفاق می افتد:
- بیت MSTR در رجیستر SPCR صفر می شود و میکروکنترلر وارد مد Slave می شود. همچنین پایه های MOSI و SCK ورودی می شوند.
- پرچم SPIF یک می شود و در صورتی که وقفۀ SPI و پرچم کلی وقفه ها فعال باشد، یک وقفۀ SPI اتفاق می افتد.
برای حل این مشکل باید در روتین وقفۀ میکروکنترلر Master، یک بودن بیت MSTR مورد بررسی قرار گیرد و یک شرط قرار داد که اگر این بیت صفر شده باشد دو باره توسط برنامه یک شود و همچنین پایه های MOSI و SCK به صورت خروجی تعریف شوند. به این شکل میکروکنترلر دوباره به مد Master بر می گردد.
ورودی یا خروجی بودن پایه های MOSI، MISO و SCK در این مد مطابق جدول بالا تعیین می شود.
عملکرد SPI در مد Slave
در این مد میکروکنترلر Slave است و با یک میکروکنترلرِ Master به تبادل داده می پردازد. پایۀ SS در این مد ورودی است و به یکی از پایه های پورت ورودی/خروجی Master متصل است. هر گاه پایۀ SS از طرف Master صفر شود، این میکروکنترلر می تواند با میکروکنترلر Master تبادل داده کند.
ورودی یا خروجی بودن پایه های MOSI، MISO و SCK در این مد مطابق جدول بالا تعیین می شود.
اولویت انتقال MSB و LSB در SPI
در میکروکنترلرهای AVR و در ATmega128 این امکان وجود دارد که در ارتباط SPI، ابتدا بیت MSB (بیت پر ارزش) فرستاده شود و در آخر بیت LSB (بیت کم ارزش) و یا ابتدا بیت LSB فرستاده شود و در آخر بیت MSB. و این که ابتدا LSB فرستاده شود یا MSB قابل برنامه ریزی می باشد.
نکته: اولویت انتقال MSB و LSB در Master و Slave باید یکسان باشد.
مدهای داده ( Data Modesیا SPI Modes) در SPI
در SPI چهار مد داده وجود دارد که این مدها تعیین کنندۀ دو مورد زیر است:
الف) پلاریتۀ پایۀ SCK در حالت Idle (Clock Polarity یا SCK Polarity). یعنی سطح ولتاژ سیگنال کلاک در حالت Idle. سطح ولتاژ پایۀ SCK در حالت Idle می تواند 0 یا 1 باشد. حالت Idle یعنی زمانی که داده تبادل نمی شود.
ب) فاز پایۀ SCK در هنگام نمونه برداری داده (Clock Phase یا SCK Phase). یعنی این که نمونه برداری داده در لبۀ بالاروندۀ کلاک SPI باشد یا در لبۀ پایین روندۀ آن. هنگامی که نمونه برداری داده در لبۀ بالا رونده باشد، با هر لبۀ بالا روندۀ کلاک SPI، یک بیت داده نمونه برداری می شود و با هر لبۀ پایین رونده، یک شیفت انجام می شود. هنگامی که نمونه برداری داده در لبۀ پایین رونده باشد، با هر لبۀ پایین روندۀ کلاک SPI، یک بیت داده نمونه برداری می شود و با هر لبۀ بالا رونده، یک شیفت انجام می شود.
این دو مورد که با بیت های CPOL و CPHA تعیین می شوند، چهار مد را تشکیل می دهند که آنها را در جدول زیر مشاهده می کنید.
شیفت در لبۀ | نمونه برداری در لبۀ | سطح پایۀ SCK در حالت Idle | CPHA | CPOL | SPI Mode |
پایین رونده | بالا رونده | 0 | 0 | 0 | 0 |
بالا رونده | پایین رونده | 0 | 1 | 0 | 1 |
بالا رونده | پایین رونده | 1 | 0 | 1 | 2 |
پایین رونده | بالا رونده | 1 | 1 | 1 | 3 |
جدول 3 – مدهای داده در SPI
تصویر 5 و 6 نشان دهندۀ سیگنال های SPI در چهار مد دادۀ مختلف است.
تصویر 5 – سیگنال ها و مدهای داده در SPI، CPHA = 0
تصویر 6 – سیگنال ها و مدهای داده در SPI، CPHA = 1
نکته: در ارتباط SPI، Master و Slave هر دو باید در مد یکسان پیکربندی شوند. اگر Slave، یک المان دیگر غیر از میکروکنترلر باشد، مثلاً یک آی سی ADC خارجی باشد، باید به دیتاشیت آن مراجعه کرد و مدی را که پشتیبانی می کند دریافت. سپس Master را با توجه به مد دادۀ آن آی سی پیکربندی کرد.
فرکانس کلاک SPI
فرکانس کلاک SPI در ATmega128 مطابق جدول زیر و با بیت های SPR1 و SPR0 تعیین می شود. در ATmega128 یک بیت دیگر وجود دارد (SPI2X) که با فعال کردن آن فرکانس کلاک SPI دو برابر می شود. مقدار دهی به این بیت ها در هنگامی است که میکروکنترلر در مد Master پیکربندی می شود. در مد Slave مقدار دادن به این بیت ها بی تأثیر است. جدول زیر بیانگر فرکانس کلاک SPI با بیت های مذکور است.
فرکانس کلاک SPI | SPR0 | SPR1 | SPI2X |
fosc / 4 | 0 | 0 | 0 |
fosc / 16 | 1 | 0 | 0 |
fosc / 64 | 0 | 1 | 0 |
fosc / 128 | 1 | 1 | 0 |
fosc / 2 | 0 | 0 | 1 |
fosc / 8 | 1 | 0 | 1 |
fosc / 32 | 0 | 1 | 1 |
fosc / 64 | 1 | 1 | 1 |
جدول 4 – فرکانس کلاک واحد SPI در میکروکنترلرهای AVR
fosc همان فرکانس کلاک CPU است.
نکته: تنها در مد Master می توانیم از دو برابر کنندۀ فرکانس (یعنی بیت SPI2X) استفاده کنیم. در مد Slave نیز فرکانس کلاک ورودی روی پایۀ SCK باید کمتر یا مساوی یک چهارم فرکانس CPU (fosc / 4) باشد. در این صورت می توان اطمینان داشت که SPI به درستی کار می کند.
وقفه SPI در AVR
با اتمام یک تبادل داده پرچم SPIF یک می شود و اگر وقفۀ SPI و پرچم I در SREG یک باشد، وقفۀ SPI اتفاق می افتد و برنامه وارد روتین وقفه می شود. در مد Master، وقفۀ SPI با صفر شدن پایۀ SS نیز اتفاق می افتد که پیش تر دربارۀ آن توضیح داده شد.
کتابخانه spi.h در نرم افزار کدویژن
این کتابخانه دارای تابع زیر است که همزمان داده را هم می فرستد و هم دریافت می کند. ورودی این تابع داده ای است که باید ارسال شود و خروجی آن داده ای است که دریافت می شود. این تابع هم در Slave و هم در Master قابل استفاده است.
unsigned char spi (unsigned char data);
همان طور که از عبارت unsigned char مشخص است، ورودی و خروجی این تابع یک عدد 8 بیتی بدون علامت است.
نکته: برای استفاده از این تابع باید ابتدا رجیسترهای SPI تنظیم شوند.
به عنوان مثال در دستور زیر data_out فرستاده می شود و data_in دریافت می شود:
data_in = spi (data_out);
رجیسترهای SPI در میکروکنترلر AVR ATmega128
SPI دارای سه رجیستر است که در ادامه آنها را شرح خواهیم داد. یکی از این رجیسترها رجیستر کنترلی، یکی رجیستر وضعیت و دیگری رجیستر دادۀ SPI است. برای نحوه راه اندازی SPI در میکروکنترلرهای AVR کافی است دو رجیستر SPCR و بیت SPI2X رجیستر SPSR (در صورت نیاز) مقدار دهی شوند.
رجیستر SPCR
این رجیستر، رجیستر کنترلی SPI است. بیت های مربوط به تعیین فرکانس کلاک، مدهای داده، اولویت انتقال MSB یا LSB و همچنین فعال سازی SPI و وقفۀ آن در این رجیستر قرار دارد.
SPCR (SPI Control Register) | ||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Bit number |
SPR0 | SPR1 | CPHA | CPOL | MSTR | DORD | SPE | SPIE | Bit name |
R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W | Access |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Initial Value |
جدول 5 – رجیستر SPCR در میکروکنترلر AVR ATmega128
بیت SPIE (SPI Interrupt Enable): با یک شدن این بیت، وقفۀ SPI فعال می شود و با صفر شدن آن، این وقفه غیر فعال می شود.
بیت SPE (SPI Enable): با یک شدن این بیت، SPI فعال می شود و با صفر شدن آن، SPI غیر فعال می شود.
بیت DORD (Data Order): با یک شدن این بیت، ابتدا LSB فرستاده می شود (و در آخر MSB) و با صفر شدن آن، ابتدا MSB فرستاده می شود (و در آخر LSB).
بیت MSTR (Master/Slave Select): اگر این بیت یک شود، میکروکنترلر در مد Master قرار می گیرد و اگر صفر شود، میکروکنترلر در مد Slave قرار می گیرد.
بیت CPOL (Clock Polarity): این بیت سطح منطقی کلاک SPI یعنی سطح منطقی پایۀ SCK را در حالت Idle مشخص می کند. اگر این بیت یک شود، سطح منطقی SCK در حالت Idle، یک است. اگر این بیت صفر شود، سطح منطقی SCK در حالت Idle، صفر است.
بیت CPHA (Clock Phase): این بیت تعیین کنندۀ لبه ای است که در آن نمونه برداری و شیفت داده اتفاق می افتد. نوع لب با توجه مقدار بیت CPOL متفاوت است. برای درک بهتر این موضوع به بخش مدهای داده مراجعه کنید.
بیت های CPOL و CPHA، چهار حالت می سازند که به این چهار حالت مدهای دادۀ SPI می گویند. به بخش مدهای داده در SPI مراجعه کنید.
بیت های SPR[1:0] (SPI Clock Rate Select): این دو بیت فرکانس کلاک SPI را تعیین می کنند. بیت SPI2X نیز در فرکانس کلاک SPI دخیل است. در مد Slave، فرکانس کلاک ورودی روی پایۀ SCK باید کمتر از یک چهارم فرکانس CPU باشد.
رجیستر SPSR
این رجیستر، رجیستر وضعیت SPI است. در این رجیستر پرچم های وقفۀ SPI و تداخل داده و همچنین بیت انتخاب سرعت دو برابر وجود دارد.
SPSR (SPI Status Register) | ||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Bit number |
SPI2X | – | – | – | – | – | WCOL | SPIF | Bit name |
R/W | R | R | R | R | R | R | R | Access |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Initial Value |
جدول 6 – رجیستر SPSR در میکروکنترلر AVR ATmega128
بیت SPIF (SPI Interrupt Flag): این بیت، پرچم وقفۀ SPI است. هر گاه یک تبادل داده به اتمام برسد این پرچم 1 می شود. با اجرای روتین وقفۀ SPI، این پرچم توسط سخت افزار پاک می شود. این پرچم با اولین خواندنِ رجیستر SPSR نیز پاک می شود. همچنین این پرچم در مد Master اگر پایۀ SS صفر شود ،یک می شود.
بیت WCOL (Write Collision Flag): این بیت، پرچمِ تداخل دادۀ SPI است. هر گاه یک تبادل داده در حال اجرا باشد و در این زمان روی رجیستر دادۀ SPI مقداری جدید نوشته شود، یک تداخل داده به وجود می آید و پرچم WCOL یک می شود. با اولین خواندنِ رجیستر SPSR، این پرچم پاک می شود.
بیت SPI2X (Double SPI speed Bit): این بیت فرکانس کلاک SPI را که توسط بیت های SPR1 و SPR0 انتخاب می شوند، دو برابر می کند. این بیت تنها در مد Master کاربرد دارد و مقدار دهی به آن در مد Slave بی تأثیر است.
رجیستر SPDR
این رجیستر، رجیستر دادۀ SPI است. با نوشتن در این رجیستر، ارسال داده و در نتیجۀ آن دریافت داده، آغاز می شود.
SPDR (SPI Data Register) | ||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Bit number |
SPID0 | SPID1 | SPID2 | SPID3 | SPID4 | SPID5 | SPID6 | SPID7 | Bit name |
R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W | Access |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Initial Value |
جدول 7 – رجیستر SPDR در میکروکنترلر AVR ATmega128
تمرین های آموزش پروتکل SPI میکروکنترلرهای AVR
در این بخش دو تمرین برای درک بهتر کار با پروتکل SPI در میکروکنترلرهای AVR طرح کرده ایم. این دو تمرین با استفاده از کتابخانه spi.h در کدویژن نوشته شده است. برای یادگیری راه اندازی SPI میکروکنترلر AVR به صورت رجیستری و روش مناسب نوشتن برنامه برای SPI میکروکنترلر AVR و همچنین روش استفاده از بافر نرم افزاری برای SPI می توانید به نوشتۀ «روش راه اندازی پروتکل SPI در میکروکنترلر AVR با نمونه کد Slave» مراجعه کنید. برای درک مفهوم بافر نرم افزاری به نوشتۀ «بافر در USART میکروکنترلرها بافر نرم افزاری بافر سخت افزاری» مراجعه فرمایید. فایل های برنامه و شبیه سازی دو تمرین زیر در پیوست این نوشته موجودند.
تمرین 1 – ارتباط سه میکروکنترلر با هم از طریق SPI
در اینجا راه اندازی SPI میکروکنترلر AVR ATmega128A با استفاده از مقدار دهی به رجیسترهای SPI و همچنین استفاده از تابع spi کدویژن تمرین می شود. برای یادگیری مباحث مربوط به ورودی و خروجی پایه های میکروکنترلر AVR، نوشتۀ «آموزش پورت های IO در میکروکنترلرهای AVR پورت های IO در ATmega128A» را مطالعه نمایید.
سه میکروکنترلر ATmega128 را در نظر بگیرید. یکی از آن ها Master باشد و دو تای دیگر Slave. پورت A هر سه میکروکنترلر را ورودی و پول آپ داخلی کنید و یک دیپ سوییچ 8 تایی روی پایه های آن قرار دهید و پایه های سمت دیگر دیپ سوییچ را به زمین وصل کنید. برنامه ای بنویسید که با استفاده از ارتباط SPI، مقدار قرار گرفته روی پورت A میکروکنترلر Master در پورت C میکروکنترلرهای Slave و مقدار قرار گرفته روی پورت A میکروکنترلرهای Slave روی پورت D و E میکروکنترلر Master قرار بگیرد. پایۀ SS میکروکنترلر Master را با یک مقاومت 10 کیلو اهمی پول آپ کنید و پایه های SS میکروکنترلرهای Slave را به ترتیب به PB4 و PB5 وصل کنید. فرکانس کاری میکروکنترلرها 8 مگاهرتز باشد. از کتابخانۀ spi.h استفاده شود، فرکانس کلاک SPI برابر 125 کیلوهرتز باشد، از مد صفر استفاده شود و همچنین اولویت انتقال با MSB باشد.
راهنمایی: بعد از تنظیم رجیسترهای SPI، در حلقۀ بی نهایت while هر Slave می نویسیم:
while (!PINB.0) }
PORTC = spi(PINA);
}
در حلقۀ بینهایت while میکروکنترلر Master هم باید دو تابع spi() نوشته شود. همچنین Master باید قبل از تبادل داده، Slave مورد نظر را انتخاب کند.
delay_ms(50);
PORTB.4 = 0;
PORTC = spi(PINA);
PORTB.4 = 1;
delay_ms(50);
PORTB.5 = 0;
PORTD = spi(PINA);
PORTB.5 = 1;
تمرین 2 – ارتباط دو میکروکنترلر AVR با SPI و کنترل تایمر Slave
در این تمرین قصد داریم با پیاده سازی پروتکل SPI، مقدار رجیستر OCR1A را از Master به Slave انتقال دهیم و با استفاده از تایمر Slave یک شکل موج بسازیم.
دو میکروکنترلر ATmega128 را در نظر بگیرید. ارتباط SPI را بین دو میکروکنترلر ایجاد کنید و یکی از آن ها را Master و دیگری را Slave کنید. برای میکروکنترلر Slave، تایمر 1 را در مد CTC با مقدار TOP برابر OCR1A فعال کنید. مقدار OCR1A را با ارتباط SPI، از میکروکنترلر Master بگیرید. دو کلید روی دو پایه از میکروکنترلر Master باشد و با آنها مقدار OCR1A را بین 2000 و 64000 با پله های 500 تایی و تأخیر 50 میلی ثانیه کم و زیاد کنید. از مد صفر برای SPI استفاده کنید. اولویت انتقال داده با MSB باشد. فرکانس هر دو میکروکنترلر 8 مگاهرتز، فرکانس تایمر یک میکروکنترلر Slave برابر 1 مگاهرتز و فرکانس SPI برابر 125 کیلوهرتز باشد. برای SPI از کتابخانۀ spi.h استفاده کنید. برای آشنایی با تایمر 1 میروکنترلر ATmega128 نوشتۀ «آموزش تایمر کانتر میکروکنترلرهای AVR تایمر کانتر 1 و 3 در ATmega128A» را مطالعه فرمایید.
راهنمایی: در این مثال ارتباط یک طرفه است و نیازی به پایۀ MISO نیست. و در ورودیِ تابع spi() در میکروکنترلر slave باید 0x00 نوشته شود. همچنین در تبادل داده ابتدا بایت بالا و سپس بایت پایین فرستاده می شود. به کدهای برنامه دقت فرمایید.
از آموزش ارتباط SPI در AVR ATmega128 نتیجه می گیریم:
- در SPI یک Master و یک یا چند Slave داریم. می توان به روش های برنامه نویسی کاری کرد که چند میکروکنترلر Master شوند، اما نمی شود به طور همزمان در یک شبکۀ SPI، چند Master داشته باشیم.
- در پروتکل SPI، ارتباط تمام دو طرفه است. البته لزومی ندارد که حتماً ارتباط دو طرفه باشد.
- نام پایه های SPI در میکروکنترلرهای AVR به صورت MOSI و MISO و SCK و SS است. ممکن است در المان ها یا میکروکنترلرهای دیگر نام های دیگری برای این پایه ها در نظر گرفته شود.
- در SPI میکروکنترلر AVR می توان تعیین کرد که ابتدا بیت کم ارزش داده منتقل شود و در نهایت بیت پر ارزش و یا ابتدا بیت پر ارزش منتقل شود و در نهایت بیت پر ارزش.
- چهار نوع شیفت رجیستر از لحاظ ورودی و خروجی وجود دارد. شیفت رجیستر ورودی-سری، خروجی-سری، شیف رجیستر ورودی-سری، خروجی-موازی، شیفت رجیستر ورودی-موازی، خروجی-سری و شیفت رجیستر ورودی-موازی، خروجی-موازی.
- انتقال داده در SPI را Master با تغییر سطح ولتاژ پایۀ SS المان (یا میکروکنترلر) Slave شروع می کند.
- وقتی یک بیت از Master به Slave منتق می شود، همزمان نظیر همان بیت (از لحاظ شمارۀ بیت) از Slave به Master منتقل می شود. و وقتی 8 بیت انتقال داده شد، همۀ بیت هایی که در شیفت رجیستر Master بود در شیفت رجیستر Master قرار می گیرد و همۀ بیت هایی که در شیفت رجیستر Slave بود در شیفت رجیستر Master قرار می گیرد.
- پروتکل SPIیک پروتکل 8 بیتی است. زیرا شیفت رجیستر آن 8 بیتی است. برای انتقال تعداد بیت های بیشتر باید چند بار تبادل داده را انجام داد.
- در میکروکنترلرهای AVR پایۀ SS یک پایۀ Active Low است و وقتی میکروکنترلر Slave می شود، برای انتقال داده با آن، Master باید پایۀ SS را صفر کند. برای همین در میکروکنترلرهای AVR وقتی که قرار است Master باشند، باید پایۀ SS را وقتی ورودی است، پول آپ کنیم تا وارد مد Slave نشوند.
- در SPI چهار مد داده وجود دارد که این چهار مد بیانگر پلاریتۀ پایۀ SCK و فاز آن است. پلاریتۀ پایۀ SCK یعنی سطح Low یا High بودن آن در حالت Idle و فاز آن یعنی نمونه برداری در لبۀ پایین رونده باشد یا پایین رونده.
- در ارتباط SPI، Master و Slave هر دو باید در مد یکسان پیکربندی شوند. اگر Slave، یک المان دیگر غیر از میکروکنترلر باشد، مثلاً یک آی سی ADC خارجی باشد، باید به دیتاشیت آن مراجعه کرد و مدی را که پشتیبانی می کند دریافت. سپس Master را با توجه به مد دادۀ آن آی سی پیکربندی کرد.
- تنها در مد Master می توانیم از دو برابر کنندۀ فرکانس (یعنی بیت SPI2X) استفاده کنیم. در مد Slave نیز فرکانس کلاک ورودی روی پایۀ SCK باید کمتر یا مساوی یک چهارم فرکانس CPU باشد. در این صورت می توان اطمینان داشت که SPI به درستی کار می کند.
سلام استاد اسدی. یک سوال داشتم از خدمتتون. کاربرد SPI توی چه کاربردهایی هست؟ چند مثال هم اگر بفرمایید ممنون میشم.
سلام. کاربردهای پروتکل ارتباطی SPI به صورت کلی توی مقدمه ذکر شد، یعنی برقراری ارتباط با SD card با SPI، برقراری ارتباط با سنسورها، نمایشگرها، ماژول های فرستنده و گیرنده رادیویی و … با SPI. بعضی از آی سی های ADC قابلیت ارتباط از طریق SPI دارن. مثل آی سی های MCP3008 و MCP3201 و LTC2452 و … . بعضی سنسورها هم هستن که امکان تبادل داده از طریق SPI رو دارن. مثل سنسورهای دمای LM74 و TMP125 و ADT7320. همچنین سنسور دما و فشار و رطوبت BME280. نمونه هایی از آی سی های پتامسیومتر دیجیتال هم هستن که نوع تبادل داده با اونا SPI هستش. مثل ای سی های MCP41010 و MCP41100 و CAT2551 و MAX5487. و آی سی و ها و المان های دیگه. همچنین اگه توی یه مدار بخواید از چند میکروکنترلر استفاده کنید یه راه خوب برقراری ارتباط بین این میکروکنترلرها، رابط SPI هستش.
ممنون از مطلب مفیدتون خیلی قابل فهم و ساده توضیح دادین. متشکرم
سلام. خواهش میکنم. ممنون از نظرتون. موفق و پیروز باشید.
واقعا عالی بود…خدا خیرتون بده …
دو تا سوال داشتم.اول اینکه چطور میتونم دل و روده AVR رو در بیارم یعنی صفر تا صد کارکردن باهاشو بلد بشم؟کتابی دارین،جزوه ای هست و…؟؟
و سوال دوم اینکه وقتی گفته میشه پلاریته کلاک صفر هست بدین معناست که همواره یک سیگنال مربعی از مستر به اسلیو فرستاده میشه که در زمان های صفر انتقال داده صورت نمیگیره یا اینکه بدین معناست که دایمنا یک سیگنال صفر در پایه کلاک هست که به مجرد ارسال داده آن سیگنال صفر به یک سیگنال مربعی تبدیل میشه؟ و اگه حالت دوم درست باشه سوالی که مطرح میشه اینه که چطور پایه کلاک میفهمه که قراره داده ای ارسال بشه که در این صورت سیگنال مربعی تولید کنه؟
با سپاس فراوان
سلام. خواهش میکنم. لطف دارید. برای این که این میکروکنترلرها رو خیلی خوب یاد بگیرید مرحلۀ اول خوب یاد گرفتن مباحث تئوریه. شاید بیش از 70 درصد مطالب AVR رو توی وبلاگ آموزش دادیم. بهترین منبع برای یادگیری دیتاشیته و برای این که حرفه ای بشید باید پروژه های متنوع انجام بدید.
وقتی پلاریتۀ سیگنال کلاک صفره به این معنیه که قبل از شروع تبادل داده، سطح سیگنال کلاک صفره و به محض شروع تبادل داده، یک لبۀ بالارونده به وجود میاد و از این به بعد کلاک شکل میگیره. این کلاک هم در سخت افزار SPI زمانی به وجود میاد که توی رجیستر دادۀ SPI مقداری نوشته بشه. یعنی سخت افزار SPI بعد از این که مقداری توی رجیستر داده ش نوشته میشه، کلاک رو ایجاد میکنه. البته اگه در مد Master باشه. خواهش میکنم. موفق باشید.
سلام، یک سوال داشتم از خدمتتون
ماکزیمم فاصله ای که با ارتباطات SPI و I2C میتوان داشت چقدر است؟
این اطلاعات را از دیتاشیت خود میکرو نتوانستم به دست بیاورم. ممنون می شوم بفرمایید از چه مرجع و داکیومنتی می توان این فاصله را به دست آورد که مطمئن بود.
سلام. منابع مختلف و افراد مختلف و سایت های گوناگون، مقادیر متفاوتی ذکر کردن. و هرکدوم هم بسته به شرایطی که خودشون داشتن نظر دادن. ارتباط SPI معمولا برای ارتباط المان های روی یک برد استفاده میشه. و برای فواصل کوتاه هستش. برای I2C هم شرایط فرق دارن. ماکزیمم فاصلۀ I2C رو برای دوستی که توی نوشتۀ I2C پرسیدن جواب دادم:
نوشتۀ پروتکل I2C یوبرد
بنده هم متاسفانه موقع جست و جوی حداکثر فاصلۀ قابل اعتماد برای I2C و SPI مرجعی پیدا نکردم.
Mohammad Bashiry:
با سلام و تشکر از زحمات شما
می خوام یک میکروکنترلر رو به nrf متصل کنم و در سمت دیگر یک nrf رو از طریق یک دانگل usb به رایانه متصل کنم و ارسال و دریافت داده و فرمان به میکرو داشته باشم و نتیجه رو در نرم افزار سریال در رایانه مانیتور کنم ( مثلا خاموش و روشن کردن یک پایه در میکرو و چک کردن دما و ارسال داده به رایانه )
اینکار چگونه خواهد بود ؟