دوشنبه , ۳ تیر ۱۳۹۸
آخرین مطالب
LINK TABLES
خانه | میکروکنترلر | دوره آموزشی AVR | برنامه نویسی اسمبلی برای AVR(جلسه ۷)

برنامه نویسی اسمبلی برای AVR(جلسه ۷)

در این جلسه می‌خواهیم کمی در مورد مباحث پیشرفته در زبان اسمبلی AVR مانند ایجاد تاخیر زمانی،دستور تفریق، دستورات چرخش، دستورات منطقی، دستورات مقایسه و … صحبت کنیم. پس با این جلسه همراه باشید.

ایجاد تاخیر زمانی

در ایجاد تأخیر زمانی توسط زبان اسمبلی برای AVR  باید به فرکانس نوسانساز میکرو(داخلی یا خارجی) و همچنین چرخه های زمانی که برای اجرای یک دستور لازم است توجه کرد. چرخه های زمانی یا چرخه ماشین در AVR یک دوره تناوب نوسانگر  است.اکثر دستورات در AVR بیش از یک یا دو چرخه ماشین برای اجرا شدن نیاز ندارند.اگر ما فرکانس نوسانگر را بدانیم واز تعداد چرخه ماشین هر دستور اطلاع داشته باشیم میتوانیم برنامه هایی برای ایجاد تاخیر زمانی بنویسیم و یا زمانی را که یک برنامه برای اجرا شدن مصرف میکند محاسبه کنیم.

مثال: اگر فرکانس کریستال ۱۰ مگاهرتز باشد مقدار تاخیر کد زیر را بیابید:

جواب:[۱+((۱+۱+۱+۲)×۲۵۵)+۱]× µS127.7=µS۰٫۱

باید توجه داشته باشید که دستور BRNE در صورت پرش دو چرخه دستور زمان می برد و اگر از حلقه بیرون برود یک چرخه لازم دارد.یعنی جواب نهایی باید ۱۲۷٫۶ µS باشد.

می توان با ایجاد حلقه های تو در تو تاخیر های زمانی طولانی تری را ایجاد کرد.

دستورات محاسباتی و منطقی

در مورد دستور ADD قبلا توضیح دادم، فقط این مطلب را اضافه کنم که این دستور پرچم های وضعیت را تحت تاثیر قرار می دهد.توجه کنید که هیچ یک از دستورات پردازشی و منطقی نمی توانند به طور مستقیم عمیات پردازشی خود را برروی خانه های حافظه انجام دهند و حتما باید از ثبات های همه منظوره استفاده کنند.

دستور ADC:

از این دستور در جمع دو داده ۱۶ بیتی استفاده میشود.این دستور عملیات جمع را با رقم نقلی(C) انجام می دهد. به عنوان مثال در جمع دو عدد ۳CE7H و ۳B8DH به صورت زیر عمل می کنیم:

دستور تفریق

در avr پنج دستور برای تفریق داریم که عبارتند از SUB،SBC،SUBI،SBCI و SBIW.

دستور SUB: این دستور مقدار دو ثبات را از هم کم می کند.

دستور SBC

این دستور برای تفریق اعداد چند بایتی استفاده می شود و رقم قرضی بایت پایینی را در تفریق شرکت می دهد.

به عنوان مثال برای تفریق دو عدد ۲۷۶۲H و ۱۲۹۶H به این صورت عمل می کنیم:

دستور SUBI

این دستور یک مقدار بلافصل یا عددی را از یک ثبات کم میکنه.

دستور SBCI

 این دستور در تفریق یک مقدار بلافصل از یک ثبات، رقم قرضی را هم شرکت می دهد.

دستور SBIW

 این دستور یک مقدار بلافصل را از یک عدد یک کلمه ای، که در غالب دو ثبات است کم میکند.

نقش پرچم نقلی در تفریق

در AVR بعد از عملیات تفریق رقم نقلی توسط خود CPU معکوس می شود.برای تشخیص مثبت یا منفی بودن جواب باید پرچم C را بررسی کنیم.اگر بعد از عملیات تفریق C=1 باشد جواب منفی است و اگر  C=0باشد جواب مثبت است.

