مقدمه:
بدون شک کامپایلر بسکام برای دوستداران زبان بیسیک محبوبیت بسیار زیادی داشته و برای نوشتن سریع کدها و برنامههای مختلف برای میکروکنترلر AVR فارغ از درگیر شدن با جزئیات رجیسترها بهترین گزینه به شمار میرود (البته نسخه قانونی آن). با این حال داشتن دانش قبلی در خصوص رجیسترها و نحوه عملکرد میکروکنترلر AVR از ضروریات است، لیکن Bascom زمان را میخرد؛ که مهمترین دارایی ماست.
تنها مشکل بسکام معماری بسته آن است که مشخص نیست دستورهای ساده را چگونه به کد تبدیل میکند. به طور مثال اخیراً برای یک پروژه نیاز به کار با مقدار زیادی دیتای EEPROM داشتیم، بسکام کار را براحتی با تعریف متغیر از نوع ERAM ساده میکند اما نکته مهم این بود که آیا طبق گفته برخی مقالات آموزشی باید بعد از دستورات نوشتن و خواندن بصورت دستی از تاخیر waitms 10 استفاده کنیم؟ آیا بسکام مراقب زمان لازم برای نوشتن در EEPROM هست یا نه؟ به طور مثال اگر نیاز به نوشتن 512 بایت EEPROM باشد و هرکدام نیاز به 10 میلی ثانیه تاخیر داشته باشد باید حدود 5 ثانیه برنامه را منتظر بگذاریم؟
مهندسی معکوس (تبدیل HEX به ASM با AVR Disassembler)
در چنین شرایطی تنها راه ممکن اینست که یک برنامه خیلی ساده در حد نوشتن یک عدد در متغیر Eram نوشته و آنرا به Hex تبدیل کنیم. سپس کد Hex را به کمک برنامه DISAVR که یک برنامه کوچک خط فرمان برای تبدیل فایل Hex به ASM است به کد اسمبلی تبدیل و آن را تحلیل کنیم. بدین منظور کد زیر را نوشتیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
'AVR64.com By Behnam Zakizadeh 2022 [1401/02/06] $regfile = "m8adef.dat" $crystal = 4000000 $hwstack = 64 $swstack = 64 $framesize = 64 Dim A As Eram Byte Dim B As Byte A = 6 'B = A End |
سپس کد hex را با نام ep.hex تولید کرده و به کمک برنامه دیس اسمبلر که می توانید آن را از آدرس زیر دریافت کنید:
https://www.avrfreaks.net/forum/disavr-win32-101-beta-released
یا از این لینک بگیرید:
و با تایپ دستور
disavr ep.hex > ep.asm
کد اسمبلی زیر را در خروجی تحویل گرفتیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
; Atmel Win32 AVR Disassembler v1.01 ; .cseg .org 0 rjmp avr0013 ; 0000 C012 reti ; 0001 9518 reti ; 0002 9518 reti ; 0003 9518 reti ; 0004 9518 reti ; 0005 9518 reti ; 0006 9518 reti ; 0007 9518 reti ; 0008 9518 reti ; 0009 9518 reti ; 000A 9518 reti ; 000B 9518 reti ; 000C 9518 reti ; 000D 9518 reti ; 000E 9518 reti ; 000F 9518 reti ; 0010 9518 reti ; 0011 9518 reti ; 0012 9518 avr0013: ldi r24, 0x5F ; 0013 E58F out SPL, r24 ; 0014 BF8D ldi YL, 0x20 ; 0015 E2C0 ldi ZL, 0xB8 ; 0016 EBE8 mov r4, ZL ; 0017 2E4E ldi r24, 0x04 ; 0018 E084 out SPH, r24 ; 0019 BF8E ldi YH, 0x04 ; 001A E0D4 ldi ZH, 0x03 ; 001B E0F3 mov r5, ZH ; 001C 2E5F wdr ; 001D 95A8 in r24, MCUCSR ; 001E B784 mov r0, r24 ; 001F 2E08 andi r24, 0xF7 ; 0020 7F87 out MCUCSR, r24 ; 0021 BF84 ldi r24, 0x18 ; 0022 E188 clr r25 ; 0023 2799 out WDTCR, r24 ; 0024 BD81 out WDTCR, r25 ; 0025 BD91 ldi ZL, 0xFE ; 0026 EFEE ldi ZH, 0x03 ; 0027 E0F3 ldi XL, 0x60 ; 0028 E6A0 ldi XH, 0x00 ; 0029 E0B0 clr r24 ; 002A 2788 avr002B: st X+, r24 ; 002B 938D sbiw ZL, 0x01 ; 002C 9731 brne avr002B ; 002D F7E9 clr r6 ; 002E 2466 ldi ZL, 0x00 ; 002F E0E0 ldi ZH, 0x00 ; 0030 E0F0 ldi XL, 0x10 ; 0031 E1A0 clr XH ; 0032 27BB ldi r24, 0x06 ; 0033 E086 st X, r24 ; 0034 938C ldi r23, 0x7B ; 0035 E77B rcall avr0048 ; 0036 D011 cli ; 0037 94F8 avr0038: rjmp $ ; 0038 CFFF avr0039: sbiw ZL, 0x01 ; 0039 9731 brne avr0039 ; 003A F7F1 ret ; 003B 9508 set ; 003C 9468 bld r6, 2 ; 003D F862 ret ; 003E 9508 clt ; 003F 94E8 bld r6, 2 ; 0040 F862 ret ; 0041 9508 avr0042: sbic EECR, 1 ; 0042 99E1 rjmp avr0042 ; 0043 CFFE out EEARL, ZL ; 0044 BBEE out EEARH, ZH ; 0045 BBFF adiw ZL, 0x01 ; 0046 9631 ret ; 0047 9508 avr0048: ldi r25, 0x01 ; 0048 E091 rjmp avr004B ; 0049 C001 ldi r25, 0x02 ; 004A E092 avr004B: cpi r23, 0x7B ; 004B 377B brne avr0057 ; 004C F451 in r23, SREG ; 004D B77F cli ; 004E 94F8 avr004F: rcall avr0042 ; 004F DFF2 ld r24, X+ ; 0050 918D out EEDR, r24 ; 0051 BB8D sbi EECR, 2 ; 0052 9AE2 sbi EECR, 1 ; 0053 9AE1 dec r25 ; 0054 959A brne avr004F ; 0055 F7C9 out SREG, r23 ; 0056 BF7F avr0057: clr r23 ; 0057 2777 ret ; 0058 9508 .exit |
همانطوریکه در برنامه اسمبلی در خط
avr0042: sbic EECR, 1 ; 0042 99E1
مشاهده می کنید بیت شماره یک یعنی بیت EEWE از رجیستر EECR بررسی شده و فقط در صورت 0 بودن دستورات بعدی را که عملیات خواندن یا نوشتن در EEPROM است انجام میدهد. بنابراین کد تولید شده توسط BASCOM در خصوص کار با متغیرهای EEPROM کاملا اصولی بوده و هیچ نیازی به استفاده از توابع ایجاد تاخیر مثل waitms 10 بعد از دستورات مقداردهی متغیرهای نوع EEPROM نمیباشد.
نتیجه گیری
در این مقاله آموختیم که چگونه خروجی بسته بسکام را به کد اسمبلی تبدیل کرده و آن را تحلیل کنیم. همچنین یادگرفتیم که براحتی و با اطمینان خاطر از متغیرهای Eram در برنامه استفاده کنیم. البته همیشه سعی کنید در ابتدای برنامه یک کپی از متغیرهای Eram در SRAM ذخیره کنید و برای جلوگیری از سربار اضافه و نیز خراب شدن EEPROM در متن برنامه با رم کار کنید. همچنین هرگز در حلقههای تکرار به دفعات در متغیرهای Eram ننویسید تا EEPROM را خراب نکنید چرا که EEPROM محدودیت تعداد دفعات نوشتن دارد.
بازدیدها: 846
سلام مهندس ممنون خیلی جالب بود
من بخاطر بی اعتمادی به ایپرام میکرو ای وی ار متاسفانه مجبورم از ایپرام خارجی استفاده کنم چون ایپرام داخلی میکرو بعد از مدتی باعث فرار دیتا ها میشه روی فیوز بیت ها هم کار کردم ولی راه حل مناسبی پیدا نکردم
سلام، خواهش میکنم. ما از EEPROM داخلی در تمام محصولات تجاریمون (Novinkit.com) استفاده میکنیم و تابحال مشکلی با پاک شدن دیتا نداشتیم. توجه داشته باشید که EEPROM داخلی به تغذیه حساس هست، بنابراین حتما فیوزبیت BODEN فعال و BODLEVEL روی ولتاژی مثل 2.7 تنظیم بشه که در صورت کم شدن ولتاژ، میکرو خاموش بشه. در غیر این صورت اگر موقع خاموش شدن میکرو در ولتاژهای پایین (مثلا هنگام تخلیه خازن تغذیه) میکرو در حال کار با EEPROM باشه ممکنه دیتا آسیب ببینه. همچنین در ورودی تغذیه میکرو حتما فیلتر پایینگذر شامل سلف 10 میکروهانری و خازن 100 نانو (مشابه فیلتر ADC) استفاده بشه تا نویزهای خارجی از راه تغذیه وارد میکرو نشن.
بدی کار بسکام اینجاست که موقع رایت ایپیرام وقفه سراسری غیرفعال میشه
و عملا زیر برنامه های دارای وقفه که زیر 5 میلی ثانیه رفرش داشته باشند نمیشه استفاده کرد چون عملا اجرا نمیشن و از دست میرن
راهکاری برای این مشکل ارایه کنید
سلام بیت EERIE در رجیستر EECR مسئول وقفه آمادگی EEPROM هست، شاید بسکام از وقفه آمادگی EEPROM استفاده میکند و آن را فعال میکند و به همین خاطر وقفه قبلی غیر فعال میشود. اگر بدون وقفه هم بتوان با EEPROM کار کرد میتوانید برای نوشتن در EEPROM یک تابع کوچک اسمبلی ایجاد کنید و آن را فراخوانی کنید و با روش pooling در یک حلقه، وضعیت EEWE را چک کنید و سپس در EEPROM بنویسید و در این حلقه وقفه قبلی میتواند به کار خودش ادامه دهد. نمونه کد اسمبلی در دیتاشیت هر نوع میکروکنترلر AVR زیر بخش مموری و EEPROM موجود است.
با سلام
لطفا در مورد برنامه disavr توضيح بفرماييد.
دانلودش كردم . فايل EXE رو نميشناسه در كامپيوتر من لطفا راهنمايي بفرماييد سپاس
سلام احتمالا روی فایل exe کلیک کردید. اینکار اشتباهه
باید پوشه دانلودی رو داخل root مثلا درایو C قرار بدید بعدش از منوی استارت CMD رو سرچ و باز کنید (خط فرمان) و دستور
disavr ep.hex > ep.asm
رو بزنید با فرض اینکه اسم فایل شما ep باشه
راه دوم ایجاد یک فایل متنی با پسوند run.bat در کنار فایل exe و تایپ دستور disavr ep.hex > ep.asm داخل اون هست.
بعدش فایل هگز رو به ep.hex تغییر نام داده و کنار exe و run.bat قرار بدید و در نهایت روی فایل bat کلیک کنید تا دستور داخلش اجرا بشه و فایل ep.asm در همون جا ایجاد بشه.
مهندس خیلیییی حالیته… خوشمان امد …..برکاننا…
درود بر شما دوست گرامی