راه‌اندازی ENC28J60 با STM32 و ارتباط SPI، مدیریت رجیسترها و دستورات | قسمت ششم آموزش Embedded Ethernet

blog
26 بازدید
۱۴۰۴-۰۱-۲۴
10 دقیقه

مروری بر وضعیت فعلی پروژه

خب برگردیم سراغ پروژه مون؛ تا اونجا رفتیم جلو که ارتباط SPI بین میکرو و ENC رو برقرار کردیم. پین‌های RST,CS تراشه ENC رو هم دادیم به دوتا از پین‌های میکرو که به‌صورت خروجی تعریف شده بودن. در نرم‌افزار STMCubeMX هم تنظیمات اولیه رو انجام دادیم و برای کامپایلر KEIL ازش خروجی گرفتیم. شما با هر میکرو و کامپایلری میتونید کار کنید، فقط این کارها رو احتمالاً باید خودتون هندل کنید و بعضی کدها رو هم بنا به نیاز تغییر بدید. برگردیم سر وقت دیتاشیت ENC28J60

نگاه کاربردی به دیتاشیت ENC28J60

اینجا بگیم که ما نمیخوایم دیتاشیت ENC رو به طور کامل ترجمه کنیم. فقط اون قسمت‌هایی که برامون لازمه رو توضیح میدیم و با میکرو راه میندازیم، مابقی توانایی‌ها و قابلیت‌های ENC مثل خروجی INT برای وقفه؛ میمونه به عهده خودتون که ازش استفاده بکنید یا نه!

تجربه‌ی شخصی در مسیر راه‌اندازی ENC

یه اعترافی هم اینجا بکنم؛ حوالی سال 90 نیاز داشتم در پروژه‌ای، داده‌هایی رو تحت پروتکل TCP برای کامپیوتر ارسال کنم. مداری که بستم و کدی که از نت برداشتم (برای میکروی STM32f107 که خودش کنترلر اترنت داره) جواب نداد و چون اطلاعاتم در مورد شبکه خیلی ناقص بود، عیب‌یابی هم نتونستم بکنم. مجبور شدم اون برد رو رها کنم و از ماژول آماده ایکه TCP/IP رو بدون درگیرشدن با مفاهیم شبکه به ارتباط سریال USART تبدیل می‌کرد؛ استفاده کنم. سال‌ها از این ماژول استفاده می‌کردم تا اینکه بالاخره دوباره خواستم برگردم و خودم یه تراشه کنترلر اترنت رو راه بندازم. از اونجاییکه میخواستم بعدها بتونم کد رو روی هر میکروی دیگه ای هم پیاده‌سازی کنم؛ تراشه ENC رو انتخاب کردم؛ طبیعتاً کلی کد آماده برای انواع میکرو وجود داشت؛ ولی من دوست داشتم این بار اگه مشکی پیش اومد یا خواستم تغییراتی بدم، بدونم دارم چکار می‌کنم. اینه که با جستجو بالاخره تونستم سایتی رو پیدا کنم که همینطور که من دارم الان توضیح میدم؛ مفاهیم رو توضیح داده بود؛ البته بسیار خلاصه‌تر و کم‌حجم‌تر از این که می‌بینید (در 5 صفحه اینترنتی). به‌علاوه از دو پروتکل اصلی UDP و TCP هم فقط UDP رو کار کرده بود، ولی طریقه حل مسئله و روش آموزشش، سر نخ (getting started) خوبی بود برای من؛ لذا با همون روش سعی دارم به طور کامل‌تر و البته مفصل‌تری این مسیر رو ادامه بدم و TCP, DHCP, HTTP رو هم با همین روش کار کنم. آدرس اون سایت هست microtechnics.ru کدهای مورد نیازتون رو البته تا پروتکل UDP (بدون DHCP,TCP, HTTP) میتونید از این سایت دانلود کنید؛ همین‌جا هم تجربه خودم رو بگم که بعد از دانلود و کامپایل برنامه؛ تعداد زیادی خطای نحوی (Syntax Error) داشت که باید اونها رو رفع کنید. مهم‌ترینش تا اونجایی که یادمه؛ فاصله بین اشاره‌گر به ساختمان، یعنی عملگر -> بود که بین – و > یه فاصله افتاده بود؛ لذا تعداد زیادی خطا ایجاد می‌کرد. لینک دانلود بخش اصلی نرم‌افزار بدون TCP, DHCP,HTTP رو در انتهای لينك زير می تونید پیدا کنید:

https://microtechnics.ru/stm32-i-ethernet-chast-5-transportnyj-uroven-protokol-udp/

آماده‌سازی پروژه در محیط KEIL

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