لازم به ذکر است که اعداد منفی در سیستم دودویی به صورت مکمل ۲ نمایش داده می شوند.برای اینکه یک عدد دودویی را مکمل ۲ کنیم ابتدا باید تک تک بیت های آن را معکوس کرده و بعد عدد بدست آمده را با یک جمع کنیم.دستور  NEGدر AVRهمه این مراحل را به صورت اتوماتیک انجام می دهد.

مثال: عدد ۰۰۰۰۰۰۱۱ که معادل ۳ دهدهی است یک عدد مثبت است.اگر بیت های آن را معکوس کنیم می شود ۱۱۱۱۱۱۰۰   می شود ۰Xfc هگز که متمم عدد ۳ است.حال اگر آن را با یک جمع کنیم می شود ۱۱۱۱۱۱۰۱   یا ۰xfd که مکمل دو عدد ۳ می باشد.این عدد فرم منفی عدد ۳ است.مثلا اگر ما بخواهیم عدد ۳ را از ۵ کم کنیم می توانیم فرم منفی عدد ۳ را با ۵ جمع کنیم.یعنی ۰۰۰۰۰۱۰۱+۱۱۱۱۱۱۰۱=۰x102.همانطور که می بینید جواب بزرگتر از یک ثبات است و رقم نقلی وجود دارد.مقداری که در ثبات نتیجه می ماند ۰x02  می باشد و چون avr رقم نقلی را معکوس می کند C=0 می شود.پس جواب نهایی +۲ است.در واقع پردازنده برای تفریق دو عملوند فرم مثبت عملوند اول را با فرم منفی عملوند دوم جمع کرده و بعد رقم نقلی را برای تعیین علامت معکوس می کند.

دستورات ضرب: عمل ضرب در AVR بایت به بایت است.دو ثبات همه منظوره به عنوان عملوند در دستور ضرب شرکت می کنند و جواب نهایی که یک جواب ۱۶ بیتی است در R1(بایت بالایی جواب) و R0(بایت پایینی جواب) قرار می گیرد.

دستورات ضرب در AVR عبارتند از:

عملیات ضرب کاربرد بایت اول بایت دوم بایت بالایی جواب بایت پایینی جواب
MUL  Rd,Rr اعداد بدون علامت Rd Rr R1 R0
MULS  Rd,Rr اعداد علامت دار Rd Rr R1 R0
MULSU  Rd,Rr اعداد بدون علامت با اعداد علامت دار Rd Rr R1 R0

مثال:

درAVR دستور مستقلی برای تقسیم وجود ندارد.عملیات تقسیم را باید شبیه سازی کنیم.ما می توانیم با تفریق مکرر مقسوم علیه از مقسوم تا زمانی که جواب تفریقات از مقسوم علیه کوچکتر شود این کار را انجام دهیم.در اینجا تعداد دفعات تفریق به عنوان خارج قسمت و عددی که در تقسیمات از مقسوم علیه کوچکتر شد به عنوان باقیمانده در نظر گرفته می شود.

مثال: در این مثال مقدار ثبات R16 بر عدد ۱۰ تقسیم می شود.ثبات R18 تعداد دفعات تفریق را تا زمانی که مقدار R16 از ۱۰ کمتر شود می شمارد.دستور CPI مقدار R16 را با ۱۰ مقایسه کرده و پرچمهای وضعیت را برای تصمیم گیریهای شرطی تحت تاثیر قرار می دهد.دستور CLR ثبات R18 را پاک می کند.

چه زمانی پرچم V یک می شود

