بررسی عملکرد داخلی CPU، حافظه، GPIO و واحدهای جانبی در محیطهای شبیهسازی
بخش دوم: از اجرای دستور ماشین تا کنترل پایههای واقعی مجازی
مقدمه
در بخش اول مقاله بررسی کردیم که نرمافزارهایی مانند Proteus، Wokwi و سایر ابزارهای شبیهسازی مدار چگونه قطعات الکترونیکی را با استفاده از مدلهای ریاضی بازسازی میکنند.
دیدیم که یک مقاومت، دیود یا ترانزیستور در یک شبیهساز فقط یک تصویر گرافیکی نیست، بلکه دارای یک مدل نرمافزاری است که رفتار الکتریکی آن را تعریف میکند.
اما زمانی که صحبت از میکروکنترلرها میشود، موضوع بسیار پیچیدهتر خواهد شد.
یک مقاومت فقط یک رابطه بین ولتاژ و جریان دارد، اما یک میکروکنترلر مانند ESP32 یا STM32 یک سیستم کامل کامپیوتری در ابعاد بسیار کوچک است.
یک میکروکنترلر شامل بخشهای مختلفی مانند:
- پردازنده مرکزی (CPU)
- حافظه Flash
- حافظه RAM
- رجیسترها
- تایمرها
- واحدهای ارتباطی
- مبدل آنالوگ به دیجیتال (ADC)
- واحد PWM
- کنترلر وقفهها
- پایههای ورودی و خروجی (GPIO)
است.
بنابراین برای شبیهسازی آن، نرمافزار باید تقریباً یک کامپیوتر کوچک را داخل خودش بازسازی کند.
به همین دلیل شبیهسازی میکروکنترلرها بیشتر شبیه ساخت یک کامپیوتر مجازی است تا صرفاً شبیهسازی یک قطعه الکترونیکی.
تفاوت شبیهسازی یک مقاومت با یک میکروکنترلر
برای درک بهتر موضوع، دو مثال را مقایسه کنیم.
مقاومت
یک مقاومت:
- ورودی دارد: ولتاژ
- خروجی دارد: جریان
مدل آن بسیار ساده است.
میکروکنترلر
اما یک ESP32 باید بتواند:
- برنامه را از حافظه بخواند
- دستورها را اجرا کند
- اطلاعات را در RAM ذخیره کند
- وقفه دریافت کند
- تایمرها را مدیریت کند
- پایهها را تغییر دهد
- اطلاعات را از سنسورها دریافت کند
- ارتباط سریال برقرار کند
یعنی نرمافزار شبیهساز باید رفتار میلیونها ترانزیستور داخل تراشه را به صورت مستقیم شبیهسازی نکند، بلکه یک مدل سطح بالاتر از عملکرد آن بسازد.
CPU Emulator چیست؟
مهمترین بخش شبیهسازی یک میکروکنترلر، امولاتور پردازنده یا CPU Emulator است.
پردازنده واقعی داخل میکروکنترلر مجموعهای از دستورهای ماشین را اجرا میکند.
برای مثال یک CPU ممکن است دستورهایی مانند:
LOAD
STORE
ADD
SUB
JUMP
COMPARE
CALL
RETURN
داشته باشد.
در سختافزار واقعی، این دستورها توسط مدارهای دیجیتال داخل CPU اجرا میشوند.
اما در شبیهساز، یک برنامه نرمافزاری همان رفتار را تقلید میکند.
به این صورت:
برنامه کاربر
↓
فایل HEX یا ELF
↓
CPU Emulator
↓
خواندن دستور ماشین
↓
تغییر رجیسترها
↓
تغییر وضعیت میکروکنترلر
چرخه اجرای دستور در میکروکنترلر
هر پردازنده یک چرخه مشخص برای اجرای دستورها دارد که معمولاً به آن:
Fetch – Decode – Execute
گفته میشود.
این چرخه در شبیهساز نیز بازسازی میشود.
مرحله اول: Fetch
پردازنده آدرس دستور بعدی را از Program Counter دریافت میکند.
مثلاً:
PC = 0x1000
یعنی دستور موجود در آدرس 1000 خوانده شود.
مرحله دوم: Decode
پردازنده بررسی میکند که این دستور چیست.
مثلاً:
ADD R1,R2
یعنی:
مقدار رجیستر R2 را با R1 جمع کن.
مرحله سوم: Execute
دستور اجرا میشود.
مثلاً:
قبل:
R1 = 5
R2 = 3
بعد:
R1 = 8
در یک میکروکنترلر واقعی این کار در چند سیکل کلاک انجام میشود.
در شبیهساز، همین اتفاق به صورت نرمافزاری محاسبه میشود.
حافظه Flash چگونه شبیهسازی میشود؟
وقتی یک برنامه برای میکروکنترلر کامپایل میکنیم، خروجی معمولاً یک فایل باینری است.
مثلاً:
program.hex
یا:
firmware.bin
این فایل شامل دستورهای ماشین است.
در محیط شبیهسازی:
این فایل به عنوان حافظه برنامه بارگذاری میشود.
ساختار:
Flash مجازی
آدرس 0:
دستور اول
آدرس 4:
دستور دوم
آدرس 8:
دستور سوم
CPU Emulator از همین حافظه دستورها را میخواند.
RAM در شبیهساز چگونه کار میکند؟
RAM محل ذخیره اطلاعات موقت برنامه است.
برای مثال:
int counter = 10;
در زمان اجرا این مقدار باید جایی ذخیره شود.
در شبیهسازی:
یک فضای حافظه مجازی ساخته میشود:
RAM
0x2000:
counter = 10
0x2004:
temperature = 25
هر بار که CPU مقدار یک متغیر را تغییر میدهد، مقدار موجود در RAM مجازی تغییر میکند.
رجیسترها؛ قلب کنترل میکروکنترلر
میکروکنترلرها برای کنترل سختافزار داخلی خود از رجیسترها استفاده میکنند.
برای مثال در بسیاری از میکروکنترلرها، پایههای GPIO توسط رجیستر کنترل میشوند.
فرض کنید:
GPIO_REGISTER = 00000000
یعنی تمام پایهها خاموش هستند.
اگر بیت شماره ۲ تغییر کند:
GPIO_REGISTER = 00000100
پایه شماره ۲ فعال میشود.
در شبیهساز:
وقتی برنامه مینویسد:
digitalWrite(2,HIGH);
در نهایت اتفاقی شبیه این رخ میدهد:
تغییر رجیستر GPIO
↓
تشخیص تغییر بیت
↓
تغییر وضعیت پایه مجازی
↓
ارسال سیگنال به قطعه متصل
GPIO چگونه در شبیهساز کار میکند؟
GPIO یا General Purpose Input Output یکی از مهمترین بخشهای هر میکروکنترلر است.
هر پایه میتواند:
- ورودی باشد
- خروجی باشد
- دیجیتال باشد
- دارای PWM باشد
- دارای عملکرد جایگزین باشد
برای مثال:
ESP32:
GPIO2
Input:
خواندن کلید
Output:
روشن کردن LED
در شبیهساز، هر پایه یک مدل نرمافزاری دارد:
مثلاً:
Pin Number:
2
Direction:
OUTPUT
Voltage:
3.3V
State:
HIGH
وقتی CPU مقدار آن را تغییر میدهد، موتور شبیهسازی این تغییر را به سیمهای مدار منتقل میکند.
ارتباط پایهها با قطعات دیگر
فرض کنید:
ESP32 GPIO2
↓
مقاومت 220 اهم
↓
LED
↓
GND
در شبیهساز:
وقتی GPIO2 برابر HIGH شود:
GPIO2 = 3.3V
↓
سیم دارای ولتاژ میشود
↓
مقاومت جریان را محدود میکند
↓
LED روشن میشود
یعنی همان زنجیرهای که در سختافزار واقعی رخ میدهد.
تایمرها چگونه شبیهسازی میشوند؟
تقریباً تمام میکروکنترلرها دارای تایمر هستند.
کاربرد تایمر:
- ایجاد تأخیر
- تولید PWM
- اندازهگیری زمان
- شمارش پالس
در سختافزار واقعی:
تایمر با کلاک داخلی کار میکند.
مثلاً:
Clock = 80MHz
یعنی:
۸۰ میلیون پالس در ثانیه.
در شبیهساز، یک ساعت مجازی ساخته میشود:
Virtual Clock
↓
Timer Counter
↓
Interrupt
وقفهها (Interrupt) در شبیهسازی
وقفه یکی از مهمترین قابلیتهای میکروکنترلر است.
مثلاً:
یک سنسور حرکتی به پایه وصل شده است.
وقتی حرکت تشخیص داده شود:
Sensor Signal
↓
Interrupt
↓
CPU توقف برنامه فعلی
↓
اجرای تابع مربوطه
در شبیهساز نیز همین مسیر بازسازی میشود.
UART چگونه شبیهسازی میشود؟
UART یکی از سادهترین روشهای ارتباطی است.
مثلاً:
ESP32 به کامپیوتر وصل شده است.
اطلاعات:
TX
↓
RX
ارسال میشوند.
مدل شبیهسازی باید موارد زیر را در نظر بگیرد:
- نرخ Baud Rate
- بیت شروع
- بیت توقف
- زمانبندی ارسال
SPI و I2C چگونه کار میکنند؟
ارتباطهای سریع مانند:
- SPI
- I2C
نیازمند مدلسازی دقیقتری هستند.
مثلاً در I2C:
Master
↓
SDA + SCL
↓
Slave
شبیهساز باید:
- وضعیت خطوط
- آدرسدهی
- زمانبندی
- پاسخ قطعه
را کنترل کند.
ADC چگونه شبیهسازی میشود؟
ADC وظیفه تبدیل ولتاژ آنالوگ به عدد دیجیتال را دارد.
مثلاً:
ورودی:
2.5V
خروجی:
2048
در شبیهساز:
یک مدل ریاضی وجود دارد:
Voltage
↓
ADC Model
↓
Digital Value
↓
CPU
PWM چگونه شبیهسازی میشود؟
PWM برای کنترل:
- سرعت موتور
- شدت نور LED
- توان خروجی
استفاده میشود.
مثلاً:
Duty Cycle:
50%
یعنی:
نیمی از زمان روشن و نیمی خاموش.
در شبیهساز، موج مربعی تولید میشود و قطعات متصل به آن واکنش نشان میدهند.
چرا شبیهسازی ESP32 سختتر از AVR است؟
میکروکنترلرهای ساده مانند AVR دارای:
- CPU ساده
- حافظه کم
- امکانات محدود
هستند.
اما ESP32 شامل:
- پردازنده قدرتمند
- WiFi
- Bluetooth
- RTOS
- چند هسته پردازشی
- واحدهای ارتباطی متعدد
است.
بنابراین شبیهسازی کامل آن بسیار پیچیدهتر است.
برای مثال شبیهسازی WiFi واقعی نیازمند مدلسازی:
- پروتکل شبکه
- زمانبندی ارتباط
- انتقال داده
است.
به همین دلیل بسیاری از شبیهسازها فقط بخشهایی از عملکرد ESP32 را مدل میکنند.
Proteus چگونه برنامه واقعی را اجرا میکند؟
زمانی که شما یک فایل HEX برای یک میکروکنترلر در Proteus قرار میدهید:
مراحل زیر رخ میدهد:
HEX File
↓
Load Into Virtual Flash
↓
CPU Emulator Start
↓
Execute Instructions
↓
Update Registers
↓
Update Pins
↓
Update Circuit
بنابراین برنامه شما واقعاً اجرا میشود، اما روی یک نسخه نرمافزاری از پردازنده.
محدودیتهای شبیهسازی میکروکنترلر
با وجود قدرت زیاد، شبیهسازها محدودیتهایی دارند.
برخی موارد که ممکن است دقیق نباشند:
- رفتار نویز الکتریکی
- دمای قطعه
- مشکلات تغذیه
- خطاهای فیزیکی PCB
- تأخیرهای واقعی سختافزار
بنابراین شبیهسازی جایگزین صددرصد تست واقعی نیست، بلکه ابزاری برای کاهش خطا و سرعت دادن به طراحی است.
جمعبندی بخش دوم
شبیهسازی یک میکروکنترلر بسیار فراتر از نمایش یک قطعه روی صفحه است.
نرمافزارهایی مانند Proteus و Wokwi باید یک سیستم کامل شامل:
- پردازنده
- حافظه
- رجیسترها
- کلاک
- ورودی و خروجی
- ارتباطات جانبی
را به صورت نرمافزاری بازسازی کنند.
زمانی که یک برنامه روی ESP32 مجازی اجرا میشود، در واقع یک CPU Emulator دستورهای ماشین را اجرا میکند، رجیسترها تغییر میکنند، پایههای GPIO وضعیت جدید میگیرند و این تغییرات به مدار اطراف منتقل میشوند.
در بخش سوم مقاله وارد عمیقترین قسمت خواهیم شد:
چگونه میتوان یک قطعه جدید برای شبیهساز ساخت؟ موتور داخلی Proteus و Wokwi چگونه طراحی شده است؟ و اگر بخواهیم یک شبیهساز مشابه Proteus بسازیم، چه معماری نرمافزاری نیاز داریم؟
