مقدمه
یکی از کارهایی که در برنامه نویسی انجام میشود اتصال چند متغیر به یکدیگر و ایجاد یک متغیر بزرگتر است، مثلا در برخی از ماژولها یک عدد 4 بایتی به صورت 4 بایت مجزا دریافت میشود و باید 4 عدد 8 بیتی را با ضرب و جمع به یک عدد 32 بیتی تبدیل کرد، همچنین عکس این قضیه نیز صادق است و گاهی اوقات لازم است که مثلا یک متغیر 16 بیتی به دو متغیر 8 بیتی شکسته شود. این کار مستلزم نوشتن کد زیادی بوده و در صورت استفاده از توابع نیز حجم و زمان زیادی را از میکرو میگیرد.
کلیدواژه Overlay
در کامپایلر بسکام (Bascom) یک روش بسیار ساده، کاربردی و سریع وجود دارد که میتوان برای تبدیل متغیرها به بکدیگر از آن استفاده کرد. در این روش باید هنگام تعریف متغیرها ابتدا متغیر با بیت بیشتر را تعریف کرد سپس مطابق نمونه کد زیر متغیرهای کوچک را روی همان آدرس متغیر بزرگتر تعریف نمود. در این روش در واقع متغیرهای کوچکتر روی متغیر بزرگتر همپوشانی میشوند. در این حالت هر گاه متغیر بزرگ مقدار دهی شود میتوان به بخشهای مختلف آن با متغیرهای کوچکتر دسترسی پیدا کرد و برعکس.
سورس
در سورس کد زیر متغیر L از نوع 32 بیتی (Long) است و در زیر آن 4 متغیر 8 بیتی (از نوع Byte) به نام B1 الی B4 در Overlay صفر تا سه ِ متغیر L تعریف شدهاند، در واقع B1 روی همان آدرس شروع متغیر L تعریف شده و 8 بیت کم ارزشتر را همپوشانی میکند، B1 یک واحد جلوتر (منظور از یک واحد یعنی به اندازه سایز خودش که 8 بیت است) و همینطور B3 و B4 روی بخشهای بعدی L تعریف شدهاند. (در بسکام متغیرها از آدرس کوچکتر حافظه SRAM و آدرسهای ابتدایی بصورت بایت به بایت و به ترتیب از بایت کم ارزشتر به پرارزشتر تعریف میشوند) در خط بعدی L با یک عدد دلخواه مقدار دهی شده است، ما برای خوانایی بیشتر از عدد باینری استفاده کردهایم، توجه داشته باشید که در بسکام هنگام تعریف اعداد باینری برای جلوگیری از اشتباه میتوان بین اعداد به هر تعداد دلخواه آندرلاین قرار داد و این علامت توسط کامپایلر نادیده گرفته میشود. (این قضیه هیچ ارتباطی با کلیدواژه Overlay نداشته و کلی است). در بخش بعدی هم متغیر L و هم چهار متغیر B1 تا B4 روی شبیه ساز چاپ شدهاند تا نتیجه بررسی شود.
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 |
'Overlay Test By Behnam Zakizadeh @ 1403/06/29 'AVR64.com $regfile = "m8adef.dat" $crystal = 4000000 $hwstack = 40 $swstack = 16 $framesize = 32 $sim Dim L As Long Dim B1 As Byte At L + 0 Overlay Dim B2 As Byte At L + 1 Overlay Dim B3 As Byte At L + 2 Overlay Dim B4 As Byte At L + 3 Overlay L = &B11111111_00000000_11110000_10101010 Print Bin(l) Print Bin(b1) Print Bin(b2) Print Bin(b3) Print Bin(b4) End |
خروجی شبیهساز
در تصویر زیر خروجی شبیه ساز بسکام را میبینید. در این تصویر در بخش آبی UART0 خروجی دستورهای Print مشاهده میشود. ابتدا متغیر L چاپ شده است. در خطوط بعدی نیز مقدار B1 الی B4 پرینت شده که متناظر با بایتهای کم ارزشتر الی پرارزشتر متغیر L میباشد. در سمت راست یک تصویر از حافظه SRAM میکرو مشاهده میشود که نحوه نشستن متغیر L و متغیرهای B1 تا B4 را در این قسمت با خطوط رنگی مشخص کردهایم.
در آردوینو و زبان C
در آردوینو و زبان C هم چنین روشی وجود دارد. در زبان C باید از نوع داده union استفاده کنیم، union شبیه struct است با این تفاوت که در struct تمام دادههای داخل آن به طور مجزا تعریف میشوند ولی در union تمام دادهها روی یکدیگر تعریف میگردند، در واقع هر داده مثل یک نام دوم برای همان آدرس حافظه است. در قطعه کد زیر یک متغیر از نوع union به نام packed_long ایجاد شده که داخل آن یک متغیر به نام L از نوع long تعریف شده و یک آرایه چهار بایتی به نام b. دقیقا مثل بسکام این دو متغیر روی همدیگر همپوشانی دارند و با مقدار دهی هر کدام، دیگری نیز مقدار دهی میشود.
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 |
union packed_long { long l; byte b[4]; }; packed_long mydata; void setup() { // put your setup code here, to run once: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } Serial.println("salam"); mydata.l = 0b11111111000000001111000010101010; Serial.println(mydata.l,BIN); for(int i=0; i<=3; i++){ Serial.println(mydata.b[i],BIN); } } void loop() { // put your main code here, to run repeatedly: } |
خروجی ترمینال:
1 2 3 4 5 6 |
salam 11111111000000001111000010101010 10101010 11110000 0 11111111 |
نتیجهگیری
از این مقاله نتیجه میگیریم که برای اتصال و شکستن متغیرها در بسکام مثلا تبدیل دو Byte به Integer یا چهار بایت به Long و یا شکستن Long به 4 بایت یا Integer به دو بایت براحتی میتوان از کلمه کلیدی Overlay هنگام تعریف متغیرها استفاده کرد و در حجم و زمان میکروکنترلر صرفه جویی نمود.
بازدیدها: 2