آموزش ميكرو كنترلر ۸۰۵۱

قبل از همه چيز چرا ۸۰۵۱ ؟
ميكرولنترلر ۸۰۵۱ پايه و اساسي است براي يادگيري ديگر ميكروكنترلر ها دستورات اسمبلي اين ميكرو نسبت به AVR خيلي كمتر هست و داراي امكانات كمتري نسبت به ديگر ميكرو ها است به همين دليل يادگيري و فهم آن خيلي راحت و آسان مي باشد كه براي شروع ابتدا بايد مفاهيم منطق و ديجيتال را خوب فهميده باشيد و بعد از آن بايد سخت افرار ۸۰۵۱ و RAM

و ROM داخلي آن را درك كرده باشيد تا بتوانيد يك برنامه كاربردي بنويسيد تا يك پروسه را كنترل كند. خيلي ها براي يادگيري ميگن كه ما كه مي خواهيم برنامه نويسي ميكرو را ياد بگيرم پس بهتر بالاترين ميكرو يعني AVR يا PIC ياد بگيريم در صورتي كه به نظر من كاملا اشتاه بوده و كار غلطي است كه اگه بخواهيد تا آخر ادامه دهيد كاري طاقت فرسا خواهد بود. مثل اين خواهد بود كه سقف طبقه اول يك ساختمان را درست نكرده باشيم و بخواهيم طبقه دوم را درست

كنيم. در اين وبلاگ من تا بتوانم به زبان ساده و روان مطالب را بيان خواهم كرد كه البته اگه يكم علاقه و پشتكار داشته باشد مطمئن باشيد به ميكرو مسلط خواهيد شد و مي توانيد آن را به راحتي برنامه ريزي كنيد. قيمت اين ميكرو خيلي ارزان مي باشد در حدود ۱۰۰۰ تومان و حافظه ROM آن قابل پاك كردن و استفاده مجدد مي باشد پس شما به راحتي مي توانيد در خانه يا محل كار براي راحتي خود و افراد خانواده چيزهايي با آن بسازيد كه آدم باورش نشه كه اينو خودش ساخته و طراحي كرده.

تشريح پايه هاي ۸۰۵۱ و RAM و ROM داخلي آن
۸۰۵۱ داراي ۴ پورت ورودي يا خروجي مي باشد يعني اينكه هر كدام از اين پورت ها را مي توان در يك لحظه به عنوان ورودي استفاده كرد و همان پورت را دوباره در يك لحظه ديگر به عنوان خروجي از آن استفاده كرد. منظور از پورت چيست؟ پورت در ميكرو يعني ۸ عدد پين يا ۸ خط ديتا يا ذر اصطلاح ۸بيتي، كه ۸۰۵۱ داراي ۴ پورت ۸ بتي يعني ۳۲ پايه مي باشد.
ميكرو كنترلر AT89C51 داراي ۱۲۸ بايت RAM و ۴KB حافظه برنامه ROM مي باشد. و AT89C52 داراي ۲۵۶ بايت RAM و ۸KB حافظه برنامه ROM مي باشد. و AT89C55 داراي ۲۵۶ بايت RAM و ۲۰KB حافظه برنامه ROM مي باشد. كه بستگي به حجم برنامه ما دارد كه از كدام ميكرو استفاده كنيم.
كاربرد RAM چست؟ اصلا به چه دردي مي خوره؟
RAM يعني random access memory حافظه با دستيابي تصادفي. از اين حافظه براي ذخيره اطلاعات موقت استفاده مي شود يعني اينكه تا زماني كه تغذيه ميكرو وصل باش

د اين اطلاعات از بين نمي روند و با قطع كردن تغذيه اين اطلاعات از بين مي روند. ما در ميكرو ۸ ثبات ۸ بتي براي ذخيره كردن داده ها داريم در بعضي از مواقع پيش مي آيد كه اين ۸ ثبات در كل برنامه استفاده شوند و ما به يك ثبات ۸ بيتي براي ذخيره سازي داده ها داريم مثلا يك شمارنده طراحي كرديم و همه ثبات ها هم استفاده شده و ما مثلا به دو ثبات احتياج دار

يم كه مي توانيم از هر كدام از خانه هاي RAM استفاده كنيم. منظور از اطلاعات همان داده هاي ۸ بيتي مي باشند يعني همون ۰ يا ۱ ها كه به ۸ تا از آنها يك بايت يا يك داده ۸ بيتي مي گويند.
حال به تقسيم بندي RAM توجه كنيد. براي برنامه نويسي خيلي مهم است كه ما از چه خانه هاي RAM مجاز هستيم استفاده كنيم آيا مي توانيم در فلان خانه RAM داده را به صورت بيتي دستكاري كنيم يا داده را ۸ بيتي دستكاري كنيم. اصلا در چه محدوده اي از RAM قادر هستيم داده ذخيره كنيم يا بانك هاي ثباتي در كجاي RAM واقع شده اند و ديگر ثبات ها… به جدول زير كه مربوط به RAM خوب توجه كنيد:
عملكرد ثبات خانه هاي ۸ بتي RAM آدرس
FF
ثبات B B F0 F1 F2 F3 F4 F5 F6 F7 F0
ثبات A يا انباره ACC E0 E1 E2 E3 E4 E5 E6 E7 E0
كلمه وضعيت PSW D0 D1 D2 D3 D4 D5 D6 D7 D0
IP B8 B9 BA BB BC — — — B8
پورت ۳ P3 B0 B1 B2 B3 B4 B5 B6 B7 B0
كنترل وقفه ها IE A8 A9 AA AB AC — — AF A8
پورت ۲ P2 A0 A1 A2 A3 A4 A5 A6 A7 A0
ارتباط سريال SBUF قابل آدرس دهي نيست ۹۹
SCON 98 99 9A 9B 9C 9D 9E 9F 98
پورت ۱ P1 90 91 92 93 94 95 96 97 90
بايت سنگين تايمر ۱ TH1 قابل آدرس دهي نيست ۸D
بايت سنگين تايمر ۰ TH0 قابل آدرس دهي نيست ۸C
بايت سبك تايمر ۱ TL1 قابل آدرس دهي نيست ۸B
بايت سبك تايمر ۰ TL0 قابل آدرس دهي نيست ۸A
مد تايمر TMOD قابل آدرس دهي نيست ۸۹
مد شمارنده TCON 88 89 8A 8B 8C 8D 8E 8F 88
PCON قابل آدرس دهي نيست ۸۷
بايت سنگين ثبات DPTR DPH قابل آدرس دهي نيست ۸۳
بايت سبك ثبات DPTR DPL قابل آدرس دهي نيست ۸۲

اشاره گر پشته SP قابل آدرس دهي نيست ۸۱
پورت ۰ P0 80 81 82 83 84 85 86 87 80
فقط بايتي ۸۰ بايت براي خواندن و نوشتن موقت ۳۰تا۷F
بيتي و بايتي ۱۶ بايت براي خواندن و نوشتن موقت ۲۰تا۲F

 

بانك هاي ثباتي شامل R0-R7 R0-R7 بانك ۳ ۱۸تا۱F
R0-R7 بانك ۲ ۱۰تا۱۷
R0-R7 بانك ۱ ۰۸تا۰F
R0-R7 بانك ۰ ۰۰تا۰۷
MGH MGH MGH MGH

۸۰۵۱ در كل ۱۲۸ بايت RAM دارد كه به صورت جدول بالا تقسيم بندي مي شود:
۱) ۳۲ بايت از مكان هاي ۰۰ تا ۱F براي بانك هاي ثباتي و پشته كنار گذاشته شده.
۲) ۱۶ بايت از ۲۰ تا۲F براي خواندن و نوشتن آدرس پذير بيتي كنار گذاشته شده.
۳) ۸۰ بايت از مكان هاي ۳۰ تا۷F براي خواندن و نوشتن بايتي و يا آنچه كه عموما داده موقت گفته مي شو به كار مي رود.
نكته: جلوي خانه هايي كه نوشته شده قابل آدرس دهي نيست يعني اينكه نمي توان با آدرس هگز آن از اين ثبات استفاده كرده به عنوان مثال براي SBUF در برنامه نويسي حتما بايد خود SBUF را نوشت يعني از آدرس هگز آن نمي توان استفاده كرد. ولي در بقه موارد مجاز هستيم. با يك مثال اين قضيه را روشن مي كنيم:
MOV A,#60H يعني عدد ۶۰ در مبناي هگز را در انباره كپي كن. حال اين دستور را اين طوري هم مي توان نوشت يعني از آدرس A استفاده كرد. MOV E0,#60H
در RAM /8051 ما چهار بانك ثباتي داريم كه هر بانك داري ۸ بايت(R0تاR7) 8بيتي مي باشد يعني:
بانك صفر
R7 D0 D1 D2 D3 D4 D5 D6 D7
R6 D0 D1 D2 D3 D4 D5 D6 D7
R5 D0 D1 D2 D3 D4 D5 D6 D7
R4 D0 D1 D2 D3 D4 D5 D6 D7
R3 D0 D1 D2 D3 D4 D5 D6 D7
R2 D0 D1 D2 D3 D4 D5 D6 D7
R1 D0 D1 D2 D3 D4 D5 D6 D7
R0 D0 D1 D2 D3 D4 D5 D6 D7

بقيه بانك ها نيز مانند جدول بانك صفر مي باشد از اين ثبات ها در برنامه نويسي خيلي زياد استفاده مي شودند.نحوي انتخاب بانك يا تغيير دادن آن به صورت زير مي باشد:
۸۰۵۱ هنگامي روشن مي شود بانك صفر به صورت پيش فرض براي بانك ثباتي خود انتخاب مي كند كه براي تغيير دادن آن مي توانيم به صورت زير عمل كنيم.
RS0(PSW.3) RS1(PSW.4)
0 0 بانك صفر

۱ ۰ بانك يك
۰ ۱ بانك دو
۱ ۱ بانك سه

به كمك دستورات بيتي مي توان اين بانك را تغيير داد به مثال زير توجه كنيد مي خواهيم بانك ۳ را به عنوان بانك ثباتي ميكرو تغيير دهيم؟
SETB PSW.4
SETB PSW.3
مي خواهيم بانك دو را انتخاب كنيم؟
SETB PSW.4
CLR PSW.3
پشته:
هنگامي كه ۸۰۵۱ روشن مي شود اشارگر پشته به صورت پيش فرض عدد ۰۷ را در خود دارد كه نهايت با عث انتخاب بانك ۱ براي پشته خود مي شود. SP=07H
براي تغيير پشته به مكان ديگري ازRAM يا بانك ديگري مي توان به كمك دستور زير پشته را تغيير داد: MOV SP,#XX كه XX آدرس آن مكان از RAM مي باشد.
حال كاربرد پشته چيست؟ پشته كاربرد زيادي دارد شايد ما زياد با آن سرو كار نداشته باشيم ولي CPU با آن خيلي كار دارد به عنوان مثال براي اجراي يك زير برنامه(برنامه فرعي) مثلا CALL LABEL پردازنده آدرس اين مكاني را كه در آن به اين دستور برخورد كرده، را در پشته خود ذخيره مي كند و بعد از اجراي پشته به كمك اين آدرس بر مي گردد تا ادامه برنامه اصلي را انجام دهد.
براي درج داده رد پشته از دستور PUSH استفاده مي كنيم و براي بازيافت داده از پشته از دستور POP استفاده مي كنيم. با هر بار درج در پشته اشارگز پشته يك واحد به آن اضافه مي شود. و با هر بار بازيافت از پشته اشارگر پشته يك واحد از آن كم مي شود.
ROM چيست؟
اين حافظه از دست ما خارج است يعني اينكه فقط توسط كامپيوتر مي توان برنامه اصلي را توي اين حافظه كپي كرد و ما بعدا توسط خود ميكرو نمي توانيم محتواي آن را تغيير دهيم بلكه فقط مي توانيم اطلاعات را اين حافظه به حافظه RAM انتقال داده و بعد از پردازش مي توان آنها را به خروجي فرستاد.
پايه RST(9) ريست
با فعال شدن اين پايه يعني يك شدن به مدت حداقل ۲ سيكل ماشين ميكرو ريست شده و به خانه ۰۰۰۰H پرش كرده و ار آنجا شروع به خواندن برنامه مي كند.
پايه EA
اگر اين پايه را يك كنيم ميكرو برنامه را از ROM داخلي خودش شروع به خواندن مي كند و اگر اين پايه را صفر كنيم ميكرو از ROM داخلي خودش هيچ اطلاعاتي نمي خواند و با برنامه ريزي كه شده از ROM بيروني شروع به خواندن اطلاعا

ت مي كند.
پايه PSE
اين پايه براي زماني است كه بخواهيم از RAM يا ROM بيروني استفاده كنيم كه بسته به شرايط يا صف مي شود يا يك.
پايه ALE
اگر از RAM يا ROM بيروني استفاده كنيم اين پايه پورت صفر را به عنوان خطوط آدرس معرفي مي كند.

دستور EQU و DB
البته اين دو دستور جزء قالب هاي دستوري ۸۰۵۱ نيست يعني اصلا ميكرو چنين دستوري را ندارد و اجرا هم نمي كند. اين دو دستور را فقط كامپايلر ها مي شناسد كه به رهنمون هم معرف هستند اينها براي راحتي كار و برنامه نويسي هستند.
EQU به كمك اين دستور مي توان يه متغير تهريف كنيم مثلا ما در يك پروژه داريم كه در آن يك كليد به نام OK وجود دارد ما مي خواهيم OK را روي بيت ۳ از پورت ۲ قرار دهيم يعني اينكه P2.3=OK براي راحتي كار در طول برنامه ممكن از اين كليد بخواهيم زياد استفاده كنيم به همين دليل اول برنامه اين بيت را به متغيير OK نسبت مي دهيم به روش زير:
OK EQU P2.3
…………………….
JB OK,LOOP
برنامه اينطور مي باشد كه P2.3 به OK اختصاص داده شده و در برنامه اصلي ما مي خواهيم كه هر گاه اين بيت يك شد به آدرس LOOP پرش كند. پس ما مي نويسيم اگر OK يك شده به LOOP پرش كن.
DB اگه با LCD سرو كار داشته باشيم براي نمايش پيغام ها روي LCD بايد كد اسكي آنها رو نوشت كه خيلي كار سخت و وقت گيري به همين دليل در برنامه پيغام خود را به صورت زير مي نويسيم:
ORG 600H
DB ‘WWW.MC8051.BLOGFA.COM’
ابتدا بايد مكان اين پيغام را مشخص كنيم مثلا من در خانه ۶۰۰ ROM اين عبارت را نوشته توجه شود كه هر كاراكتر ۸ بيت دارد و هر يك از آنها در خانه ۶۰۰و۶۰۱و۶۰۲و۶۰۳ تا…. قرار مي گيرد. قالب دستور به اين صورت مي باشد DB ‘ ‘ متن يا پيغام را بايد حتما بين اين دو علامت نوشت تا كامپايلر متوجه شود كه متن ما هميني هست كه توي اين دو تا علامت قرار دارد و بعد از اين علامت جزء پيغام ما نيست.
دستور MOV
اين دستور پر كاربرد ترين دستور در ميكرو مي باشد معني اين دستور هم كپي كردن هست و انتقال دادن به مثال هاي زير توجه كنيد!
MOV A,#80H عدد ۸۰ را در انباره كپي كن
MOV R1,#50H عدد۵۰ را در ثبات R1 كپي كن
MOV P1,A محتواي انباره روي پورت ۱ انتقال بده
مثال : برنامه يك چشمك زن بنويسيد با دو تا LED كه روي بيت هاي P1.1 , P1.2 وصل شده اند؟
ابتدا بيتهاي پورت يك را به صورت زير مي نويسيم و كد هگز آن را بدست مي آوريم توجه شود كه بايد حتما بعد از كد H بنويسيم.
P1 D0 D1 D2 D3 D4 D5 D6 D7
02 0 1 0 0 0 0 0 0

۰۴ ۰ ۰ ۱ ۰ ۰ ۰ ۰ ۰

عدد ۲ را روي پورت ۱ انتقال بدهSTART: MOV P1,#02H
يك تاخير ايجاد كن ACALL DELAY
عدد ۴ را روي پورت ۱ انتقال بده MOV
به اول برنامه بر گردد و مراحل را تكرار كن SJMP START
يك زير برنامه تاخيريDELAY:
نكته بجاي اينكه كد هگز را بدست‌ بياوريم مي توانيم از قاعد زير استفاده كنيم فقط توجه شود كه بايد از حرف B حتما استفاده كنيم.MGH
MOV P1,#00000010B , MOV P1,#00000100B
انواع مدهاي آدرس دهي
الف) آدرس دهي ثباتي
اين روش آدرس دهي به صورت ثباتي انجام مي گيرد يعني اينكه ثبات با ثبات كپي مي شوند.
محتواي يكي از ثبات هاي ۱ تا ۷ را در انباره كپي مي كندMOV A,R1…R7
محتواي R3 در خانه ۳۰ از RAM كپي مي شود MOV 30H,R3
ب) آدرس دهي مستقيم
يعني اينكه ثبات با ثبات يا خانه اي از RAM با خانه اي ديگر به طور مستقيم و بدون واسطه انجام مي گيرد.
محتواي R5 در R4 كپي مي شودMOV R4,R5
محتواي ثبات B در انباره كپي مي شودMOV A,B
محتواي خانه ۳۰ از RAM در ثبات R3 كپي مي شود MOV R3,30H
محتواي خانه ۳۰ از RAM در ثبات B كپي مي شود MOV B,30H
ج) آدرس دهي غيره مستقيم
همانطور از اسمش پيداست به صورت غير مستقيم ديتايي از يك نقطه به نقطه ديگر كپي مي شود.
محتواي خانه اي از RAM كه آدرس آن در ثبات R0 مي باشد را در انباره كپي كن MOV A,@R0
محتواي خانه اي از RAM كه آدرس آن در ثبات R1 مي باشد را در ثبات B كپي كن MOV B,@R1
محتواي خانه اي از RAM كه آدرس آن در ثبات R0 مي باشد را در خانه ۴۰Hاز RAM كپي كن MOV 40H,@R0
محتواي خانه اي از RAM كه آدرس آن در ثبات R1 مي باشد را در TL0 كپي كن MOV TL0,@R1
نكته: براي آدرس دهي غير مستقيم تنها مجاز هستيم از R0 و R1 استفاده كنيم.
از اين نوع آدرس دهي بيشتر در مواردي استفاده مي شود كه بخواهيم خانه هاي زيادي از RAM را بخوانيم يا در آن چيزي بنويسيم كه باعث كاهش بسيار زياد تعداد دستورات مي شود براي واضح تر شدن به اين نوع آدرس دهي به مثال زير توجه كنيد.
برنامه بنويسيد تا عدد ۵۰H را در ۲۰ خانه از RAM با آدرس شروع ۴۰H كپي نمايد؟
عدد ۲۰H را در R5 كپي كن MOV R5,#20H
عدد ۴۰H را در R0 كپي كن MOV R0,#40H
عدد ۵۰H را در آدرسي كه R0 دارد كپي كن START: MOV @R0,#50H
يك واحد به R0 اضافه كن INC R0

يك واحد از R5كم كن اگر صفر نشده به برچسپ START پرش كن DJNZ R5,START
برنامه به اين صورت كار مي كند كه ابتدا عدد ۲۰ كه معادل۱۴H مي باشد در R5 كپي مي شود كه بعنوان شمارنده بكار مي رود تا فقط ۲۰ خ

انه از RAM را اطلاعات در آن كپي كند. به ثبات R0 مقدار ۴۰H يعني اولين خانه اي كه بايد در آن اين اطلاعات كپي شود را قرار مي دهيم در خط بعدي عدد ۵۰H در آدرسي كه R0 دارد كپي مي شود يعني در خانه ۴۰H و در خط بعدي يك واحد به R0 اضافه مي شود تا در تكرار بعدي عدد ۵۰ در خانه ۴۱H كپي شود. در آخرين خط برنامه يك واحد از R5 كم مي شود تا به ۱۹ و ۱۸ و ۱۷و در نهايت به صفر برسد و عدد ۵۰ در ۲۰ خانه از RAM كپي شود.MGH
د) آدرس دهي فوري
هرگاه از علامت پوند (#) در پشت يك عدد استفاده كرديم آدرس دهي فوري مي شود يعني اينكه فورا عددي در ثبات و يا در خروجي انتقال مي يابد.
MOV A,#05H
MOV R1,#85H
MOV @R1,#60H
دستور MOVC A,@A+DPTR
از اين دستور بيشتر براي رفتن به خانه هاي از حافظه با آدرس بيشتر از FF كه ديگر دستورات قادر به انجام آن نخواهند بود استفاده مي شود. طرز كار اين دستور به اين گونه است كه چون DPTR يك ثبات ۱۶ بيتي مي باشد قادر است تا از ۰۰۰۰ تا FFFF را در خود ذخيره كند. پس محتواي DPTR با محتواي انباره جمع مي شود و تشكليل يك آدرس را مي دهند كه ميكرو به اين آدرس رفته و محتواي ۸ بيتي آن را در انباره كپي ميكند. اين دستور كاربرد هاي فراوني دارد از جمله در آوردن اطلاعات يا يك متن يا پيغام از حافظه ROM و نمايش بر روي LCD .عملكرد ان در آوردن اطلاعات مشابه قسمت ج) در مثال بالا مي باشد.MGH
آموزش ميكرو كنترلر ۸۰۵۱ قسمت اول (سخت افزار)
آموزش ميكرو كنترلر ۸۰۵۱ قسمت سوم (معرفي دستورات)
جمع و تفريق بي علامت )دستور (ADD

از اين دستور براي جمع دو داده ۸ بيتي استفاده مي شود. براي عمل جمع حتما بايد يكي از داده ها در انباره A باشد و ديگري مي تواند در يكي از ثباتها يا داده فوري باشد.
قالب دستور: ADD A,SOURCE
مثال عدد ۱۰H را با E5 جمع كنيد؟
ابتدا يك از اعداد را به طور دلخواه در انباره

ريخته و سپيس عدد ديگر را با انباره جمع مي كنيم
MOV A,#10H 10H
ADD A,#0E0H +E5H =F5H A=F5H
نكته: اگر بعد از علامت پوند # عددي در مبناي هگز باشد كه بايت سنگين آن يكي از حروفهاي A تا F باشد بايد حتما بين اين حروفها و # صفر قرار دهيم تا كامپايلر آن را يك عدد در مبناي هگز بشناسد نه يك حرف انگليسي.
بعد از عمليات جمع نتيجه حاصل جمع در خود انباره قرار مي گيرد.
جمع اعداد ۱۶ بتي دستور ADDC
از اين دستور براي جمع دو داه ۱۶ بيتي استفاده مي شود البته نه اينكه مستقيما داده ۱۶ بيتي را با هم جمع مي كند بلكه ما ابتدا بايد اين داده ۱۶ بتي را به داده ۸ بتي تجزيه كردن و با هم جمهع كنيم براي اين كار اگر با ۸ بيتي اول عدد اول را با ۸ بيت اول عدد دوم جمع كنيم اگر رقم نقلي توليد شود اين دستور به طور اتوماتيك اين رقم نقلي را با بايت دوم عدد اول و دوم جمع مي كند به مثال زير توجه كند!
مثال مي خواهيم عدد ۳CE7+3B8D را در مبناي هگز با هم جمع كنيم. براي جمع ابتدا پرچم كري را صفر مي كنيم چون ممكن است از قبل توسط برنامه اي ديگر يك شده باشد. سپس اين داده ۱۶ بيتي را به داده ۸ بيتي تجزيه مي كنيم. مي دانيم كه در ميكر همه چيز ۸بتي مي باشد پس از جمع دو داده ۱۶ بيتي مطمئنا يك داده ۱۶ بزرگتر توليد مي شود براي همين ما بايت سبك را در R1 قرار مي دهيم و بايت سنگين را در R2 قرار مي دهيم البته اين يك فرض دلخواه مي باشد شما مي توانيد اين داده را در هر ثباتي قرار دهيد و از حاصل اين جمه در جايي ديگر استفاده كنيد.
CLR C
MOV A,#0E7H
ADD A,#8DH
MOV R1,A
MOV A,#3CH
ADDC A,#3BH

MOV R2,A
اصول كار ADDC در اصل اين است كه دو عمل جمع را انجام مي دهد يعني اينكه ابتدا عدد ۳C را با عدد ۳B جمع كرده و نتيجه اين محاسبه را دوباره با مقدار كري يعني CY=1 جمع مي كند و نتيجه نهايي را در انباره قرار مي دهد.
۱
۳CE7
در اين مثال از جمع E7+8D يك رقم نقلي توليد مي شود كه در نتيجه پرچم كري برابر با ۱ خواهد شد كه نشانگر انشار رقم نقلي از بايت پايين به بايت بالا مي باشد كه در خط بعدي برنامه اين رقم نقلي با حاصل جمع بايت هاي سنگين نيز جمع خواهد شد.
دستور DA A
از اين دستور براي جمع BCD استفاده مي شود همانطور كه مي دانيم اعداد ما از ۰ تا ۹ مي باشد كه در ميكرو بعد از جمع ممكن است اين حاصل جمع BCD نباشد و براي ما قابل فهم نيست يعني اينكه قابل نمايش روي سون سگمنت يا LCD نيست كه براي حل اين مشكل از دستور DA A استفاده مي شود قابل ذكر است كه اين دستور تنها بعد از دستور جمع و با انباره مي تواند كار كند يعني اينكه قبل از DA A بايد از دستور جمع حتما استفاده شود. عددي كه قرار است براي BCD بودن تست شود اول بايد انباره قرار گيرد و سپس از اين دستور استفاده كنيم. اين دستور يك بايت را چك مي كند و در صورت لزوم به نيبل پايين عدد ۶ را اضافه مي كند تا اين BCD استاندارد شود و براي نيبل بالا عدد ۶ يعني ۶۰ را اضافه مي كند. به مثال هاي زير توجه كنيد!
۱۷H+28H=3FH=00111111B
عدد F يك عدد BCD نمي باشد همانطور كه مي دانيم حداكثر عدد يعني ۹ داراي كد ۱۰۰۱ مي باشد كه در نيبل پايين اين عدد ۱۱۱۱ مي باشد براي BCD كردن آن به صورت زير عمل مي كنيم. ابتدا عدد را در انباره قرار داده و سپس از دستور DA A استفاده مي كنيم دستور به طور خودكار عدد ۶ را به نيبل پايين اضافه مي كند.
MOV A,#17H 17
ADD A,#28H +28
DA A 3F+06=45H
براي نيبل بالا هم همين مراحل انجام مي گير البته همانطور گفتيم اين دستو خودكار است يعني اينكه اگر خود حاصل جمع BCD بود ديگر عدد ۶ را اضافه نمي كند.
تفريق اعداد بي علامت (SUB SUBB)
البته دستور تفريق دو نوع مي باشد يكي SUB و ديگري SUBB تفريق با قرض. در بسيار از ميكرو پروسسورها اين دو نوع دستور وجود دارد حال در۸۰۵۱ فقط SUBB وجود دارد براي تبديل SUBB به SUB كافي است كه قبل از اجراي اين دستور CY=0 گردد.

SUBB با CY=0
8051 و ديگر پردازنده هاي مدرن از روش متمم ۲ براي تفريق استفاده مي كنند.
براي مثال عدد ۳F-23 را انجام م دهيم:
CLR C CY=0
MOV A,#3FH A=3F
MOV R1,#23H R1=23

SUBB A,R1 A-R1 = 1C
اگر بعد از اجراي SUBB پرچم CY=1 گردد نتيجه عمليات منفي بوده و اگر CY=0 گردد نتيجه عمليات مثبت بوده. حال اگر نتيجه منفي بود CPU آن را به صورت متمم ۲ رها ميكند كه بايد خود برنامه نويس با استفاده از دستوات شرطي نتيجه را به كمك دستور CPL (يعني متمم كردن) و دستور INC (يك واحد اضافه كردن) تغيير دهد.
مثال عدد ۶E از ۴C كم شود و نتيجه تفريق در ثبات R1 قرا گيرد؟
در اين برنامه اگر نتيجه مثيت باشد كه MGH پرش مي كند و حاصل را د R1 قرار مي هد و اگر نتيجه منفي باشد ابتدا محتوا انباره متمم مي شود و سپس يك واحد به آن اضافه مي شود كه در نهايت نتيجه براير خواهد بود با -۲۲
پرچم كري برابر صفر گردد CLR C
عدد ۴C در انباه قرار گيرد MOV A,#4CH
عدد ۶E از انباره كم شود SUBB A,#6E
اگر پرچم كري صفر است به MGH پرش كن JNC MGH
محتواي انباره را متمم كن CPL A
يك واحد به انباره اضافه كن INC A
محتواي انباره را در R1 كپي كن MGH: MOV R1,A
SUBB با CY=1
از اين دستور براي تفريق اعداد ۱۶ بيتي استفاده مي شود كه از قرض عملوند پايين تر مراقبت مي كند. اگر CY=1 باشد بعد از اجراي دستور SUBB عدد ۱ از حاصل تفريق كم خواهد شد. به مثال زير توجه كنيد!
مي خواهيم عدد ۲۷۶۲-۱۲۹۶ را از هم كم كنيم؟ بايت سبك در R1و بايت سنگين در R2
كري برابر با صفر شود CLR C
عدد ۶۲ را در انباره بريز MOV A,#62H
عدد ۹۶ را از انباره كم كن كه از اين كم كردن پرچم كري ۱ خواهد شد SUBB A,#96H
نتيجه اين دو بايت را در R1 قرار بده MOV R1,A
عدد ۲۷ را در انباره كپي كن MOV A,#27H
عدد ۱۲ را از انباره كم كن و اين نتيجه را اگر CY=1 است از ۱ هم كم كن SUBB A,#12H
نتيجه را در R2 قرار بده MOV R2,A
توضيح برنامه: ما در اول برنامه پرچم كري را به كمك دس

تور CLR صفر كرديم حال براي تفريق اين عدد ۱۶ بتي را به دو عدد ۸ بتي تجزيه كرده و از هم كم مي كنيم از تفريق عدد ۹۶ از ۶۲ پرچم كري ما يك مي شود و اين نشان دهنده منفي بودن عمليات است و در تفريق دو بايت بعدي ميكرو دو بايت سنگين را از هم كم مي كند و سيپس نتيجه هر چه بود به پرچ كري نگاه مي كند مي بيتد كه CY=1 شده بود از قيل، پس اين نتيجه را از ۱ كم مي كند و نتيجه را در R2 قرار مي دهد.
قضيه اعدا مثبت و منفي در ديجيتال
در ديجيتال ما بيت آخر را به عنوان علامت مثبت و منف

ي اعدد استفاده مي كنيم به اين صورت كه اگر بيت آخر كه با رنگ قرمز نشان داده شده صفر بود نشانگر مثبت بودن عدد مي باشد و اگر يك بود يعني اينكه عدد منفي مي باشد پس ما تنها از ۷ بيت براي مقدار عدد مي توانيم استفاده كنيم. به محاسبه عدد زير توجه كنيد؟
۰ ۱ ۰ ۰ ۰ ۱ ۱ ۰ = ۶۲H
0 1 1 0 1 0 0 1 = -96H
در ميكرو CPU عمل جمع را جمع مي كند و عمل تفريق را هم جمع مي كند چون طراحي مدار تفريق گر در CPU مشكل است از همان جمع كننده استفاده كرده اند اما براي تفريق CPU مراحل زير را انجام مي دهد.
۱) ابتدا عدد منفي را متمم كرده (مكمل ۱)
۲) سپس يك واحد به آن اضافه مي نمايد (مكمل ۲)
CPU دو عدد بالا را براي تفريق به صورت زير انجام مي دهد:
با عدد ۶۲ كه خودش مثبت مي باشد كاري ندار و فقط روي عدد منفي به صورت زير كار مي كند.
۰ ۱ ۰ ۰ ۰ ۱ ۱ ۰ = ۶۲H ثابت مي ماند
۰ ۱ ۱ ۰ ۱ ۰ ۰ ۱ = -۹۶H معادل باينري اين عدد
۱ ۰ ۰ ۱ ۰ ۱ ۱ ۰ متمم كردن فقط عدد ۹۶
۱ + با عدد ۱ جمع مي شود
۰ ۱ ۰ ۱ ۰ ۱ ۱ ۰ = ۶AH نتيجه بعد از جمع با عدد ۱
۰ ۱ ۰ ۰ ۰ ۱ ۱ ۰ = ۶۲H
0 1 0 1 0 1 1 0 = 6AH حال اين نتيجه را با عدد ۶۲ جمع مي كنيم
۰ ۰ ۱ ۱ ۰ ۰ ۱ ۱ = CCH نتيجه نهايي پايان كار CPU
براي اينكه نتيجه را به دسيمال تبديل كه بفهميم نتيجه عمليات چند بوده به شكل زير عمل مي كنيم
۰ ۰ ۱ ۱ ۰ ۰ ۱ ۱ = CCH نتيجه نهايي را دوباره متمم مي كنيم
۱ ۱ ۰ ۰ ۱ ۱ ۰ ۱ البته در ابن مرحله بيت علامت را متمم نمي كنيم
۱ +
۰ ۰ ۱ ۰ ۱ ۱ ۰ ۱ = دسيمال عدد همرا با بيت علامت آن
۴ ۳ – = -۳۴H كه -۳۴H معادل -۵۲ دسيمال مي باشد

با توجه به جدول بالا كه به وضوحنشان داده ش

ده كه چطوري اعدا منفي از هم تفريق مي شود فهميديم كه اگر عدد ما علامت دار باشد در نتيجه ۷ بيت اول مقدار عدد مي شود و بيت آخر علامت عدد مي شود كه اين بيت آخر روي پرچم كري تاثير دارد يعني اينكه اگر اين بيت ۱ شود در اصل پرچم كري يك شده و وقتي كري ۱ شود CPU متوجه مي شود كه نتجه محاسبه منفي بود.