بله، حتماً. برای شبیهسازی عملکرد یک DAC شبکه نردبانی R-2R، ما میتوانیم برنامهای بنویسیم که رفتار ریاضی این مدار را پیادهسازی کند.
در یک شبکه R-2R ایدهآل، ولتاژ خروجی حاصل جمع وزندار بیتهای ورودی است. فرمول کلی آن به صورت زیر است:
$$V_{out} = V_{ref} \times \frac{\text{DigitalValue}}{2^N}$$
که در آن:
- $V_{ref}$: ولتاژ مرجع (مثلاً ۵ ولت).
- $N$: رزولوشن یا تعداد بیتها (مثلاً ۸ بیت).
- $DigitalValue$: مقدار عددی باینری ورودی.
کد پایتون شبیهساز R-2R
این برنامه دو کار انجام میدهد:
- یک تابع تبدیل R-2R را تعریف میکند.
- یک موج رمپ (پلهای) تولید میکند تا ماهیت پلهای بودن خروجی آنالوگ را در نمودار نشان دهد.
Python
import numpy as np
import matplotlib.pyplot as plt
class R2R_DAC:
def __init__(self, resolution_bits, v_ref):
"""
مقداردهی اولیه شبیهساز DAC
:param resolution_bits: تعداد بیتهای DAC (مثلاً 4، 8، 10)
:param v_ref: ولتاژ مرجع مدار (مثلاً 5 ولت)
"""
self.n = resolution_bits
self.v_ref = v_ref
self.max_val = 2 ** resolution_bits
def digital_to_analog(self, digital_input):
"""
تبدیل یک عدد دیجیتال به ولتاژ آنالوگ بر اساس فرمول R-2R
"""
if digital_input >= self.max_val:
digital_input = self.max_val - 1
if digital_input < 0:
digital_input = 0
# فرمول اصلی شبکه نردبانی R-2R
# V_out = V_ref * (Digital_Value / 2^N)
analog_voltage = self.v_ref * (digital_input / float(self.max_val))
return analog_voltage
def show_bit_contribution(self):
"""
نمایش سهم ولتاژ هر بیت (از MSB تا LSB)
"""
print(f"--- سهم ولتاژی هر بیت (V_ref={self.v_ref}V, {self.n}-bit) ---")
for i in range(self.n - 1, -1, -1):
weight = 2 ** i
voltage = self.digital_to_analog(weight)
bit_position = i
print(f"Bit {bit_position} (Weight {weight}): {voltage:.4f} V")
print("-" * 40)
# --- تنظیمات شبیهسازی ---
RESOLUTION = 4 # رزولوشن (مثلاً 4 بیت برای دیدن راحت پلهها)
V_REF = 5.0 # ولتاژ مرجع 5 ولت
# ساخت نمونه از کلاس DAC
my_dac = R2R_DAC(RESOLUTION, V_REF)
# نمایش سهم هر بیت در خروجی (برای درک بهتر)
my_dac.show_bit_contribution()
# --- تولید داده برای نمودار (شبیهسازی موج رمپ) ---
# تولید تمام کدهای دیجیتال ممکن از 0 تا 2^N
digital_inputs = np.arange(0, 2**RESOLUTION)
analog_outputs = [my_dac.digital_to_analog(val) for val in digital_inputs]
# --- رسم نمودار ---
plt.figure(figsize=(10, 6))
plt.step(digital_inputs, analog_outputs, where='post', color='blue', linewidth=2)
plt.title(f'R-2R DAC Simulation ({RESOLUTION}-bit, Vref={V_REF}V)')
plt.xlabel('Digital Input Code (Decimal)')
plt.ylabel('Analog Output Voltage (V)')
plt.grid(True, which='both', linestyle='--', alpha=0.7)
# نمایش LSB (اندازه هر پله)
lsb_voltage = V_REF / (2**RESOLUTION)
plt.text(0, V_REF - 0.5, f'LSB Step Size: {lsb_voltage:.4f} V', fontsize=12, color='red')
plt.show()
توضیحات کد:
- کلاس
R2R_DAC: این کلاس شبیهساز ماست. در متد__init__تعداد بیتها و ولتاژ مرجع را میگیرد. - متد
digital_to_analog: این متد قلب تپنده R-2R است. هر عدد صحیحی که به آن بدهید، ولتاژ خروجی متناظر را محاسبه میکند. - متد
show_bit_contribution: برای درک آموزشی، نشان میدهد که روشن بودن هر بیت به تنهایی چقدر ولتاژ تولید میکند (مثلاً در سیستم ۴ بیتی، بیت با ارزشترین (MSB) نیمی از ولتاژ مرجع را تولید میکند). - رسم نمودار (
plt.step): از آنجا که خروجی DAC پیوسته نیست و پلهای است، از تابعstepبرای رسم استفاده شده تا شکل واقعی خروجی (Staircase) دیده شود.
خروجی مورد انتظار:
اگر برنامه را با رزولوشن ۴ بیت و ولتاژ ۵ ولت اجرا کنید:
- یک نمودار پلهای خواهید دید که از ۰ ولت شروع شده و تا حدود ۴.۶۸ ولت بالا میرود (نه دقیقاً ۵ ولت، چون ماکزیمم خروجی همیشه یک LSB کمتر از ولتاژ مرجع است).
- در کنسول، سهم هر بیت چاپ میشود (مثلاً بیت ۳ مقدار ۲.۵ ولت، بیت ۲ مقدار ۱.۲۵ ولت و…).
پیشنهاد بعدی
این کد یک DAC ایدهآل را شبیهسازی میکند (یعنی فرض میکند مقاومتها دقیقاً R و 2R هستند). در واقعیت، مقاومتها خطا (Tolerance) دارند (مثلاً ۱٪ خطا).
آیا دوست دارید کد را توسعه دهیم تا خطای مقاومتها را نیز شبیهسازی کند و ببینیم چطور عدم دقت مقاومتها باعث خراب شدن خطینگی (Linearity) نمودار میشود؟
سایت آموزشی الکترونیک و کامپیوتر اوپن مقاله های آموزشی الکترونیک و کامپیوتر و فن آوری