تعریف فایل‌های enc28j60.c و enc28j60.h

ابتدا دو فایل با نام‌های enc28j60.c و enc28j60.h رو به برنامه تون در محیط KEIL اضافه کنید (امیدوارم حداقل با برنامه‌نویسی C آشنا باشید. اگر آشنا نیستید؛ این فایل رو ببندید و اول اون رو یاد بگیرید). در هدر فایل؛  اعلان‌ها (declaration) رو قرار میدیم و در فایل C، تعریف (definition) متغیرها و توابع رو.

تابع کنترل CS برای تراشه ENC

طبق گفته دیتاشیت برای ارتباط SPI باید پین CS تراشه در منطق LOW قرار بگیره. اولین تابعی که می‌نویسیم تابعی برای کنترل پین CS تراشه ENC یه همچین چیزیه:

 

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

تعریف پورت‌ها و enum مربوط به CS

و در فایل هدر (header) مشخص می‌کنیم پین‌های CS,RST کجاست. همچین enum مورد نظر برای ENC28J60_CS_State رو هم اعلان می‌کنیم.

 

  • تمام کدها به طور کامل در انتهای همین نوشتار اضافه میشه. همچنین از سایت اعلام شده هم میتونید این فایل‌ها رو دانلود کنید. به طور جداگانه هم در سایت‌های ایرانی آپلود میشه که بتونید استفاده کنید. فعلاً ذهنتون متوجه روش پیاده‌سازی و یادگیری مفاهیم باشه.

توابع خواندن و نوشتن بایت از طریق SPI

توابع زیر برای ارسال یا دریافت بایت یا بایت‌هایی از پورت SPI تعریف میشن.

ساختار رجیسترها و بانک‌ها در ENC28J60

جهت کنترل ENC و برقراری ارتباط با آن مکانیزم ساده‌ای در نظر گرفته شده؛ بدین‌طریق که رجیستر (ثبات) های کنترلی در چهار بانک تقسیم شده‌اند. این چهار بانک شامل رجیسترهای کنترلی در سه گروه هستند که عبارت‌اند از:

  • رجیسترهای کنترل
  • رجیسترهایی برای خواندن/نوشتن بافر اترنت
  • رجیسترهای ارتباط با بخش PHY

نام‌گذاری و دسته‌بندی رجیسترها

نام‌گذاری رجیسترها (Register ، ثبات) هم شامل قاعده ساده ایست. ثبات‌های کنترل اترنت با حرف E ؛ رجیسترهای مرتبط با بخش MAC با حروف MA و رجیسترهای مرتبط با ارتباط MII با حروف MI مشخص شده‌اند.

تصویر زیر نمایی از این رجیسترهاست.

شکل 9 ثباتهای کنترلی در ENC28J60

شکل 9 ثباتهای کنترلی در ENC28J60

آدرس‌های مشترک و رجیسترهای عمومی

بنا به گفته دیتاشیت، برای دسترسی به هر رجیستر، ابتدا باید بانک موردنظر انتخاب شود. بیت‌های کنترلی انتخاب بانک، در ثبات ECON1 در آدرس 0x1F قرار گرفته‌اند. از طرفی چنانچه با دقت به شکل 9 نگاه کنیم متوجه می‌شویم که در انتهای تمام بانک‌ها، 5 ثبات با نام مشابه قرار دارند. در واقع این آدرس‌ها به یک ثبات ارجاع می‌دهند؛ درنتیجه در هنگام دسترسی به این رجیسترها، انتخاب یا تغییر بانک نیاز نیست؛ به‌عنوان‌مثال، چنانچه قصد ارتباط با EIR در آدرس 0x1C را داشته باشیم، نیاز نیست که بانک فعلی را تغییر دهیم و تنها کافی‌ست اطلاعات مورد نیاز را از آدرس 0x1C بخوانیم یا بنویسیم.

 

معرفی دستورات ارتباطی با ENC28J60

برای ارتباط با ENC تنها 7 نوع دستورالعمل تعریف شده است. چهار دستور برای خواندن/نوشتن رجیسترهای کنترلی و حافظه بافر؛ دو دستور برای تغییرات بیتی و یک دستور برای ریست نرم افزاری (جهت ریست سخت افزاری نیز از پین RST استفاده خواهیم کرد).

 

شکل 10 دستورات ارتباطی با ENC

شکل 10 دستورات ارتباطی با ENC

شکل 10 دستورات ارتباطی با ENC

شکل 10 دستورات ارتباطی با ENC

شکل 12 نوشتن در ثباتهای کنترلی

شکل 12 نوشتن در ثباتهای کنترلی

ساختار کلی دستورات ارتباطی

باتوجه‌به نوع دستورها می‌بینیم که هر دستور از 3 بیت برای نوع دستور (Opcode) و 5 بیت که یا جهت آدرس دهی یا (با مقدار ثابت) جهت دستورات خاص؛ تشکیل شده. تنها تفاوت بین خواندن یا نوشتن در جهت بایت دوم است که یا ما برای ENC از پین MOSI ارسال خواهیم کرد یا از پین MISO از ENC خواهیم خواند.

مدل ساده برای دسترسی به رجیسترها

برای اجرای عملیات خواندن/نوشتن ENC یک مدل ساده برای نرم افزارمون طراحی کردیم به‌این‌ترتیب که از یک متغیر یک بایتی برای مشخص‌کردن رجیستر مد نظرمون استفاده می‌کنیم. ساختار این بایت در جدول زیر نشون داده شده:

0

1

2

3

4

5

6

7

آدرس

بانک

نوع رجیستر

00=Bank 0

01=Bank 1

10=Bank 2

11=Bank 3

0= Ethernet

1=MAC,MII

مدل‌سازی رجیسترها و بانک‌ها در ENC28J60

این مدل به‌صورت زیر در هدر فایل آمده است.

  •  

تعریف Enumها برای بانک و نوع رجیستر

  • اگر به مقادیر داخل enum مقدار ندیم؛ به ترتیب از 0 به صورت صعودی شماره گذاری میشن.

بعلاوه ثابت‌هایی که با استفاده از #define تعریف شده‌اند.

تعریف بیت‌ماکروها و ماسک‌های آدرس‌دهی

در واقع مدل ما در هنگام دسترسی به یک ثبات یه همچین چیزی هست:

بررسی بیت‌های مهم در رجیسترها

از طرفی نیاز داریم با تعدادی از بیت‌ها در بعضی از رجیسترها، به‌صورت مستقیم ارتباط داشته باشیم که اون ها رو هم به طور ثابت در برنامه تعریف می‌کنیم؛ مثل:

توابع دسترسی و استخراج اطلاعات رجیستر

خب بعد از انجام تعاریف (Define) حالا آماده‌ایم تعدادی تابع برای بررسی نوع رجیسترها، همچنین مشخص‌شدن بانک و آدرسشون بنویسیم. قبل‌تر گفتیم که هرگاه بخواهیم به یک ثبات دسترسی داشته باشیم (به جز بایت‌های مشترک در انتهای بانک‌ها)؛ اول باید مطمئن شیم که در بانک مورد نظر هستیم یا نه!

کنترل بانک رجیسترها

در توابعی که در ادامه پیاده‌سازی شدن (Implementation) و هنگام دسترسی به هر رجیستری، ابتدا بررسی می‌کنیم که آیا در بانک مدنظر قرار داریم یا نه؟  و اگر نیاز بود بانک رو تغییر میدیم. اگه یادتون باشه؛ گفتیم بیت‌های انتخاب بانک در ثبات ECON1 قرار دارند (که خود این ثبات هم در بخش انتهایی و مشترک تمام بانک‌ها هست؛ لذا برای دسترسی به این ثبات، دیگه لازم نیست بانک رو تغییر بدیم).

راه‌اندازی ENC28J60 با STM32 و ارتباط SPI، مدیریت رجیسترها و دستورات | قسمت ششم آموزش Embedded Ethernet

از اونجاییکه ما به‌دفعات نیاز داریم بدونیم که در کدام بانک هستیم؛ به‌جای اینکه هر بار محتویات ECON1 رو بخونیم؛ بانک فعلی رو در یک متغیر ذخیره می‌کنیم. از شکل بالا هم متوجه میشیم که مقدار اولیه بانک بعد از ریست، روی بانک صفر هست، لذا مقدار اولیه متغیرمون رو هم روی Bank0 تنظیم کردیم.

حالا یه تابع می‌نویسیم که بانک یک رجیستر رو چک کنه؛ اگر بانک این رجیستر متفاوت از بانک فعلی بود؛ بانک رو تغییر میدیم:

بررسی و تغییر خودکار بانک با تابع CheckBank

این تابع مقدار یک رجیستر رو به فرمتی که تعریف کردیم دریافت میکنه؛ اول چک میکنه که این رجیستر از رجیسترهای مشترک نباشه، سپس اگر بانک فعلی از بانکی که رجیستر مدنظرمون توش هست؛ متفاوت بود با دستورات بیتی بانک رو به بانک مدنظر تغییر میده  و در نهایت مقدار متغیر CurBank هم بروز میشه.

همونطور که در کد تابع ChekBank می‌بینید از توابعی استفاده شده که هنوز نمیدونیم چی هستن.

دستورالعمل‌های ENC28J60

حالا بریم سر وقت دستورالعمل‌ها؛ یادمون هست که کلاً 7 نوع دستور بیشتر نداشتیم. مجدداً طبق روال برنامه مون؛ اونها رو با یک enum و یک آرایه تعریف می‌کنیم:

تعریف Enum و آرایه Opcode دستورات

و تعریف تابعی برای ارسال یک دستور به ENC به همراه داده مطلوب:

پیاده‌سازی توابع سطح پایین دسترسی به رجیسترها

حالا بر اساس این تابع؛ توابع اصلی رو پیاده‌سازی می‌کنیم، به‌عنوان‌مثال تابع خواندن یک رجیستر کنترلی:

همونطور که مشخص هست؛ ابتدا بانک رو چک (و تنظیم) می‌کنیم؛ بعد دستور خواندن رجیستر صادر میشه و بعد رجیستر خونده میشه. البته از دیتاشیت میدونیم که اگر نیاز به خواندن یک رجیستر از نوع MAC/MII هست در ابتدای پروسه خواندن داده اصلی، باید یک بایت dumy (الکی) رو بخونیم! و بعد داده اصلی از ENC خارج میشه؛ تنها نکته این تابع همینه.

توابع ReadControlReg و خواندن رجیسترهای MAC/MII

توابع اصلی به علاوه توابعی که برای دسترسی به رجیسترهای دوبایتی مثل EWRPRL و EWRPRH نیاز هست در ادامه اومدن. یک تابع هم برای ریست نرم‌افزاری ENC نوشتیم.

دسترسی به رجیسترهای PHY

یک نکته دیگه هم اینکه به رجیسترهای بخش PHY دسترسی مستقیم (مثل بقیه رجیسترهایی که تا الان گفتیم) نداریم و طبق گفته دیتاشیت، باید یک روال طی بشه. برای نوشتن در این رجیسترها، باید آدرس رو در رجیستر MIREGADR بنویسم؛ در ادامه داده رو به‌صورت دوبایتی در ثبات‌های MIWRL و MIWRH می‌نویسم و صبر می‌کنیم تا نوشتن داده تموم بشه (با بررسی بیت MISTAT_BUSY_BIT از ثبات MISTAT)

اطلاعات
26
0
0
لینک و اشتراک
profile

مجتبی داشخانه

متخصص الکترونیک

مقالات بیشتر
slide

پالت | بازار خرید و فروش قطعات الکترونیک

قطعات اضافه و بدون استفاده همیشه یکی از سرباره‌‌های شرکتها و طراحان حوزه برق و الکترونیک بوده و هست. پالت سامانه‌ای است که بصورت تخصصی اجازه خرید و فروش قطعات مازاد الکترونیک را فراهم می‌کند. فروش در پالت
family

آیسی | موتور جستجوی قطعات الکترونیک

سامانه آی سی سیسوگ (Isee) قابلیتی جدید و کاربردی از سیسوگ است. در این سامانه سعی شده است که جستجو، انتخاب و خرید مناسب تر قطعات برای کاربران تسهیل شود. وقتی شما در این سامانه، قطعه الکترونیکی را جستجو می‌کنید؛ آی سی به سرعت نتایج جستجوی شما در اکثر فروشگاه‌های آنلاین در حوزه قطعات الکترونیک را نمایش می‌دهد. جستجو در آیسی
family

سیسوگ‌شاپ | فروشگاه محصولات Quectel

فروشگاه سیسوگ مجموعه ای متمرکز بر تکنولوژی های مبتنی بر IOT و ماژول های M2M نظیر GSM، GPS، LTE، NB-IOT، WiFi، BT و ... جایی که با تعامل فنی و سازنده، بهترین راهکارها انتخاب می شوند. برو به فروشگاه سیسوگ
family

سیسوگ فروم | محلی برای پاسخ پرسش‌های شما

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

سیکار | اولین مرجع متن باز ECU در ایران

بررسی و ارائه اطلاعات مربوط به ECU (واحد کنترل الکترونیکی) و نرم‌افزارهای متن باز مرتبط با آن برو به سیکار
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
خانواده سیسوگ

سیسوگ‌شاپ

فروشگاه محصولات Quectel

پالت

سیسوگ فروم

محلی برای پاسخ پرسش‌های شما

سیسوگ جابز
سیسوگ
سیسوگ فروم

سی‌کار

اولین مرجع متن باز ECU در ایران

سیسوگ مگ

آی‌سی

موتور جستجوی قطعات الکترونیکی

سیسوگ آکادمی

پالت

بازار خرید و فروش قطعات الکترونیک

دیدگاه ها

become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله