قبلا در این پست که رجیستر W را همراه با کدهای عملیاتی جدید اضافه کردیم، برای اولین بار رجیستر W معرفی شد، حالا کمی بیشتر با این رجیستر آشنا می شویم، و به نحوه کارکرد دستورات دو مرحله ای می پردازیم، و در نهایت این دستور ها را به شبیه ساز خود اضافه می کنیم.
دستورات زیر، دستورات دو مرحله ای هستند، به این معنی که ممکن است دستوری را اجرا نکنند و از آن بگذرند، توجه داشته باشید که در بعضی از دستور ها از حرف d استفاده شده که به معنی destination (فاصله) می باشد.
این دستور به مقدار رجیستر داده شده یکی اضافه می کند. و در صورتی که مقدار d برابر با 0 بود مقدار را در رجیستر W ذخیره می کنید و اگر مقدار برابر با 1 بود، نتیجه در خود آدرس داده شده ذخیره می شود.
در صورتی که مقدار بزرگتر از 255 بود مقدار رجیستر برابر با 0 می شود.
این دستور همانند دستور INCF یکی به مقدار رجیستر داده شده اضافه می کند. و در صورتی که d برابر با 0 بود مقدار را در رجیستر W و در غیر این صورت اگر برابر با 1 بود مقدار را در آدرس داده شده قرار می دهد.
تفاوت این دستور با دستور INCF این است که در صورتی که مقدار برابر با 0 شد دستور بعدی اجرا نمی شود و بجای آن یک NOP اجرا می شود (دو مرحله ای). و در صورتی که مقدار برابر با 0 نبود، دستور بعد از INCFSZ اجرا می شود (به صورت عادی)
این دستور یکی از مقدار آدرس داده شده کم می کند. در صورتی که مقدار آدرس داده شده برابر با 0 نباشد. و مثل دستور های قبلی اگر مقدار d برابر با 0 بود نتیجه در رجیستر W ذخیره می شود و در غیر این صورت اگر برابر با 1 بود مقدار در آدرس داده شده ذخیره می شود.
این دستور نیز مانند دستور DECF یکی از مقدار آدرس داده شده کم میکند در صورتی که برابر با 0 نباشد، و اگر مقدار d برابر با 0 بود مقدار در جیستر W ذخیره می شود و در غیر این صورت مقدار اگر برابر با 1 بود مقدار در آدرس داده شده ذخیره می شود.
تفاوت این دستور با دستور DECF این است که اگر مقدار برابر با 0 بود بجای دستور بعدی یک NOP اجرا می شود، در غیر این صورت مثل DECF عمل می کند و دستور بعدی نیز به صورت عادی اجرا می شود.
این دستور برای تست کردن بیت می باشد به صورتی که f برابر با آدرس و b برابر با شماره بیت (0 تا 7) می باشد، در صورتی که بیت مورد نظر در آدرس داده شده برابر با 0 بود، دستور بعدی اجرا نمی شود و بجای آن یک NOP اجرا می شود، در غیر این صورت (برابر با 1 بود) اتفاقی نمی افتد.
این دستور نیز برای تست می باشد و همانند دستور BTFSC یک آدرس (f) و شماره بیت (b) را می گیرد. که شماره بیت می تواند بیت 0 تا 7 باشد.
تفاوت این دستور با BTFSC این است که در صورتی که مقدار بیت داده شده برابر با 1 بود بجای دستور بعدی یک NOP اجرا می شود و در صورتی که برابر با 0 بود اتفاق خاصی نمی افتد.
اول از همه باید بخش decode مربوط به CPU را به روز کنیم، که CPU قادر باشد دستورها را تشخیص دهد و مقدار های مورد نیاز را از instruction داده شده استخراج کند
حالا به تابع decode_inst دستورات زیر را اضافه می کنیم:
بعد از decode حالا زمان اجرا کردن دستورات توسط پردازنده می باشد، که توابعی را که قبلا در این پست نوشته ایم را آپدیت می کنیم:
در اینجا یک متغیر جدید به اسم bypass تعریف شده است که مشخص می کند که دستور بعدی اجرا شود یا خیر که برای دستورات دو مرحله ای بسیار مفید می باشد.
کاری که این متغیر می کند:
در خط 1 این متغیر تعریف شده و در خط 6 با توجه با تابع execute مقدار دهی می شود (یا 0 یا 1) و در خط 11 بررسی می شود که آیا متغیر bypass برابر است با 1، و در این صورت در خط 12 مقدار برابر با 0 می شود (تا از رد شدن از دستورات بعدی جلوگیری کند)، و در خط 13 مقدار شمارنده برنامه را یکی بیشتر می کند (باعث رد شدن از دستور بعدی می شود) و در نهایت در خط 14 باعث جلوگیری از اجرا شدن دستورات دیگر می شود و به اول حلقه باز می گردد.
حالا برای آشنایی بیشتر با این دستور ها، به کدهای اسمبلی زیر توجه کنید:
در کد بالا مقدار GPIO مداوم افزایش می یابد تا با مقدار باینری 0b10000000 برابر شود (برابر با عدد 128) و بعد از آن میکروکنترلر به حالت SLEEP می رود.
برای تست دستور DECF نیز می توانیم کد زیر را داشته باشیم:
کاری که این کد در مجموع انجام می دهد به این صورت می باشد که اول مقدار 255 (0b11111111) را در GPIO قرار میدهد (با استفاده از MOVLW و MOVWF)، بعد در هر حلقه یکی از 255 کم می کند، و در صورتی که مقدار برابر با 127 شد (با 0b01111111) دستور SLEEP اجرا می شود.
کد های مربوط به این بخش را می توانید از لینک Github زیر دانلود و استفاده کنید:
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.