مجموعه دستورات و ثبات ها در 8051
مجموعه دستورات و ثبات ها در 8051
بانک های ثبات:
8051 دارای 8 ثبات با نامهای R0-R7 میباشد دستوراتی که از این ثباتها استفاده می کنند نسبت به دستورات مشابه خود که از انواع دیگر آدرس دهی استفاده می کنند دارای تعداد بیت کمتر و سرعت بیشتری هستند بنابراین در صورتی که از داده ای به طور متناوب در برنامه استفاده می کنیم بهتر است که این داده در یکی از ثباتهای بانک ثبات قرار گیرد.
در 8051 , 4 بانک ثبات وجود دارد که در هر لحظه از زمان می توان فقط یکی از این بانکها را فعال و از آن استفاده کرد . برای فعال کردن یک بانک ثبات از دو بیت با نامهای PSW.3, PSW.4 استفاده می کنیم این 2 بیت اجزای ثبات PSW هستند.
ثبات PSW:
مخفف Program status word یا کلمه وضعیت سیستم است .این ثبات در هر سیکل ماشین بسته به وضعیت و جواب برنامه تغییر می کند و برنامه نویس می تواند بر اساس این تغییرات منطق برنامه را تغییر دهد. PSW مشابه FLAG های ریزپردازنده های سیستم های میکروکامپیوتری می باشد.
شکل زیر بیتهای ثبات وضعیت (PSW) را نشان می دهد.
C یا CY
AC
F0
RS1
RS0
OV
----
P
شکل 1-3
بیت توازن ((P :
این بیت تنظیم توازن زوج , مقدار آن صفر یا یک می شود . در صورتیکه تعداد یکهای داخل آکومولاتور فرد باشد این بیت یک می شود تا مجموع یکها زوج باشد این یک روش ساده تشخیص تعداد فرد خطا در انتقال اطلاعات می باشد.برای مثال اگر آکومولاتور عدد 00000011 را در مبنای دو در خود داشته باشد چون در این مثال تعداد 1 ها دو عدد می باشد بنابراین بیت توازن صفر می شود تا تعداد یکها ی زوج باقی بماند.این بیت اکثرا در روتین های پورت سری استفاده می شود به طوری که اطلاعات با بیت توازن ارسال می شود و در موقع دریافت اطلاعات بیت توازن تست می گردد.
بیت پرچم سرریز یا OV :
این بیت با نام OVER FLOW یا سرریز نام دارد. اگر هنگام جمع یا تفریق حسابی نتیجه حاصل بزرکتر از 127 + یا کوچکتر از 127- شود سرریز اتفاق می افتد و بیت OV برابر 1 می شود.
بیت های انتخاب بانک ثبات :(RS0,RS1)
این دو بیت به منظور فعال کردن یکی از 4 بانک ثبات مورد استفاده قرار می گیرد.مقدار پیش فرض این 2 بیت 00 است که بانک ثبات 0 را فعال می کند.
بیت :FO
این بیت با نام پرجم صفر هم شناخت هشده است. اگر نتیجه یک عمل حسابی صفر شوداین بیت یک می شود.
بیت :AC
در هنگام انجام عملیات حسابی در صورتی که از بیت شماره 3 به شماره 4 رقن نقلی داشته باشیم در این صورت این بیت یک می شود.
بیت پرچم نقلی یا :CY
این بیت به دو منظور به کار می رود:
1- در مواقع محاسبات یعنی زمانی که عمل جمع انجام می شود اگر از بیت 7 رقم خارج شود بیت C یک می شود.
2- اگر در زمان تفریق از بیت 7 قرض گرفته شود در این صورت بیت C برابر یک می شود.
ثبات A:
این ثبات Accumulator یا انباره نامیده می شود. این ثبات همه منظوره است . بیشتر دستورات میکروکنترولر با این ثبات کار می کنند بنابراین ابتدا باید داده در این ثبات قرار بگیرد سپس عملیات انجام شود.
ثبات :B
ثبات یا آکومولاتور B در آدرس F0H حافظه قرار دارد و معمولا با ثبات A برای محاسبات ضرب و تقسیم استفاده می شود.
ثبات B را می توان به عنوان یک ثبات عمومی برای هر کاربرد دیگری نیز لستفاده نمود. علاوه بر این بیت های ثبات B آدرس پذیر و از آدرس F0H تا F7H می باشند لذا می توان با دستورات روی بیت , عملیات بر روی آنها انجام داد.
ثبات DPTR یا اشاره گر داده:
این ثبات یک ثبات 16 بیتی است که از 2 ثبات 8 بیتی با نامهای DPL,DPH ساخته شده است و به عنوان اشاره گر داده به کار می رود.ای ثبات برای دسترسی به حافظه کد و داده خارجی به کار می رود. به عنوان مثال دستورات زیر عدد 55H را در حافظه داده خارجی RAM می نویسند:
MOV A,#55H
MOV DPTR,#1000H
MOV @DPTR,A
اشاره گر پشته یا :SP
SP یک ثبات 8بیتی می باشد که آدرس اطلاعات بالای حافظه پشته را دارا می باشد . عملیات حافظه پشته شامل قرار دادن اطلاعات در بالای حافظه پشته ( با دستور ( PUSH یا برداشتن اطلاعات (با دستور (POP از بالای حافظه پشته می باشد.
هربار که اطلاعات در حافظه پشته قرار می گیرد ابتدا به محتوای SP یک واحد اضافه می شود و سپس اطلاعات در حافظه پشته نوشته می شود ((PUSH
هربار که اطلاعاتی از حافظه پشته خوانده می شود ( ( POPابتدا اطلاعات خوانده می شود و سپس یک واحد از SP کم می شود.
روش های آدرس دهی:
مبحث مهمی که در برنامه نویسی به زبان اسمبلی وجود دارد شیوه های آدرس دهی است .منظور از آدرس دهی روش دستیابی میکروکنترلر به اطلاعات است . روش های آدرس دهی مبدا و مقصد داده ها را تعیین می کند و اینکه در جریان انتقال داده ها از مقصد به مبدا چه عملیات بیتی انجام می شود .
در 8051 . هشت نوع آدرس دهی وجود دارد که عبارتند از:
1- آدرس دهی ثبات((Rejister Addresing
2- آدرس دهی مستقیم((Direct Addresing
3- آدرس دهی غیر مستقیم((Indirect Addresing
4- آدرس دهی فوری ((Immediate Addresing
5- آدرس دهی نسبی ( (Relative Addresing
6- آدرس دهی مطلق ((Absolute Addresing
7- آدرس دهی بلند ((Long Addresing
8- آدرس دهی اندیس دار ((Index Addresing
1- آدرس دهی ثبات:
در 8051 هشت ثبات با نام بانک ثبات وجود دارد که این ثبات ها به صورت تک تک با نامهای R0-R7 شناخته می شوند تعدادی از دستورالعمل های 8051 بر روی این ثباتها کار می کنند ابن دستورالعملها را دستورهای با آدرس دهی ثبات گویند.در دستورا ت آدرس دهی ثبات , سه بیت کم ارزشتر کد دستور , آدرس ثباتهای مذکور را مشخص می کند بنابراین کد اجرا و آدرس ثبات در یک بایت دستور قرار می گیرد.
زبان اسمبلی میکروکنترولر 8051 , آدرس دهی ثبات را با سمبل RN مشخص می کند که N بین 0 تا 7 می باشد.به عنوان مثال برای اضافه کردن محتوای ثبات R7 به آکومولاتور دستور زیر استفاده می شود:
ADD A,R7
کد اجرای این دستور 00101111 است که 5بیت پر ارزشتر یعنی 00101 دستور جمع ADD و سه بیت کم ارزش تر آن یعنی 111 ثبات R7 را مشخص می نماید.
مثال2: کد اجرای دستور زیر چیست و این دستور چه عملی انجام می دهد؟
MOV A,R7
فرم کلی دستور MOV به صورت زیر است:
منبع , مقصد MOV
اصولا 15 نوع دستور MOV وجود دارد که در اینجا نوع MOV A,Rn را بررسی می کنیم. کد باینری این دستور به صورت 11101rrr است که سه بیت کم ارزش تر , آدرس ثبات منبع را مشخص می کند . با قرار دادن آدرس R7 یعنی 111 در کد باینری به جای rrr خواهیم داشت 11101111 که کد EFH برای دستور مذکور حاصل می شود.دستور مذکور محتوای ثبات R7 را به آکومولاتور منتقل می کند.
آدرس دهی مستقیم:
همانطور که می دانیم هر بیت (8 بیت) از حافظه میکرو به وسیله عددی منحصر به فرد که شماره ردیف آن بیت است مشخص می شود , این عدد منحصر به فرد آدرس نام دارد. از این جهت می گوییم منحصر به فرد زیرا هیچ دو بیت از حافظه میکرو دارای یک آدرس نیستند.
لذا با استفاده از این آدرس می توان به کلیه مکانهای حافظه دسترسی داشت . آدرس دهی مستقیم از این آدرس استفاده می کند. علائه بر آدرس , بیشتر مکانهای حافظه دارای نام نیز هستند. برای مثال پورت یک هم دارای آدرس 90H است و هم نام P1 را دارد. استفاده از هر دو (نام یا آدرس ) در برنامه نویسی مجاز است.
در برنامه نویسی هنگامی که عددی را بدون هیچ پیشوندی می نویسند نشان دهنده استفاده از آدرس دهی مستقیم است.
به عنوان مثال در دستور زیر:
MOV P1,A
که محتوای ثبات آکومولاتور (A) را به پورت P1 انتقال می دهد , از آدرس دهی مستقیم استفاده شده است.
آدرس دهی غیر مستقیم:
آدرس دهی غیر مستقیم از آدرس بایت مورد نظر استفاده می کند. تفائت آن با آدرس دهی مستقیم این است که در آدرس دهی غیر مستقیم آدرس مکان حافظه ابتدا در یکی از ثباتهای بانک ثبات قرار می گیرد و سپس ثبات مذکور به همراه پیشوند @ در دستورالعمل استفاده می شود.
کاربدر این نوع آدرس دهی برای مواقعی است که آدرس یک متغیر بیتی در زمان اجرای برنامه , نه در زمان نوشتن کد , محاسبه شود و نیز هنگام استفاده از مکانهای متوالی حافظه نیز باید از آدرس دهی غیر مستقیم استفاده کنیم . در موارد بالا نمی توانیم از آدرس دهی مستقیم و ثبات استفاده کنیم زیرا این دو آدرس دهی در هنگام کامپایل برنامه به آدرس مکان حافظه نیاز دارند در حالی که ما آدرس مکان حافظه را نمی دانیم.
برای فهم بیشتر مطلب دو دستور زیر را در نظر بگیرید:
MOV R0,#90h
MOV @R0,A
دستور اول عدد 90 در مبنای 16 را در ثبات R0 قرار می دهد. عدد 90h آدرس پورت یک می لاشد.دستور دوم به میکرو دستور می دهد تا محتوای ثبات A را در آدرسی که در R0 است (یا مکانی که R0 به آن اشاره می کند) قرار بده.
جمله بالا در مفاهیم برنامه نویسی به نام اشاره گر معروف است . اشاره گر متغیری است که آدرس مکان حافظه را در خود نگه می دارد.
در این دستور @R0 معادل همان P1 است.
آدرس دهی فوری یا بلافاصله:
در صورتی که بخواهیم یک عدد ثابت نه یک آدرس را در مکانی از حافظه قرار دهیم از آدرس دهی فوری استفاده می کنیم. دستور اول در مثال قبلی نوعی از آدرس دهی فوری بود . مشخصه آدرس دهی فوری استفاده از پیشوند # قبل از عدد است.
در صورتی که در یک دستور از عددی استفاده کنیم اگر عدد بدون پیشوند باشد نوع آدرس دهی مستقیم است و در صورتی که عدد پیشوند # داشته باشد آدرس دهی فوری خواهد بود.به این دو دستور توجه کنید تا این جمله را بهتر متوجه شوید:
MOV A,#90h
MOV A,9h
دستور اول عدد 90 در مبنای 16 را در ثبات A قارا می دهد . بعد از اجرای دستور مطمئن هستیم که محتوای ثبات A , . 90h است.دستور دوم مقداری را که در آدرس 90h حافظه است در ثبات A قرار می دهد یادآوری می کنم که 90h آدرس پورت یک است . بنابراین هر عددی که بر روی پورت یک باشد در درون ثبات A قرار خواهد گرفت و ما از مقدار این عدد هیچ اطلاعی نداریم.
آدرس دهی نسبی:
این نوع آدرس دهی در چند دستورالعمل پرشی به کار رفته است ( مانند ( sjmp با استفاده از این نوع آدرس دهی می توان به 127 بایت بالاتر و 127 بایت پایین تر از مکان فعلی برنامه پرش کرد. هنگامی که کامپایلر به این نوع دستورات پرشی می رسد آدرس مبدا را از آدرس مقصد تفریق می کند و نتیجه را به شمارنده برنامه اضافه می کند( (pc دستور زیر را در نظر بگیرید:
90 sjmp 100
اکنون در مکان 90 حافظه هستیم برنامه می خواهد به مکان 100 پرش کوتاه انجام دهد . آدرس مبدا از مقصد کم می شود (100-90) و به pc , +10 واحد اضافه می شود.
مزیت استفاده از این نوع آدرس دهی این است که کد مستقل از مکان ایجاد می کند.
آدرس دهی مطلق:
آدرس دهی مطلق فقط برای دستورات ACALL (فراخوانی سابروتین) و AJMP (پرش مطلق) به کار برده می شود و دو بایتی هستند . با این دستورات می توان تا 2K بایت در داخل یک صفحه حافظه پرش نمود.به عنوان مثال:
AJMP BACK
آدرس دهی بلند:
این نوع آدرس دهی با دستورات فذاخوانی سابروتین(( LCALL و دستور پرش بلند ((LJMP به کار برده می شود.این دستورات 3 بایتی هستند که در بایت دوم و سوم آنها آدرس 16 بیتی مقصد می باشد.
یکی از مزیتهای این دستورات این است که می توان به تمات فضای حافظه برنامه دسترسی پیدا کرد ولی اشکال آن ها این است که سه بایت طول دارند.به عنوان مثال:
LJMP FAR_AHEAD
آدرس دهی اندیس دار:
این نوع آدرس دهی در دستورات پرش ( ( JMP و انتقال ( (MOVC استفاده می شودکه محتوای ثبات پایه مانند((pc یا اشاره گر داده ((DPTR را با محتوای آکومولاتور جمع می کند تا آدرس مقصد حاصل شود.
هم چنین این نوع آدرس دهی در نوشتن جداول جستجو ((LOOUP TABLE استفاده می شود.به عنوان مثال:
MOVC A,@A+DPTR
انواع دستورات:
دركل دستوراتي كه دربرنامه نويسي ميكروكنترلر استفاده مي شوند به دودسته تقسيم مي شوند
1- دستورات مربوط به cpuدر ميكروكنترلر هاي 8051
2- دستورات مربوط به assembler
تفاوت اين دونوع دستوراين است كه دستورهاي assembler درهنگام كامپايل شدن اجرامي شوندوبراي رساندن مفهومي به اسمبلراست ولي دستورهاي نوع اول در داخل ميكرو اجرامي شوند.
شروع برنامه نويسي:
اگرتاكنون بازبان هاي برنامه نويسي مختلف كاركرده باشيد مشاهده كرده ايد كه تمامي آنها محيط مخصوص به خودرا دارا مي باشندوليكن خصوصيت زبان اسمبلي اين است كه تنها نياز به محيطي دارد كه اصطلاحاً قابليت(Text Editor) را داشته باشد.
اگر محيط كارشما ويندوزباشد مي توانيد با اجرا نمودن نرم افزار NOTE PAD وچنانچه در سيستم عامل dosكارمي كنيدمي توانيد با اجراي نرم افزارEdit.exe محيط برنامه نويسي خودرافعال نماييد.
هم اكنون شما مي توانيد دستورات برنامه نويسي رادراين محيط تايپ نماييد.
به طور کلی دستورات میکروکنترولر 8051 به 5 گروه تقسیم شده اند که
عبارتند از:
- دستورات محاسباتی
- دستورات منطقی
- دستورات انتقال اطلاعات
- دستورات روی بیت
- دستورات کنترلی
دستور ORG :
org
دستورفوق كه مربوط به Assembler مي باشدبه شما امكان مي دهد،آدرس شروع برنامه در حافظه برنامهeeprom ميكروكنترلر راتعيين نماييد. مثال:
org 0h
اين دستور شروع برنامه در حافظه راازخانه صفرآن تعيين مي كند
دستورات محاسباتی:
این مجموعه دستورات شامل دستورات جمع و تفریق و کاهش و افزایش و ضرب و تقسیم 8 بیتی می باشند.
دستور :ADD
دستوراالعمل ADD برای جمع کردن یک مقدار 8 بیتی با ثبات A مورد استفاده قرار می گیرد. عملوند اول این دستور ثبات A می باشد این دستورالعمل در 4 مورد آدرس دهی (که قبلا بحث کردیم ) مورد استفاده قرار می گیرد.
دستور دیگری برای جمع وجود دارد با سمبل ADC که مخفف ADD whit carry می باشد و به معنی جمع با رقم نقلی است عملکرد آن بدین صورت است که ابتدا مقدار بیت C (نقلی) با ثبات A جمع شده و سپس عملوند دوم هم به ثبات A اضافه می شود . این دستور هم مانند دستور ADD در 4 مود آدرس دهی گفته شده مورد استفاده قرار می گیرد.
دستورالعمل تقسیم 8 بیتی:
DIV A
این دستورالعمل مقدار موجود در ثبات A را بر مقدار موجود در ثبات B تقسیم می کند . خارج قسمت در ثبات A و باقیمانده عمل تقسیم در ثبات B ذخیره خواهد شد.
فرض کنید که ثبات A حاوی مقدار 11 است و ثبات B حاوی مقدار 4 باشد پس از اجرای عمل تقسیم مقدار 2 در ثبات A و مقدار 3 در ثبات B ذخیره خواهد شد.
دستورالعمل افزایش(:(INC
یک دستورالعمل تک عملوندی است این دستور عملوند خود را یک واحد افزایش می دهد . نکته ای که در مورد این دستورالمل باید به آن توجه کرد اینست که هیچ پرچمی بعد از اجرای دستور تغییر نخواهد کرد برای مثال اگر ثبات A حاوی مقدار #0ffh باشد بعد از اجرای این دستور مقدار A , 00 خواهد شد اما پرچم OVER FLOW تغییر نخواهد کرد.
این دستورالعمل در سه مورد آدرس دهی ثبات . مستقیم و غیر مستقیم عمل می کند.
دستورالعمل کاهش(:(DEC
یک دستورالعمل تک عملوندی است . پس از اجرای این دستور از محتوای عملوند یک واحد کم می شود.به عنوان مثال اگر ثبات A حاوی مقدار 10 باشد پس از اجرای DEC A ثبات A حاوی مقدار 9 خواهد بود.
دستورالعمل ضرب(:(MULL
MULL AB
این دستور محتوای ثبات A را در ثبات B ضرب می کند نتیجه ضرب بدین گونه ذخیره می شود بیت پایین حاصلضرب در ثبات A و بیت بالای حاصلضرب در ثبات B ذخیره می شود.
دستورالعمل تفریق(:(SUBB
دستور SUBB برای تفریق یک مقدار 8 بیتی از ثبات A مورد استفاده قرار می گیرد این دستور مخفف Sub with BARROW است و عملوند دوم را به اضافه Carry از ثبات A کم می کند اگر در جریان تفریق از بیت هشتم نیاز به رقم قرضی باشد Carry یک می شود و در غیر این صورت صفر می شود .
دستورالعمل منطقی:
این دستورالعمل ها بر روی تک تک بیت ها اعمال منطقی AND,OR,XOR را انجام می دهند . دستورات چرخش و شیفت بیتی هم در زمره این دستورات هستند.
در AND کردن نتیجه دو بیت زمانی یک است که هر دو بیت یک باشند . در OR کردن دو بیت نتیجه دو بیت زمانی صفر است که هر دو بیت صفر باشند. در XOR کردن نتیجه هنگامی صفر است که هر دو بیت یا صفر باشند یا یک.
XOR برای مکمل کردن بیت ها هم به کار می رود نتیجه XOR یک بیت با بیت 1 مکمل آن خواهد بودو نتیجه xor یک بیت با بیت 0 خود آن بیت را نتیجه خواهد داد . این دستورات برای مکمل کردن بیت های مشخصی از یک بایت حافظه که بیت آدرس پذیر نیستند مفید است.
دستور اسمبلی که برای AND کردن مورد استفاده قرار می گیرد ANL (And Logic) است.
دستورات OR کردن و XOR کردن هم ساختاری مانند دستور ANL داند فقط برای OR از ORL و برای XOR از XRL استفاده می کنیم.
دستور دیگری هم با نام CPL وجود دارد که کارش مکمل کردن عملوند خود است.
دستورات چرخشی:
چهار دستور RR A,RL A,RLC A,RRC A برای عملیات چرخشی مورد استفاده قرار می گیرد.
RLA بیت های ثبات A را یک واحد به طرف چپ چرخش می دهد بیت شماره هفت از ثبات خارج می سود و دوباره وارد بیت شماره صفر می شود اگر ثبات A حاوی #10000001 b باشد:
10000001--------------> 00000011
RR L ثبات را یک واحد به راست چرخش می دهد در دستورات چرخش بیتی که خارج می شود از طرف دیگر وارد ثبات می شود
10000001-------------------> 11000000
RLC A, RRC A هم مشابه دستورات بالا هستند با این تفاوت که بیتی که از یک طرف خارج می شود وارد بیت Carry می شود و محتوای قبلی Carry از طرف دیگر وارد ثبات می گردد.
دستورات انتقال اطلاعات:
دستورات انتقال داده به دو دسته RAM خارجی و دستورهای RAM داخلی تقسیم می شوند .
MOV
اين دستور براي كپي كردن يك خانه از حافظه يا داده ها در بايت ها ي حافظه استفاده مي شود.توجه كنيدكه اين دستوريك دستوربايتي است.
مثال1:
mov p1,#55h
اين دستور مقدارعددي 55 درمبناي شانزده رادر بايتي از حافظه به نام p1مي ريزد.
mov p1,#85d
اين دستور مقدارعددي 85 درمبناي ده رادر بايتي از حافظه به نام p1مي ريزد.
mov p1,#010100011b
اين دستور مقدارعددي 01010011 درمبناي دو را در بايتي از حافظه به نام p1 مي ريزد.
توجه :همانطوركه در دستور ات بالامشاهده نموديدعلامت# قبل ازهركدام ازاعداد قيد شده بود.اين علامت براي مشخص نمودن اين مفهوم است كه مقدارعددي عبارت بعدي مي بايست دربايت معرفي شده از حافظه ريخته شود.
مثال2:
mov p1,55h
اين دستور محتويات داخل بايت 55h حافظه رادرخانه مي ريزد.دقت كنيدكه تمام ثبات هاي موجود را مي توان به جاي اين بايت استفاده كرد.
مثال3:
mov a,p1
mov a,p2
درمثال بالا اگربخواهيم اطلاعات روي p1 راروي p2 بريزيم ابتدا بايد ديتا را به آكومولاتورانتقال دهيم وسپس از اكومولاتور به p2انتقال دهيم.
عبارتb,d,hكه بعد از مقدارهاي عددي قيد شده آمده است مبين مبناي عدد مي باشد.
B=Binary
D=Decimal
H=Hexadecimal
دستورات 16 بیتی انتقال اطلاعات:
دستورات انتقال اطلاعات 16 بیتی برای مقدار اولیه دادن به اشاره گر داده((DPTR به صورت زیر است:
MOV DPTR,#DATA16
ثبات اشاره گر داده برای دسترسی به حافظه داده خارجی یا جداول حافظه به کار برده می شود مثال:
MOV DPTR,#1234H
این دستور عدد 1234H را به ثبات اشاره گر داده بار می کند.
دستور :XCH
فرم کلی این دستور به صورت زیر است:
XCH A,آدرس منبع
که باعث می شود تا محتوای ثبات آکومولاتور A با خانه ای که آدرس آن داده شده , جابجا شود. به عنوان مثال :
XCH A,20H
محتوای خانه حافظه 20H را با محتوای آکومولاتور A , جابجا می کند.
دستور حافظه داده خارجی :RAM
دستورات انتقال اطلاعات که داده را با حافظه خارجی مبادله می کند مانند MOVX از آدرس دهی غیر مستقیم استفاده می کند.
آدرس دهی غیر مستقیم:
* یا یک بایت آدرس از طریق @R0 (Ri که برابر R0 یا R1 است) استفاده می کند.
* و یا دو بایت آدرس اشاره گر داده را به صورت @DPTR به کار می برد.
مثال:
دستوراتی بنویسید که محتوای خانه های حافظه به آدرس های 10F4H , 10F5H را بخواند و آن ها را به ترتیب در ثباتهای R6,R7 قرار دهد.
حل: دستورات مذکور مطابق زیر می باشند:
MOV DPTR,#10F4H دستور (1)
دستور (2) MOV A,@DPTR
MOV R6,A دستور (3)
INC DPTR دستور (4)
MOVX A,@DPTR دستور (5)
MOV R7,A دستور (6)
دستور 1 : آدرس 16 بیتی 10F4H را در ثبات اشاره گر قرار می دهد.
دستور 2: محتوای خانه حافظه ای که با اشاره گر داده نشان داده شده یعنی محتئای خانه حافظه 10F4H را می خواند و در آکومولاتور A قرار می دهد.
دستور 3: محتوای آکومولاتور A را در ثبات R6 قرار می دهد به این ترتیب اولین خواسته مسئله انجام شده است.
دستور 4: به ثبات اشاره گر داده یک واحد اضافه می کند یعنی اشاره گر داده برابر 10F5H می شود.
دستور 5: محتوای خانه حافظه ای که با اشاره گر داده نشان داده شده را می خواند و در ثبات آکومولاتور A قرار می دهد.
دستور 6: محتوای آکومولاتور A را در ثبات R7 قرار می دهد یعنی خواست دوم مسئله انجام می پذیرد.
نکته: فقط با دستور MOVX می توان به حافظه داده خارجی RAM دسترسی داشت در این صورت یکی از عملوندها حتما آکومولاتور می باشد.
EQU
اين دستورمربوط به اسمبلر بوده وجهت نامگذاري قسمتي از حافظه داخلي ميكرو كنترلر استفاده مي شود
مثال4: برنامه زير خانه 20از حافظه رابه memory نامگذاري مي كند.
Memory equ 20h
ايجاد حلقه در برنامه نويسي ميكروكنترلر :
دستورات کنترل برنامه:
اين دستور براي پرش به مكاني از برنامه استفاده مي شود كه اين مكان يك برچسب است كه قبلاً نامگذاري شده است.دقت كنيدكه براي پرش هاي كوتاه مي توان ازدستور sjmpوبراي پرش هاي بلنداز دستور ljmp استفاده كرد.
مثال5:
loop:
.
.
.
jmp loop
دستور فوق به مكاني از برنامه به نام loopپرش مي كند.
loop:jmp loop
اين خط برنامه باعث مي شود cpu دريك حلقه گيركند.البته مي توان به جاي برنامه فوق ازدستورjmp$ نيز استفاده كرد.
end
اين دستور مربوط به اسمبلر است كه نشان دهنده پايان برنامه وخروج ازآن است.لازم به ذكراست اين دستور مي بايست هميشه آخرين خط برنامه باشد.
نكته:شمابايد به گونه اي برنامه نويسي نماييدكه هيچگاه برنامه به دستور end نرسد.
نمونه برنامه(1):
باتركيب دستورات فوق شما مي توانيد يك برنامه ساده بنويسيد:
org 0
mov p1,#55h
loop:jmp loop
end
باپروگرام نمودن ic وقراردادن آن برروي بردآموزشي اين برنامه باعث مي شودكه ledهاي روي برد به صورت يك درميان روشن شوند.چرا؟
حال به تحليل برنامه ونحوه كار آن مي پردازيم:
اولين دستور كه نمايانگر خانه شروع برنامه است.همانطوركه درمباحث ميكرو كنترلر 89c51 مطالعه نموده ايد،p1 دقيقاً يك بايت از حافظه ram ميكروكنترلر مي باشد كه به ازاي هربيت خوديك پايهi/o برروي ميكروكنترلر دارد (پايه يك تاهشت).حال اگرهر بيت ازاين حافظه يك شودشما روي پايه نظيرآن +5vو چنانچه صفر شود شماروي پايه نظير هر بيت مقدارصفريا gnd خواهيدداشت و بالعكس.
حال عدد55h رابه باينري تبديل نماييد ودربيت هاي نظير حافظه قراردهيد.
55H=010101010B
دقيقاً به ازاي عددباينري بالا پايه هاي ميكرو فعال مي شوند.
نكته :البته توجه نماييد ledهاي روي بردآموزشي به صورت آندمشترك بسته شده اند در نتيجه Active Lowهستند،پس به ازاي هرصفرledروشن مي شود.
دستورات پرش های شرطی:
میکروکنترولر دارای تعدادی دستورات پرش شرطی است که عبارتند از JZ , JNZ , DJNZ , CJNE
دستور :JZ
JZ آدرس مقصد یا برچسب دستور
این دستور یعنی اگر محتوای آکومولاتور A برابر 0 است به آدرس مقصد پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JNZ
JNZ آدرس مقصد یا برچسب دستور
یعنی اگر محتوای آکومولاتور A برابر 0 نباشد به آدرس مقصد پرش می کند در غیر این صورت دستور بعدی اجرا می گردد.
دستور :CJNE
این دستور برای عملیات حلقه به کار می رود و فرم کلی آن به صورت زیر است:
CJNE اپراند 1 , آدرس نسبی. اپراند 2
این دستور اپراند 1 را با اپراند 2 مقایسه می کند اگر مساوی نباشد به آدرس نسبی مقصد پرش می کند در غیر این صورت دستور بعدی اجرا می شود.
ايجادتأخيرزماني درروند فعاليت ميكرو به وسيله حلقه ها:
DJNZ COUNT,LOOP
اين دستور مقدارعددي خانه اي از حافظه راكه قبلاً توسط دستورEQUبه نام countتعريف شده است رايك واحد كاهش مي دهدواگرمقدارآن خانه صفرنبودبه آدرسي از خانه حافظه به نام loopپرش مي كند
درمثال زير بايت ها ايجاد يك تأخير زماني دو مقدار مختلف رابرروي پورت يك بايت ها فاصله زماني مشخص رامي توانيم روي اسكوپ ببينيم.
نمونه برنامه(2):
count equ 30h
org 00h
main:
mov count ,#200
mov p1,#01010101b
loop:djnz count,loop
mov p1,#10101010b
mov count,#250
loop1:djnz count,loop
jmp main
برنامه فوق يك بار پورت يك رابا55h فعال كرده وبعداز 400µs پورت يك را با aah بارگذاري مي كندوبعداز501µs دوباره پورت رابا 55hبارگذاري مي كند وهمين كارادامه خواهدداشت.شايدازخود بپرسيدچگونه متوجه مي شويم مقدارپورتها ، بعد از گذشت چه زماني عوض مي شوند؟
خيلي ساده است انجام هر دستور djnzدو سيكل ماشين زمان نيازداردودرحلقه اول ما200باراين دستور رااجرانموديم پس درمجموع400µsودرحلقه بعدي چون قبل ازآن يك دستورmov وجودداردومي دانيم براي انجام اين دستور نيز يك سيكل ماشين زمان نياز داريم درمجموع1+250*2سيكل ماشين تأخير ايجادشده است.
نكته:طبق استانداردي كه براي سخت افزار ميكرو قرارداده شده است ازنوسان ساز 12MHz استفاده مي كنيم ودرنتيجه هر سيكل ماشين يك ميكروثانيه زمان نيازدارد.
شما مي توانيد براي تست بصري اين تغييرات ازدستگاه اسكوپ استفاده نماييد.زيرابه علت سرعت زيادledها تغييرات آن براي ماشين ملموس نيست .
z= 10* y
براي تنظيم زمان بيشتر مي توانيدازچندحلقه متداخل استفاده نماييدكه بايك مثال درزيرنشان داده شده است.
x=loop1=2*255
y= 255 * x
y=loop2=255*x
x=2*255
z=loop3=10*y
درنتيجه
z=10*(255*(2*255))=1300500
پس باتشكيل حلقله هاي روبرو تقريباً3/1ثانيه تأخير ايجادنموديم.
البته توجه نماييدماازمقدارتأخير مربوط به خودdjnzدرحلقه دوم وسوم صرف نظر كرديم زيرا درمقابل عددبدست آمده مقدارناچيزي است.وماازآن چشم پوشي مي كنيم.
نمونه برنامه (3):
برنامه اي بنويسيدكه ledهاي متصل به پورت يك ،دربردآموزشي راباسرعت حدودي يك تادوثانيه خاموش وروشن كند.
count1 equ 20h
count2 equ 21h
count3 equ 22h
main:
mov p1,#0ffh
اين دستور باعث مي شود تمام ledهاي متصل به روي پورت p1خاموش شوند
(چون اين ledهابه صورت آند مشترك بسته شده اند.)
call delay
حدوديك ثانيه تأخير
mov p1,#oh
روشن كردن ledها
call delay
يك ثانيه تأخير
jmp main
پرش به ابتداي main
delay:
mov count2,#255
mov count3,#10
loop3:
mov count2,#255
loop2:
mov count1,#255
loop1:djnz count1,loop1
djnz count2,loop2
djnz count3,loop3
ret
end
دستور call:
در برنامه فوق چون زيرروال delay تكرارشده بودماازتكرارآن خودداري كرديم واز دستورcall استفاده كرديم ودرهنگام انجام اين دستور براي زيربرنامه cpu,delay به ابتداي برنامه delayرفته وآن رااجرامي كند تابه دستور ret برسد.پس از انجام كامل اين مرحله ورسيدن به دستور retاززير برنامه delay, برگشته وقفه كارخود را بعد از دستور callادامه مي دهد.شما با روش هاي مشابه مي توانيد به صورت تقريبي تأخيرمورد نظرخودرا دركنترلرها اعمال نماييد، ولي براي ايجاد تأخيرهاي دقيق تر در اجراي برنامه مي توانيد از timerها (كه درادامه به بحث درمورد آنها مي پردازيم) استفاده كنيد.
استفاده دستورات بيتي در ميكروكنترلر :
همان طور كه ملاحظه نموديد8051 دستوراتي جهت كارروي بايت هاي حافظه دارد. توجه داشته باشيد شماتوسط دستورات بايتي نمي توانيدروي يك خانه ازبيت حافظه كار كنيد.جهت كاربابيت هامي توانيد از دستورات بيتي زير استفاده نماييد.
setb
يك بيت را يك كرده
setb p1.0
بيت صفر از بايت p1 رايك كرده وتأثيري روي بقيه بيت ها ندارد.
P1
X
X
X
X
X
X
X
1
D7
D6
D5
D4
D3
D2
D1
D0
clr
يك بيت راصفر كرده
clr p0,5
بيت پنجم ازبايت p0راصفركرده وتأثيري روي بقيه بيت هاندارد.
P0
X
X
X
0
X
X
X
X
D7
D6
D5
D4
D3
D2
D1
D0
jnb
پرش درصورت يك نبودن
jnb P1.2,loop
اين دستور بيت دوم بايت p1رابررسي مي كند،اگراين پايه ازبيرون gndشده بود به loop پرش كرده ودرغيراينصورت برنامه از خط بعدي ادامه خواهديافت.بيشترين كاربرد اين دو دستور براي چك كردن كليد است كه درادامه يك مثال براي روشن شدن موضوع آورده شده است.
jb
پرش درصورت يك بودن
jb P1.2,loop
اين دستور بيت دوم بايت p1رابررسي مي كند،اگراين بیت یک باشد به loop پرش كرده ودرغيراينصورت برنامه از خط بعدي ادامه خواهديافت .
دستور :JBC
Jbc BIT , آدرس مقصد یا برچسب دستور
یعنی اگر بیت ( (BITمورد نظر برابر 1 است آن را 0 کن و به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JC
Jc آدرس مقصد یا برچسب دستور
یعنی اگر بیت نقلی ( (Cمورد نظر برابر 1 است به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JNC
Jnc آدرس مقصد یا برچسب دستور
یعنی اگر بیت نقلی ( (Cمورد نظر برابر 1 نیست به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
نمونه برنامه (4):
برنامه اي بنويسيد كه بازدن كليدp3.3 عدد 55h روي p1 قراربگيردوبازدن كليدp3.5 عدد aah روي p1 قراربگيرد.
org 00h
scan:
jnb p3.3,num1
jnb p3.5,num2
jmp scan
num1:
mov p1,#55h
jmp scan
num2:
mov p1,#0aah
jmp scan
end
بانک های ثبات:
8051 دارای 8 ثبات با نامهای R0-R7 میباشد دستوراتی که از این ثباتها استفاده می کنند نسبت به دستورات مشابه خود که از انواع دیگر آدرس دهی استفاده می کنند دارای تعداد بیت کمتر و سرعت بیشتری هستند بنابراین در صورتی که از داده ای به طور متناوب در برنامه استفاده می کنیم بهتر است که این داده در یکی از ثباتهای بانک ثبات قرار گیرد.
در 8051 , 4 بانک ثبات وجود دارد که در هر لحظه از زمان می توان فقط یکی از این بانکها را فعال و از آن استفاده کرد . برای فعال کردن یک بانک ثبات از دو بیت با نامهای PSW.3, PSW.4 استفاده می کنیم این 2 بیت اجزای ثبات PSW هستند.
ثبات PSW:
مخفف Program status word یا کلمه وضعیت سیستم است .این ثبات در هر سیکل ماشین بسته به وضعیت و جواب برنامه تغییر می کند و برنامه نویس می تواند بر اساس این تغییرات منطق برنامه را تغییر دهد. PSW مشابه FLAG های ریزپردازنده های سیستم های میکروکامپیوتری می باشد.
شکل زیر بیتهای ثبات وضعیت (PSW) را نشان می دهد.
C یا CY
AC
F0
RS1
RS0
OV
----
P
شکل 1-3
بیت توازن ((P :
این بیت تنظیم توازن زوج , مقدار آن صفر یا یک می شود . در صورتیکه تعداد یکهای داخل آکومولاتور فرد باشد این بیت یک می شود تا مجموع یکها زوج باشد این یک روش ساده تشخیص تعداد فرد خطا در انتقال اطلاعات می باشد.برای مثال اگر آکومولاتور عدد 00000011 را در مبنای دو در خود داشته باشد چون در این مثال تعداد 1 ها دو عدد می باشد بنابراین بیت توازن صفر می شود تا تعداد یکها ی زوج باقی بماند.این بیت اکثرا در روتین های پورت سری استفاده می شود به طوری که اطلاعات با بیت توازن ارسال می شود و در موقع دریافت اطلاعات بیت توازن تست می گردد.
بیت پرچم سرریز یا OV :
این بیت با نام OVER FLOW یا سرریز نام دارد. اگر هنگام جمع یا تفریق حسابی نتیجه حاصل بزرکتر از 127 + یا کوچکتر از 127- شود سرریز اتفاق می افتد و بیت OV برابر 1 می شود.
بیت های انتخاب بانک ثبات :(RS0,RS1)
این دو بیت به منظور فعال کردن یکی از 4 بانک ثبات مورد استفاده قرار می گیرد.مقدار پیش فرض این 2 بیت 00 است که بانک ثبات 0 را فعال می کند.
بیت :FO
این بیت با نام پرجم صفر هم شناخت هشده است. اگر نتیجه یک عمل حسابی صفر شوداین بیت یک می شود.
بیت :AC
در هنگام انجام عملیات حسابی در صورتی که از بیت شماره 3 به شماره 4 رقن نقلی داشته باشیم در این صورت این بیت یک می شود.
بیت پرچم نقلی یا :CY
این بیت به دو منظور به کار می رود:
1- در مواقع محاسبات یعنی زمانی که عمل جمع انجام می شود اگر از بیت 7 رقم خارج شود بیت C یک می شود.
2- اگر در زمان تفریق از بیت 7 قرض گرفته شود در این صورت بیت C برابر یک می شود.
ثبات A:
این ثبات Accumulator یا انباره نامیده می شود. این ثبات همه منظوره است . بیشتر دستورات میکروکنترولر با این ثبات کار می کنند بنابراین ابتدا باید داده در این ثبات قرار بگیرد سپس عملیات انجام شود.
ثبات :B
ثبات یا آکومولاتور B در آدرس F0H حافظه قرار دارد و معمولا با ثبات A برای محاسبات ضرب و تقسیم استفاده می شود.
ثبات B را می توان به عنوان یک ثبات عمومی برای هر کاربرد دیگری نیز لستفاده نمود. علاوه بر این بیت های ثبات B آدرس پذیر و از آدرس F0H تا F7H می باشند لذا می توان با دستورات روی بیت , عملیات بر روی آنها انجام داد.
ثبات DPTR یا اشاره گر داده:
این ثبات یک ثبات 16 بیتی است که از 2 ثبات 8 بیتی با نامهای DPL,DPH ساخته شده است و به عنوان اشاره گر داده به کار می رود.ای ثبات برای دسترسی به حافظه کد و داده خارجی به کار می رود. به عنوان مثال دستورات زیر عدد 55H را در حافظه داده خارجی RAM می نویسند:
MOV A,#55H
MOV DPTR,#1000H
MOV @DPTR,A
اشاره گر پشته یا :SP
SP یک ثبات 8بیتی می باشد که آدرس اطلاعات بالای حافظه پشته را دارا می باشد . عملیات حافظه پشته شامل قرار دادن اطلاعات در بالای حافظه پشته ( با دستور ( PUSH یا برداشتن اطلاعات (با دستور (POP از بالای حافظه پشته می باشد.
هربار که اطلاعات در حافظه پشته قرار می گیرد ابتدا به محتوای SP یک واحد اضافه می شود و سپس اطلاعات در حافظه پشته نوشته می شود ((PUSH
هربار که اطلاعاتی از حافظه پشته خوانده می شود ( ( POPابتدا اطلاعات خوانده می شود و سپس یک واحد از SP کم می شود.
روش های آدرس دهی:
مبحث مهمی که در برنامه نویسی به زبان اسمبلی وجود دارد شیوه های آدرس دهی است .منظور از آدرس دهی روش دستیابی میکروکنترلر به اطلاعات است . روش های آدرس دهی مبدا و مقصد داده ها را تعیین می کند و اینکه در جریان انتقال داده ها از مقصد به مبدا چه عملیات بیتی انجام می شود .
در 8051 . هشت نوع آدرس دهی وجود دارد که عبارتند از:
1- آدرس دهی ثبات((Rejister Addresing
2- آدرس دهی مستقیم((Direct Addresing
3- آدرس دهی غیر مستقیم((Indirect Addresing
4- آدرس دهی فوری ((Immediate Addresing
5- آدرس دهی نسبی ( (Relative Addresing
6- آدرس دهی مطلق ((Absolute Addresing
7- آدرس دهی بلند ((Long Addresing
8- آدرس دهی اندیس دار ((Index Addresing
1- آدرس دهی ثبات:
در 8051 هشت ثبات با نام بانک ثبات وجود دارد که این ثبات ها به صورت تک تک با نامهای R0-R7 شناخته می شوند تعدادی از دستورالعمل های 8051 بر روی این ثباتها کار می کنند ابن دستورالعملها را دستورهای با آدرس دهی ثبات گویند.در دستورا ت آدرس دهی ثبات , سه بیت کم ارزشتر کد دستور , آدرس ثباتهای مذکور را مشخص می کند بنابراین کد اجرا و آدرس ثبات در یک بایت دستور قرار می گیرد.
زبان اسمبلی میکروکنترولر 8051 , آدرس دهی ثبات را با سمبل RN مشخص می کند که N بین 0 تا 7 می باشد.به عنوان مثال برای اضافه کردن محتوای ثبات R7 به آکومولاتور دستور زیر استفاده می شود:
ADD A,R7
کد اجرای این دستور 00101111 است که 5بیت پر ارزشتر یعنی 00101 دستور جمع ADD و سه بیت کم ارزش تر آن یعنی 111 ثبات R7 را مشخص می نماید.
مثال2: کد اجرای دستور زیر چیست و این دستور چه عملی انجام می دهد؟
MOV A,R7
فرم کلی دستور MOV به صورت زیر است:
منبع , مقصد MOV
اصولا 15 نوع دستور MOV وجود دارد که در اینجا نوع MOV A,Rn را بررسی می کنیم. کد باینری این دستور به صورت 11101rrr است که سه بیت کم ارزش تر , آدرس ثبات منبع را مشخص می کند . با قرار دادن آدرس R7 یعنی 111 در کد باینری به جای rrr خواهیم داشت 11101111 که کد EFH برای دستور مذکور حاصل می شود.دستور مذکور محتوای ثبات R7 را به آکومولاتور منتقل می کند.
آدرس دهی مستقیم:
همانطور که می دانیم هر بیت (8 بیت) از حافظه میکرو به وسیله عددی منحصر به فرد که شماره ردیف آن بیت است مشخص می شود , این عدد منحصر به فرد آدرس نام دارد. از این جهت می گوییم منحصر به فرد زیرا هیچ دو بیت از حافظه میکرو دارای یک آدرس نیستند.
لذا با استفاده از این آدرس می توان به کلیه مکانهای حافظه دسترسی داشت . آدرس دهی مستقیم از این آدرس استفاده می کند. علائه بر آدرس , بیشتر مکانهای حافظه دارای نام نیز هستند. برای مثال پورت یک هم دارای آدرس 90H است و هم نام P1 را دارد. استفاده از هر دو (نام یا آدرس ) در برنامه نویسی مجاز است.
در برنامه نویسی هنگامی که عددی را بدون هیچ پیشوندی می نویسند نشان دهنده استفاده از آدرس دهی مستقیم است.
به عنوان مثال در دستور زیر:
MOV P1,A
که محتوای ثبات آکومولاتور (A) را به پورت P1 انتقال می دهد , از آدرس دهی مستقیم استفاده شده است.
آدرس دهی غیر مستقیم:
آدرس دهی غیر مستقیم از آدرس بایت مورد نظر استفاده می کند. تفائت آن با آدرس دهی مستقیم این است که در آدرس دهی غیر مستقیم آدرس مکان حافظه ابتدا در یکی از ثباتهای بانک ثبات قرار می گیرد و سپس ثبات مذکور به همراه پیشوند @ در دستورالعمل استفاده می شود.
کاربدر این نوع آدرس دهی برای مواقعی است که آدرس یک متغیر بیتی در زمان اجرای برنامه , نه در زمان نوشتن کد , محاسبه شود و نیز هنگام استفاده از مکانهای متوالی حافظه نیز باید از آدرس دهی غیر مستقیم استفاده کنیم . در موارد بالا نمی توانیم از آدرس دهی مستقیم و ثبات استفاده کنیم زیرا این دو آدرس دهی در هنگام کامپایل برنامه به آدرس مکان حافظه نیاز دارند در حالی که ما آدرس مکان حافظه را نمی دانیم.
برای فهم بیشتر مطلب دو دستور زیر را در نظر بگیرید:
MOV R0,#90h
MOV @R0,A
دستور اول عدد 90 در مبنای 16 را در ثبات R0 قرار می دهد. عدد 90h آدرس پورت یک می لاشد.دستور دوم به میکرو دستور می دهد تا محتوای ثبات A را در آدرسی که در R0 است (یا مکانی که R0 به آن اشاره می کند) قرار بده.
جمله بالا در مفاهیم برنامه نویسی به نام اشاره گر معروف است . اشاره گر متغیری است که آدرس مکان حافظه را در خود نگه می دارد.
در این دستور @R0 معادل همان P1 است.
آدرس دهی فوری یا بلافاصله:
در صورتی که بخواهیم یک عدد ثابت نه یک آدرس را در مکانی از حافظه قرار دهیم از آدرس دهی فوری استفاده می کنیم. دستور اول در مثال قبلی نوعی از آدرس دهی فوری بود . مشخصه آدرس دهی فوری استفاده از پیشوند # قبل از عدد است.
در صورتی که در یک دستور از عددی استفاده کنیم اگر عدد بدون پیشوند باشد نوع آدرس دهی مستقیم است و در صورتی که عدد پیشوند # داشته باشد آدرس دهی فوری خواهد بود.به این دو دستور توجه کنید تا این جمله را بهتر متوجه شوید:
MOV A,#90h
MOV A,9h
دستور اول عدد 90 در مبنای 16 را در ثبات A قارا می دهد . بعد از اجرای دستور مطمئن هستیم که محتوای ثبات A , . 90h است.دستور دوم مقداری را که در آدرس 90h حافظه است در ثبات A قرار می دهد یادآوری می کنم که 90h آدرس پورت یک است . بنابراین هر عددی که بر روی پورت یک باشد در درون ثبات A قرار خواهد گرفت و ما از مقدار این عدد هیچ اطلاعی نداریم.
آدرس دهی نسبی:
این نوع آدرس دهی در چند دستورالعمل پرشی به کار رفته است ( مانند ( sjmp با استفاده از این نوع آدرس دهی می توان به 127 بایت بالاتر و 127 بایت پایین تر از مکان فعلی برنامه پرش کرد. هنگامی که کامپایلر به این نوع دستورات پرشی می رسد آدرس مبدا را از آدرس مقصد تفریق می کند و نتیجه را به شمارنده برنامه اضافه می کند( (pc دستور زیر را در نظر بگیرید:
90 sjmp 100
اکنون در مکان 90 حافظه هستیم برنامه می خواهد به مکان 100 پرش کوتاه انجام دهد . آدرس مبدا از مقصد کم می شود (100-90) و به pc , +10 واحد اضافه می شود.
مزیت استفاده از این نوع آدرس دهی این است که کد مستقل از مکان ایجاد می کند.
آدرس دهی مطلق:
آدرس دهی مطلق فقط برای دستورات ACALL (فراخوانی سابروتین) و AJMP (پرش مطلق) به کار برده می شود و دو بایتی هستند . با این دستورات می توان تا 2K بایت در داخل یک صفحه حافظه پرش نمود.به عنوان مثال:
AJMP BACK
آدرس دهی بلند:
این نوع آدرس دهی با دستورات فذاخوانی سابروتین(( LCALL و دستور پرش بلند ((LJMP به کار برده می شود.این دستورات 3 بایتی هستند که در بایت دوم و سوم آنها آدرس 16 بیتی مقصد می باشد.
یکی از مزیتهای این دستورات این است که می توان به تمات فضای حافظه برنامه دسترسی پیدا کرد ولی اشکال آن ها این است که سه بایت طول دارند.به عنوان مثال:
LJMP FAR_AHEAD
آدرس دهی اندیس دار:
این نوع آدرس دهی در دستورات پرش ( ( JMP و انتقال ( (MOVC استفاده می شودکه محتوای ثبات پایه مانند((pc یا اشاره گر داده ((DPTR را با محتوای آکومولاتور جمع می کند تا آدرس مقصد حاصل شود.
هم چنین این نوع آدرس دهی در نوشتن جداول جستجو ((LOOUP TABLE استفاده می شود.به عنوان مثال:
MOVC A,@A+DPTR
انواع دستورات:
دركل دستوراتي كه دربرنامه نويسي ميكروكنترلر استفاده مي شوند به دودسته تقسيم مي شوند
1- دستورات مربوط به cpuدر ميكروكنترلر هاي 8051
2- دستورات مربوط به assembler
تفاوت اين دونوع دستوراين است كه دستورهاي assembler درهنگام كامپايل شدن اجرامي شوندوبراي رساندن مفهومي به اسمبلراست ولي دستورهاي نوع اول در داخل ميكرو اجرامي شوند.
شروع برنامه نويسي:
اگرتاكنون بازبان هاي برنامه نويسي مختلف كاركرده باشيد مشاهده كرده ايد كه تمامي آنها محيط مخصوص به خودرا دارا مي باشندوليكن خصوصيت زبان اسمبلي اين است كه تنها نياز به محيطي دارد كه اصطلاحاً قابليت(Text Editor) را داشته باشد.
اگر محيط كارشما ويندوزباشد مي توانيد با اجرا نمودن نرم افزار NOTE PAD وچنانچه در سيستم عامل dosكارمي كنيدمي توانيد با اجراي نرم افزارEdit.exe محيط برنامه نويسي خودرافعال نماييد.
هم اكنون شما مي توانيد دستورات برنامه نويسي رادراين محيط تايپ نماييد.
به طور کلی دستورات میکروکنترولر 8051 به 5 گروه تقسیم شده اند که
عبارتند از:
- دستورات محاسباتی
- دستورات منطقی
- دستورات انتقال اطلاعات
- دستورات روی بیت
- دستورات کنترلی
دستور ORG :
org
دستورفوق كه مربوط به Assembler مي باشدبه شما امكان مي دهد،آدرس شروع برنامه در حافظه برنامهeeprom ميكروكنترلر راتعيين نماييد. مثال:
org 0h
اين دستور شروع برنامه در حافظه راازخانه صفرآن تعيين مي كند
دستورات محاسباتی:
این مجموعه دستورات شامل دستورات جمع و تفریق و کاهش و افزایش و ضرب و تقسیم 8 بیتی می باشند.
دستور :ADD
دستوراالعمل ADD برای جمع کردن یک مقدار 8 بیتی با ثبات A مورد استفاده قرار می گیرد. عملوند اول این دستور ثبات A می باشد این دستورالعمل در 4 مورد آدرس دهی (که قبلا بحث کردیم ) مورد استفاده قرار می گیرد.
دستور دیگری برای جمع وجود دارد با سمبل ADC که مخفف ADD whit carry می باشد و به معنی جمع با رقم نقلی است عملکرد آن بدین صورت است که ابتدا مقدار بیت C (نقلی) با ثبات A جمع شده و سپس عملوند دوم هم به ثبات A اضافه می شود . این دستور هم مانند دستور ADD در 4 مود آدرس دهی گفته شده مورد استفاده قرار می گیرد.
دستورالعمل تقسیم 8 بیتی:
DIV A
این دستورالعمل مقدار موجود در ثبات A را بر مقدار موجود در ثبات B تقسیم می کند . خارج قسمت در ثبات A و باقیمانده عمل تقسیم در ثبات B ذخیره خواهد شد.
فرض کنید که ثبات A حاوی مقدار 11 است و ثبات B حاوی مقدار 4 باشد پس از اجرای عمل تقسیم مقدار 2 در ثبات A و مقدار 3 در ثبات B ذخیره خواهد شد.
دستورالعمل افزایش(:(INC
یک دستورالعمل تک عملوندی است این دستور عملوند خود را یک واحد افزایش می دهد . نکته ای که در مورد این دستورالمل باید به آن توجه کرد اینست که هیچ پرچمی بعد از اجرای دستور تغییر نخواهد کرد برای مثال اگر ثبات A حاوی مقدار #0ffh باشد بعد از اجرای این دستور مقدار A , 00 خواهد شد اما پرچم OVER FLOW تغییر نخواهد کرد.
این دستورالعمل در سه مورد آدرس دهی ثبات . مستقیم و غیر مستقیم عمل می کند.
دستورالعمل کاهش(:(DEC
یک دستورالعمل تک عملوندی است . پس از اجرای این دستور از محتوای عملوند یک واحد کم می شود.به عنوان مثال اگر ثبات A حاوی مقدار 10 باشد پس از اجرای DEC A ثبات A حاوی مقدار 9 خواهد بود.
دستورالعمل ضرب(:(MULL
MULL AB
این دستور محتوای ثبات A را در ثبات B ضرب می کند نتیجه ضرب بدین گونه ذخیره می شود بیت پایین حاصلضرب در ثبات A و بیت بالای حاصلضرب در ثبات B ذخیره می شود.
دستورالعمل تفریق(:(SUBB
دستور SUBB برای تفریق یک مقدار 8 بیتی از ثبات A مورد استفاده قرار می گیرد این دستور مخفف Sub with BARROW است و عملوند دوم را به اضافه Carry از ثبات A کم می کند اگر در جریان تفریق از بیت هشتم نیاز به رقم قرضی باشد Carry یک می شود و در غیر این صورت صفر می شود .
دستورالعمل منطقی:
این دستورالعمل ها بر روی تک تک بیت ها اعمال منطقی AND,OR,XOR را انجام می دهند . دستورات چرخش و شیفت بیتی هم در زمره این دستورات هستند.
در AND کردن نتیجه دو بیت زمانی یک است که هر دو بیت یک باشند . در OR کردن دو بیت نتیجه دو بیت زمانی صفر است که هر دو بیت صفر باشند. در XOR کردن نتیجه هنگامی صفر است که هر دو بیت یا صفر باشند یا یک.
XOR برای مکمل کردن بیت ها هم به کار می رود نتیجه XOR یک بیت با بیت 1 مکمل آن خواهد بودو نتیجه xor یک بیت با بیت 0 خود آن بیت را نتیجه خواهد داد . این دستورات برای مکمل کردن بیت های مشخصی از یک بایت حافظه که بیت آدرس پذیر نیستند مفید است.
دستور اسمبلی که برای AND کردن مورد استفاده قرار می گیرد ANL (And Logic) است.
دستورات OR کردن و XOR کردن هم ساختاری مانند دستور ANL داند فقط برای OR از ORL و برای XOR از XRL استفاده می کنیم.
دستور دیگری هم با نام CPL وجود دارد که کارش مکمل کردن عملوند خود است.
دستورات چرخشی:
چهار دستور RR A,RL A,RLC A,RRC A برای عملیات چرخشی مورد استفاده قرار می گیرد.
RLA بیت های ثبات A را یک واحد به طرف چپ چرخش می دهد بیت شماره هفت از ثبات خارج می سود و دوباره وارد بیت شماره صفر می شود اگر ثبات A حاوی #10000001 b باشد:
10000001--------------> 00000011
RR L ثبات را یک واحد به راست چرخش می دهد در دستورات چرخش بیتی که خارج می شود از طرف دیگر وارد ثبات می شود
10000001-------------------> 11000000
RLC A, RRC A هم مشابه دستورات بالا هستند با این تفاوت که بیتی که از یک طرف خارج می شود وارد بیت Carry می شود و محتوای قبلی Carry از طرف دیگر وارد ثبات می گردد.
دستورات انتقال اطلاعات:
دستورات انتقال داده به دو دسته RAM خارجی و دستورهای RAM داخلی تقسیم می شوند .
MOV
اين دستور براي كپي كردن يك خانه از حافظه يا داده ها در بايت ها ي حافظه استفاده مي شود.توجه كنيدكه اين دستوريك دستوربايتي است.
مثال1:
mov p1,#55h
اين دستور مقدارعددي 55 درمبناي شانزده رادر بايتي از حافظه به نام p1مي ريزد.
mov p1,#85d
اين دستور مقدارعددي 85 درمبناي ده رادر بايتي از حافظه به نام p1مي ريزد.
mov p1,#010100011b
اين دستور مقدارعددي 01010011 درمبناي دو را در بايتي از حافظه به نام p1 مي ريزد.
توجه :همانطوركه در دستور ات بالامشاهده نموديدعلامت# قبل ازهركدام ازاعداد قيد شده بود.اين علامت براي مشخص نمودن اين مفهوم است كه مقدارعددي عبارت بعدي مي بايست دربايت معرفي شده از حافظه ريخته شود.
مثال2:
mov p1,55h
اين دستور محتويات داخل بايت 55h حافظه رادرخانه مي ريزد.دقت كنيدكه تمام ثبات هاي موجود را مي توان به جاي اين بايت استفاده كرد.
مثال3:
mov a,p1
mov a,p2
درمثال بالا اگربخواهيم اطلاعات روي p1 راروي p2 بريزيم ابتدا بايد ديتا را به آكومولاتورانتقال دهيم وسپس از اكومولاتور به p2انتقال دهيم.
عبارتb,d,hكه بعد از مقدارهاي عددي قيد شده آمده است مبين مبناي عدد مي باشد.
B=Binary
D=Decimal
H=Hexadecimal
دستورات 16 بیتی انتقال اطلاعات:
دستورات انتقال اطلاعات 16 بیتی برای مقدار اولیه دادن به اشاره گر داده((DPTR به صورت زیر است:
MOV DPTR,#DATA16
ثبات اشاره گر داده برای دسترسی به حافظه داده خارجی یا جداول حافظه به کار برده می شود مثال:
MOV DPTR,#1234H
این دستور عدد 1234H را به ثبات اشاره گر داده بار می کند.
دستور :XCH
فرم کلی این دستور به صورت زیر است:
XCH A,آدرس منبع
که باعث می شود تا محتوای ثبات آکومولاتور A با خانه ای که آدرس آن داده شده , جابجا شود. به عنوان مثال :
XCH A,20H
محتوای خانه حافظه 20H را با محتوای آکومولاتور A , جابجا می کند.
دستور حافظه داده خارجی :RAM
دستورات انتقال اطلاعات که داده را با حافظه خارجی مبادله می کند مانند MOVX از آدرس دهی غیر مستقیم استفاده می کند.
آدرس دهی غیر مستقیم:
* یا یک بایت آدرس از طریق @R0 (Ri که برابر R0 یا R1 است) استفاده می کند.
* و یا دو بایت آدرس اشاره گر داده را به صورت @DPTR به کار می برد.
مثال:
دستوراتی بنویسید که محتوای خانه های حافظه به آدرس های 10F4H , 10F5H را بخواند و آن ها را به ترتیب در ثباتهای R6,R7 قرار دهد.
حل: دستورات مذکور مطابق زیر می باشند:
MOV DPTR,#10F4H دستور (1)
دستور (2) MOV A,@DPTR
MOV R6,A دستور (3)
INC DPTR دستور (4)
MOVX A,@DPTR دستور (5)
MOV R7,A دستور (6)
دستور 1 : آدرس 16 بیتی 10F4H را در ثبات اشاره گر قرار می دهد.
دستور 2: محتوای خانه حافظه ای که با اشاره گر داده نشان داده شده یعنی محتئای خانه حافظه 10F4H را می خواند و در آکومولاتور A قرار می دهد.
دستور 3: محتوای آکومولاتور A را در ثبات R6 قرار می دهد به این ترتیب اولین خواسته مسئله انجام شده است.
دستور 4: به ثبات اشاره گر داده یک واحد اضافه می کند یعنی اشاره گر داده برابر 10F5H می شود.
دستور 5: محتوای خانه حافظه ای که با اشاره گر داده نشان داده شده را می خواند و در ثبات آکومولاتور A قرار می دهد.
دستور 6: محتوای آکومولاتور A را در ثبات R7 قرار می دهد یعنی خواست دوم مسئله انجام می پذیرد.
نکته: فقط با دستور MOVX می توان به حافظه داده خارجی RAM دسترسی داشت در این صورت یکی از عملوندها حتما آکومولاتور می باشد.
EQU
اين دستورمربوط به اسمبلر بوده وجهت نامگذاري قسمتي از حافظه داخلي ميكرو كنترلر استفاده مي شود
مثال4: برنامه زير خانه 20از حافظه رابه memory نامگذاري مي كند.
Memory equ 20h
ايجاد حلقه در برنامه نويسي ميكروكنترلر :
دستورات کنترل برنامه:
اين دستور براي پرش به مكاني از برنامه استفاده مي شود كه اين مكان يك برچسب است كه قبلاً نامگذاري شده است.دقت كنيدكه براي پرش هاي كوتاه مي توان ازدستور sjmpوبراي پرش هاي بلنداز دستور ljmp استفاده كرد.
مثال5:
loop:
.
.
.
jmp loop
دستور فوق به مكاني از برنامه به نام loopپرش مي كند.
loop:jmp loop
اين خط برنامه باعث مي شود cpu دريك حلقه گيركند.البته مي توان به جاي برنامه فوق ازدستورjmp$ نيز استفاده كرد.
end
اين دستور مربوط به اسمبلر است كه نشان دهنده پايان برنامه وخروج ازآن است.لازم به ذكراست اين دستور مي بايست هميشه آخرين خط برنامه باشد.
نكته:شمابايد به گونه اي برنامه نويسي نماييدكه هيچگاه برنامه به دستور end نرسد.
نمونه برنامه(1):
باتركيب دستورات فوق شما مي توانيد يك برنامه ساده بنويسيد:
org 0
mov p1,#55h
loop:jmp loop
end
باپروگرام نمودن ic وقراردادن آن برروي بردآموزشي اين برنامه باعث مي شودكه ledهاي روي برد به صورت يك درميان روشن شوند.چرا؟
حال به تحليل برنامه ونحوه كار آن مي پردازيم:
اولين دستور كه نمايانگر خانه شروع برنامه است.همانطوركه درمباحث ميكرو كنترلر 89c51 مطالعه نموده ايد،p1 دقيقاً يك بايت از حافظه ram ميكروكنترلر مي باشد كه به ازاي هربيت خوديك پايهi/o برروي ميكروكنترلر دارد (پايه يك تاهشت).حال اگرهر بيت ازاين حافظه يك شودشما روي پايه نظيرآن +5vو چنانچه صفر شود شماروي پايه نظير هر بيت مقدارصفريا gnd خواهيدداشت و بالعكس.
حال عدد55h رابه باينري تبديل نماييد ودربيت هاي نظير حافظه قراردهيد.
55H=010101010B
دقيقاً به ازاي عددباينري بالا پايه هاي ميكرو فعال مي شوند.
نكته :البته توجه نماييد ledهاي روي بردآموزشي به صورت آندمشترك بسته شده اند در نتيجه Active Lowهستند،پس به ازاي هرصفرledروشن مي شود.
دستورات پرش های شرطی:
میکروکنترولر دارای تعدادی دستورات پرش شرطی است که عبارتند از JZ , JNZ , DJNZ , CJNE
دستور :JZ
JZ آدرس مقصد یا برچسب دستور
این دستور یعنی اگر محتوای آکومولاتور A برابر 0 است به آدرس مقصد پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JNZ
JNZ آدرس مقصد یا برچسب دستور
یعنی اگر محتوای آکومولاتور A برابر 0 نباشد به آدرس مقصد پرش می کند در غیر این صورت دستور بعدی اجرا می گردد.
دستور :CJNE
این دستور برای عملیات حلقه به کار می رود و فرم کلی آن به صورت زیر است:
CJNE اپراند 1 , آدرس نسبی. اپراند 2
این دستور اپراند 1 را با اپراند 2 مقایسه می کند اگر مساوی نباشد به آدرس نسبی مقصد پرش می کند در غیر این صورت دستور بعدی اجرا می شود.
ايجادتأخيرزماني درروند فعاليت ميكرو به وسيله حلقه ها:
DJNZ COUNT,LOOP
اين دستور مقدارعددي خانه اي از حافظه راكه قبلاً توسط دستورEQUبه نام countتعريف شده است رايك واحد كاهش مي دهدواگرمقدارآن خانه صفرنبودبه آدرسي از خانه حافظه به نام loopپرش مي كند
درمثال زير بايت ها ايجاد يك تأخير زماني دو مقدار مختلف رابرروي پورت يك بايت ها فاصله زماني مشخص رامي توانيم روي اسكوپ ببينيم.
نمونه برنامه(2):
count equ 30h
org 00h
main:
mov count ,#200
mov p1,#01010101b
loop:djnz count,loop
mov p1,#10101010b
mov count,#250
loop1:djnz count,loop
jmp main
برنامه فوق يك بار پورت يك رابا55h فعال كرده وبعداز 400µs پورت يك را با aah بارگذاري مي كندوبعداز501µs دوباره پورت رابا 55hبارگذاري مي كند وهمين كارادامه خواهدداشت.شايدازخود بپرسيدچگونه متوجه مي شويم مقدارپورتها ، بعد از گذشت چه زماني عوض مي شوند؟
خيلي ساده است انجام هر دستور djnzدو سيكل ماشين زمان نيازداردودرحلقه اول ما200باراين دستور رااجرانموديم پس درمجموع400µsودرحلقه بعدي چون قبل ازآن يك دستورmov وجودداردومي دانيم براي انجام اين دستور نيز يك سيكل ماشين زمان نياز داريم درمجموع1+250*2سيكل ماشين تأخير ايجادشده است.
نكته:طبق استانداردي كه براي سخت افزار ميكرو قرارداده شده است ازنوسان ساز 12MHz استفاده مي كنيم ودرنتيجه هر سيكل ماشين يك ميكروثانيه زمان نيازدارد.
شما مي توانيد براي تست بصري اين تغييرات ازدستگاه اسكوپ استفاده نماييد.زيرابه علت سرعت زيادledها تغييرات آن براي ماشين ملموس نيست .
z= 10* y
براي تنظيم زمان بيشتر مي توانيدازچندحلقه متداخل استفاده نماييدكه بايك مثال درزيرنشان داده شده است.
x=loop1=2*255
y= 255 * x
y=loop2=255*x
x=2*255
z=loop3=10*y
درنتيجه
z=10*(255*(2*255))=1300500
پس باتشكيل حلقله هاي روبرو تقريباً3/1ثانيه تأخير ايجادنموديم.
البته توجه نماييدماازمقدارتأخير مربوط به خودdjnzدرحلقه دوم وسوم صرف نظر كرديم زيرا درمقابل عددبدست آمده مقدارناچيزي است.وماازآن چشم پوشي مي كنيم.
نمونه برنامه (3):
برنامه اي بنويسيدكه ledهاي متصل به پورت يك ،دربردآموزشي راباسرعت حدودي يك تادوثانيه خاموش وروشن كند.
count1 equ 20h
count2 equ 21h
count3 equ 22h
main:
mov p1,#0ffh
اين دستور باعث مي شود تمام ledهاي متصل به روي پورت p1خاموش شوند
(چون اين ledهابه صورت آند مشترك بسته شده اند.)
call delay
حدوديك ثانيه تأخير
mov p1,#oh
روشن كردن ledها
call delay
يك ثانيه تأخير
jmp main
پرش به ابتداي main
delay:
mov count2,#255
mov count3,#10
loop3:
mov count2,#255
loop2:
mov count1,#255
loop1:djnz count1,loop1
djnz count2,loop2
djnz count3,loop3
ret
end
دستور call:
در برنامه فوق چون زيرروال delay تكرارشده بودماازتكرارآن خودداري كرديم واز دستورcall استفاده كرديم ودرهنگام انجام اين دستور براي زيربرنامه cpu,delay به ابتداي برنامه delayرفته وآن رااجرامي كند تابه دستور ret برسد.پس از انجام كامل اين مرحله ورسيدن به دستور retاززير برنامه delay, برگشته وقفه كارخود را بعد از دستور callادامه مي دهد.شما با روش هاي مشابه مي توانيد به صورت تقريبي تأخيرمورد نظرخودرا دركنترلرها اعمال نماييد، ولي براي ايجاد تأخيرهاي دقيق تر در اجراي برنامه مي توانيد از timerها (كه درادامه به بحث درمورد آنها مي پردازيم) استفاده كنيد.
استفاده دستورات بيتي در ميكروكنترلر :
همان طور كه ملاحظه نموديد8051 دستوراتي جهت كارروي بايت هاي حافظه دارد. توجه داشته باشيد شماتوسط دستورات بايتي نمي توانيدروي يك خانه ازبيت حافظه كار كنيد.جهت كاربابيت هامي توانيد از دستورات بيتي زير استفاده نماييد.
setb
يك بيت را يك كرده
setb p1.0
بيت صفر از بايت p1 رايك كرده وتأثيري روي بقيه بيت ها ندارد.
P1
X
X
X
X
X
X
X
1
D7
D6
D5
D4
D3
D2
D1
D0
clr
يك بيت راصفر كرده
clr p0,5
بيت پنجم ازبايت p0راصفركرده وتأثيري روي بقيه بيت هاندارد.
P0
X
X
X
0
X
X
X
X
D7
D6
D5
D4
D3
D2
D1
D0
jnb
پرش درصورت يك نبودن
jnb P1.2,loop
اين دستور بيت دوم بايت p1رابررسي مي كند،اگراين پايه ازبيرون gndشده بود به loop پرش كرده ودرغيراينصورت برنامه از خط بعدي ادامه خواهديافت.بيشترين كاربرد اين دو دستور براي چك كردن كليد است كه درادامه يك مثال براي روشن شدن موضوع آورده شده است.
jb
پرش درصورت يك بودن
jb P1.2,loop
اين دستور بيت دوم بايت p1رابررسي مي كند،اگراين بیت یک باشد به loop پرش كرده ودرغيراينصورت برنامه از خط بعدي ادامه خواهديافت .
دستور :JBC
Jbc BIT , آدرس مقصد یا برچسب دستور
یعنی اگر بیت ( (BITمورد نظر برابر 1 است آن را 0 کن و به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JC
Jc آدرس مقصد یا برچسب دستور
یعنی اگر بیت نقلی ( (Cمورد نظر برابر 1 است به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
دستور :JNC
Jnc آدرس مقصد یا برچسب دستور
یعنی اگر بیت نقلی ( (Cمورد نظر برابر 1 نیست به آدرس مقصد یا برچسب دستور پرش کن در غیر این صورت دستور بعدی را اجرا کن.
نمونه برنامه (4):
برنامه اي بنويسيد كه بازدن كليدp3.3 عدد 55h روي p1 قراربگيردوبازدن كليدp3.5 عدد aah روي p1 قراربگيرد.
org 00h
scan:
jnb p3.3,num1
jnb p3.5,num2
jmp scan
num1:
mov p1,#55h
jmp scan
num2:
mov p1,#0aah
jmp scan
end
+ نوشته شده در ۱۳۸۵/۰۷/۰۱ ساعت توسط مجتبی حداد
|