اگر در عملیات اعداد علامت دار مقدار جواب از گنجایش ثبات بیشتر شود پرچم V یک می شود.در مثالی که در بالا برای تفریق دو عدد ۵و۳ گفته شد به خاطر اینکه ۰x02 از هر دو عملوند کوچکتر است V=0 است.سرریز زمانی رخ می دهد که قدرمطلق جواب قبل از اجرای دستور از عملوندها بزرگتر باشد.مثلا اگر دو عدد +۷۰(۰۱۱۰۰۰۰۰) و +۹۶ (۰۱۰۰۰۱۱۰)را باهم جمع کنیم جواب +۱۶۶( ۱۰۱۰۰۱۱۰) می شود.همانطور که میبینید از دیدگاه باینری این یک عدد منفی است(۹۰-)٫چون پرارزشترین بیت آن یک است(N=1).در حالی که دو عدد مثبت با هم جمع شده اند.یعنی جواب باید (۰۱۰۱۰۰۱۱۰) بشود ولی چون در  یک ثبات ۸ بیتی جا نمی شود V=1 می شود تا این حالت را به اطلاع برنامه نویس برساند.در این حالتها پرچم S علامت واقعی جواب را به ما نشان می دهد.اگر پرچم S  با مقدار D7 جواب برابر باشد یعنی سرریزی اتفاق نیفتاده و جواب درست است ولی اگر V=1 باشد پرچم S معکوس D7 را نشان خواهد داد. CPU فقط صفر و یک می شناسد.این برنامه نویس است که باید قواعد محاسبات اعداد علامت دار و بدون علامت را مد نظر بگیرد.پرچمها در این کار به برنامه نویس کمک می کنند.

دستورات منطقی

دستورات منطقی عبارتند از:AND,ANDI,OR,ORI,COM,NEG,EOR

این دستورات در جدول زیر به طور خلاصه آمده اند.K یک عدد ثابت است.

فرمت دستور توضیحات مثال
AND  Rd,Rr عملیات AND را بر روی محتویات ثباتهای Rd  و Rr  انجام داده و نتیجه را در Rd دخیره می کند. LDI  R23,0x0          ;R23=0x0 LDI  R24,0xFF        ;R24=0Xff AND  R24,R23       ;R24=0
ANDI  Rd,K عملیات AND را بر روی محتویات ثبات Rd  و عدد ثابت K  انجام داده و نتیجه را در Rd دخیره می کند. LDI  R24,0xFF        ;R24=0Xff ANDI  R24,0x00    ;R24=0
OR  Rd,Rr عملیات OR را بر روی محتویات ثباتهای Rd  و Rr  انجام داده و نتیجه را در Rd دخیره می کند. LDI  R23,0x0          ;R23=0x0 LDI  R24,0xFF        ;R24=0Xff OR  R24,R23          ;R24=0xFF
ORI  Rd,Rr عملیات OR را بر روی محتویات ثبات Rd و عدد ثابت K  انجام داده و نتیجه را در Rd دخیره می کند. LDI  R24,0xFF        ;R24=0Xff ORI  R24,0x00       ;R24=0
EOR  Rd,Rr عملیات EOR را بر روی محتویات ثباتهای Rd  و Rr  انجام داده و نتیجه را در Rd دخیره می کند.

LDI  R23,0x0          ;R23=0x0

LDI  R24,0xFF        ;R24=0Xff

EOR  R24,R23       ;R24=0xFF

در مورد دو دستور NEG و COM قبلا توضیح داده شده است.

دستورات مقایسه

دستورات مقایسه عبارتند از:( CPI,CPSE(Compare, Skip if Equal),CP,CPC(Compare With Carry

در جدول زیر K یک عدد ثابت یا بلافصل است.

فرمت دستور توضیحات
CP  Rd,Rr دراین دستور محتویات ثباتهای Rd و Rr مقایسه می شود
CPSE  Rd,Rr دراین دستور محتویات ثباتهای Rd و Rr مقایسه می شود و اگر مساوی بودند کنترلر به دستور دوم بعد از این دستور پرش می کند
CPC  Rd,Rr دراین دستور محتویات ثباتهای Rd و Rr با تاثیر پذیری بیت کری مقایسه می شود
CPI  Rd,K دراین دستور محتویات ثبات Rd و و عدد ثابتK مقایسه می شود.

در واقع دستورات مقایسه عملیات تفریق را بر روی عملوند های خود انجام می دهند اما نتیجه تفریق در هیچ کدام از عملوندها ذخیره نمی شود و مقدار ثبات ها تغییری نمی کند.با اجرای دستورات مقایسه پرچمهای وضعیت تغییر می کنند و ما می توانیم بر اساس وضعیت آنها و با استفاده از دستورات شرطی پرچم های وضعیت تصمیم گیری های لازم را در برنامه انجام دهیم.

مثال: در مثال زیر اگر مقدار R23 با R24 مساوی نباشد کنترلر به برچسب HERE0 پرش می کند.در غیر این صورت در حلقه HERE  برای همیشه می ماند.

مثال بالا را به این صورت نیز می توان نوشت:

دستورات چرخش

 دو دستور چرخش در AVR وجود دارد که در هردوی آنها رقم نقلی هم دخیل است. یعنی رقم نقلی مانند جزئی از ثبات عمل کرده و به ثبات همه منظوره یک ثبات ۹ بیتی را تشکیل می دهد.از دستورات چرخشی می توان برای سریال کردن داده ها استفاده کرد.

این دو دستور عبارتند از ROR و ROL.

فرمت دستور توضیحات مثال
ROR  Rd با هر بار اجرای این دستور کم ارزشترین بیت ثبات Rd وارد رقم نقلی میشود و مقدار رقم نقلی وارد پرارزشترین بیت ثبات همه منظوره می شود LDI   R25,0x04 (CLC  ;C=0(Clear Carry ROR  R25  ;R25=0x02
ROL  Rl با هر بار اجرای این دستور پر ارزشترین بیت ثبات Rd وارد رقم نقلی میشود و مقدار رقم نقلی وارد کم ارزشترین بیت ثبات همه منظوره می شود LDI   R25,0x04 (CLC  ;C=0(Clear Carry ROL  R25  ;R25=0x08

Slide1

     ROL

Slide1      ROR

این دستورات عبارتند از:LSL,LSR,ASR

فرمت دستور توضیحات مثال
LSL  Rd این دستور محتویات یک ثبات همه منظوره را یک واحد به چپ شیفت می دهد و همزمان عدد صفر وارد کم ارزشترین بیت و پر ارزشترین بیت وارد رقم نقلی می شود. LDI  R25,0x04  ;R25=4 CLC LSL  R25   ;R25=8
LSR  Rd این دستور محتویات یک ثبات همه منظوره را یک واحد به راست شیفت می دهد و همزمان عدد صفر از پر ارزشترین بیت وارد و کم ارزشترین بیت وارد رقم نقلی می شود. LDI  R25,0x04  ;R25=4 CLC LSR  R25   ;R25=82
ASR  Rd به این دستور شیفت ریاضی می گویند.با اجرای این دستور ضمن جابه جایی بیت ها به اندازه یک بیت به سمت راست مقدار پرارزشترین بیت ثابت می ماند LDI  R25,0x80  ;R25=0x80 CLC ASR  R25   ;R25=0xC0 ASR  R25   ;R25=0xE0 ASR  R25   ;R25=0xF0 ASR  R25   ;R25=0XF8

در دستورات چرخشی اگر مقدار C=0 باشد با هرباراجرای دستور LSL مقدار ثبات در ۲ ضرب می شود و با هر بار اجرای دستور LSR مقدار ثبات بر ۲ تقسیم می شود.

دستور SWAP

 عملوند های این دستور تمام ثبات های همه منظوره می توانند باشند.این دستور نیبل بالا با پایین یک ثبات همه منظوره را عوض می کند.یعنی ۴ بیت پایینتر بر روی ۴ بیت بالاتر و ۴ بیت بالاتر بر روی ۴ بیت پایینتر قرار می گیرد.

فرمت این دستور به این شکل است:  SWAP  Rd

مثال:

Slide1

درباره ی احسان عبداللهی

احسان عبداللهی هستم | کارشناسی الکترونیک خوندم و کارشناسی ارشد مخابرات |در سال 94 وب سایت میکرولرن را راه اندازی کردم | سعی کردم هر چیزی را به صورت کاربردی دنبال کنم، برای همین از کارشناسی کار با میکروکنترلرهای AVR و ARM، برنامه نویسی C و طراحی PCB را به صورت تخصصی کار کردم و از کارشناسی ارشد برنامه نویسی پایتون ، Computer vision و deep learning را به صورت تخصصی و کاربردی شروع کردم | الان هم سعی میکنم همیشه خودم را به روز نگه دارم و لذت کار کردن با دنیای برنامه نویسی و امبدد سیستم ها را به دیگران انتقال بدم

۱۰ دیدگاه

  1. لطفا لینک دانلود avr studio یا atmel stdio برام بفرسید.
    با تشکر

  2. سلام

    منظورت از چه سطحی میخوای کار کنی رو متوجه نمیشم اما میخوام از AVR در کار های صنعتی استفاده کنم. زبان C رو هم یاد میگیرم.

    ۱-میشه وقتی AVR تو مدار قرار داره بدون اینکه اون از مدار خارج شه , روی اون برنامه نوشت؟

    ۲- این جمله رو معنی کن: ;R4+R2+carry, adding the upper byte whit carry from lower byte

    تو این دو عدد بیت کم ارزش H کجا رفت؟

    • جواب اینکه تو چه سطحی میخوای کار کنی رو خودت دادی. گفتی کارهای صنعتی. منظور منم همین بود که قراره در حد دانشگاه و نمره باشه یا واسه صنعت میخوای. خب ببین غیر از کتاب مزیدی که معماری رو قوی گفته، کتاب پرتویی فر + کتاب جابر الوندی از نظر پروژه و راه انداختن به نظرم خوب کار کردن. وقتی این دو تا کتاب رو خوب یاد گرفتی بیا یک سری کتابای قوی تر بهت معرفی میکنم که کاملا پروژه محور هستن.
      ۱- آره چنین کاری رو میشه انجام داد که بهش میگن boot loader. یعنی مثلا میشه avr رو با پورت سریال به کامپیوتر وصل کرد و طبق یه برنامه ی از پیش نوشته شده داخل کامپیوتری کدهایی برای avr ارسال بشه تا برنامه ی اون تغییر کنه که البته باید خیلی دقیق باش کار کنی وگرنه ممکنه مشکل پیش بیاد.
      ۲-این جمله داره میگه که بایت های با ارزش بالاتر و بیت نقلی باهم جمع می شوند. (بیت نقلی هم از حاصل جمع بایت های با ارزش کمتر ایجاد میشه)
      منظور از H عدد نیست چون اعداد هگزادسیمال از ۰ تا F هستند. H نشون دهنده هگزا دسیمال بودنشه.

  3. سلام

    ۱-در مثال دستور ADC دو عدد ۳CE7H و ۳B8DH چه جوری جمع شدن؟ منظورم اینه عدد ها رو چه طوری تفکیک کردین و اینکه H در تفکیک وجود نداره.

    ۲- کتاب که برا ی شروع اموزش AVR که به من کمک کنه معرفی کن. و یه کتاب هم در مورد زبان اسمبلی

    • سلام ایمان عزیز
      ببین این مثال واسه آموزش بوده فقط، ابتدا بایت های با ارزش کمتر را جمع کردیم(جمع معمولی با دستور ADD) سپس بایت های باارزش بالاتر را جمع کردیم. اما این جمع معمولی نیست بلکه ADC است چون ممکنه حاصل جمع بایت های کم ارزش در یک بایت جا نشه و رقم نقلی تولید کنه پس باید این رقم نقلی در جمع بایت های با ارزش بالاتر اثر بگذاره. در عمل هم هروقت چنین اعداد دو بایتی داشتی به همین شکل جمعشون کن اما دو تا دستور هم یادت میدم به نام های low و high که این دستورات به ترتیب بایت کم ارزش و پرارزش یک مقدار ۱۶ بیتی را برات استخراج می کنن. از این هم میشه استفاده کرد.
      در رابطه با سوال دومی که مطرح کردی من ازت یک سوال دارم؟ میخوای AVR را در چه سطحی کار کنی؟ آیا زبا C هم میخوای یاد بگیری؟
      برای آموزش اسمبلی در AVR بهترین کتابی که وجود داره کتاب دکتر مزیدی هست که ترجمه هم شده توسط خانم آناهیتا نعیمی. کلا از لحاظ معماری بسیار قوی کار کرده ولی از لحاظ کاربردی یکم لنگ میزنه و نیاز به کتاب های پروژه محور داری. حالا جواب سوالیو که پرسیدم بده تا بهت چند تا کتاب دیگه هم معرفی کنم.

  4. برای تولید تاخیر زمانی در زبان سی هم آیا میشه از این روش استفاده کرد؟

    • بله می تونید چنین کاری کنید. باید از asm# و endasm# برای قرار دادن کد اسمبلی خودتون استفاده کنید. فقط دقت کنید که ابتدا رجیسترهای مورد استفاده ی خودتون را با push کنید تا بعد از تاخیر زمانی مقادیر اون ها از دست نره.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *