همهی ما به این موضوع واقف هستیم که میکروکنترلرها با مقادیر دیجیتال کار میکنند اما دنیای واقعی دنیای سیگنالها و مقادیر آنالوگ است. به همین علت به مبدلهایی نیاز داریم که بتوانند سیگنالهای آنالوگ را گرفته و معادل دیجیتال آنها را برای میکروها آماده کنند تا میکرو بتواند آن مقادیر را پردازش کند. به این نوع از مبدلها آنالوگ به دیجیتال (ADC) گفته میشود. در مقابل گونهی دیگری هم هستند که در قسمت خروجی میکروها، مقدار نهایی به دست آمده را که یک مقدار دیجیتال است را تحویل گرفته، و معادل آنالوگ آنها را بازیابی میکنند تا آمادهی ورود به جهان واقعی شود. به این دسته هم مبدل های دیجیتال به آنالوگ (DAC) گفته میشود.
یک مثال ساده برای مبدلهای DAC، در استودیوهای ضبط صدا و آواز است. تصور کنید که یک خواننده یا گوینده، در حال خواندن یا گفتن چیزی با استفاده از میکروفن است. امواج صوتیای که توسط این فرد تولید میشوند، امواجی آنالوگ هستند. اما دستگاه ضبط صدا این امواج را به صورت دیجیتال ضبط میکند. سپس در زمانی که از دستگاه بخواهیم صدای تولید شده را بازپخش کند، از روی مقادیر دیجیتال ذخیره شده، معادل آنالوگ را تولید کرده و به عنوان خروجی به ما تحویل میدهد. اگر این خروجی به امواج آنالوگ تبدیل نشود توسط گوش ما قابل شنیدن و تشخیص به همان صورت اولیه که خوانده شده بود، نیست. بنابراین در این سیستم از هر دو مبدل ADC و DAC استفاده میشود که DAC در قسمت خروجی و ADC در قسمت ورودی قرار دارند.
از مبدلهای DAC در موارد فراوانی استفاده میشود که به عنوان مثال میتوان به کنترل موتورها، کنترل شدت نور LEDها، تقویتکنندههای صوتی، انکودرهای ویدئو، سیستمهای دسترسی اطلاعات و … اشاره کرد.
در جلسات قبلی پروژهی اتصال مبدل DAC به بورد آردوینو را به شما آموزش دادهایم که میتوانید به آن دسترسی داشته باشید.
در این جلسه نیز قصد داریم چگونگی اتصال آن به میکروکنترلر STM32F103C8 را توضیح دهیم.
آنچه که برای انجام این پروژه نیاز داریم.
- میکروکنترلر STM32F103C8
- تراشهی مبدل دیجیتال به آنالوگ MCP4725
- پتانسیومتر 10K
- LCD 16×2
- برد بورد
- سیم رابط برد بوردی
دربارهی مبدل MCP4725 DAC
این آیسی یک مبدل دیجیتال به آنالوگ ۱۲ بیتی است و خروجیهای ولتاژ بین ۰ تا ۵ ولت تولید میکند. با استفاده از پروتکل I2C قابل کنترل است و دارای یک مموری EEPROM نیز هست.
همان طور که گفتیم این مبدل ۱۲ بیتی است. به عبارت دیگر میتوان گفت که رزولوشن آن ۱۲ بیت است. یعنی میتوان مقادیر از ۰ تا ۴۰۹۶ (۲۱۲) را به آن داد و متناسب با هر ورودی یک سطح ولتاژ خروجی از ۰ تا ۵ دریافت کرد. اگر ۵ ولت را ولتاژ مرجع (Reference Voltage) بنامیم، بنابراین:
فرمول محاسبهی ولتاژ خروجی
O/P Voltage = (Reference Voltage / Resolution) x Digital Value
به عنوان مثال اگر مقدار دیجیتال خروجی برابر با ۲۰۴۸ باشد؛ خروجی آنالوگ به این ترتیب محاسبه میشود.
O/P Voltage = (5/ 4096) x 2048 = 2.5V
پایههای MCP4725
در دو تصویر زیر نمایی از پایههای این تراشه و توضیحات مربوط به هر پایه را میتوانید ببینید.
پروتکل ارتباطی I2C در MCP4725
این تراشهی DAC را میتوانیم با هر میکروکنترلری که از پروتکل I2C پشتیبانی کند ارتباط دهیم. همان طور که میدانیم این پروتکل ارتباطی تنها به دو سیم SDA و SCL احتیاج دارد. به صورت پیشفرض، آدرس I2C برای ماژول 0x60 ،MCP4725 است و پین های I2C در میکروی STM32F103C8 به این صورت هستند.
SDA: PB7 or PB9, PB11. SCL: PB6 or PB8, PB10.
نمودار مدار و توضیحات مرتبط با آن
اتصال میکروکنترلر و LCD
اتصال مبدل DAC و میکروکنترلر
پتانسیومتر را هم به این ترتیب وصل میکنیم که پایهی وسطی آن را به پین PA1 میکروکنترلر وصل میکنیم. (PA1 ورودی آنالوگ را دریافت کرده و آن را به دیجیتال تبدیل میکند)
پایهی سمت چپ پتانسیومتر را به زمین و پایهی سمت راستی را هم به پین ۳.۳ ولت میکرو وصل میکنیم.
به منظور روشن شدن بیشتر مسیری که پیش رو داریم؛ هدف ما در این آموزش این است مبدل دیجیتال به آنالوگ MCP4725 را به میکروی STM32 وصل کنیم و از پتانسیومتر 10K استفاده میکنیم تا برای پین PA0 که دارای مبدل ADC است، ورودی آنالوگ فراهم کنیم. این مبدل ADC مقدار آنالوگ دریافت شده را خود به معادل دیجیتال آن تبدیل خواهد کرد. پس از آن که مقادیر دیجیتال پردازش شدند، از طریق I2C bus برای مبدل MCP4725 ارسال میشوند و مبدل آنها را دوباره به دنیای آنالوگ بازخواهد گرداند.
میتوان از پین PA1 میکرو نیز استفاده کرد تا بتوانیم خروجی آیسی مبدل را چک کنیم.
در نهایت هر دو مقدار ADC و DAC را بر روی نمایشگر LCD نشان خواهیم داد.
نوشتن برنامهی میکرو
نیازی نیست که حتما پروگرمر FTDI داشته باشید تا کدها را روی میکرو بارگذاری کنید. کافیست فقط PC را از به پورت USB میکرو متصل کنید و به کمک ARDUINO IDE آن را پروگرم کنید.
ضمنا، کد کامل این پروژه را در انتهای آموزش برای شما قرار دادهایم.
ابتدا کتابخانههای لازم برای I2C و LCD را باید به کد اضافه کنیم. مواردی مانند wire.h ،SoftWire.h و liquidcrystal.h. اگر در مورد این کتابخانهها اطلاعاتی ندارید میتوانید به منابع موجود مراجعه کنید.
#include<Wire.h> #include <LiquidCrystal.h> #include<SoftWire.h>
در قدم بعدی پینهایی از LCD را که به میکرو متصل هستند، initialize میکنیم.
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
سپس آدرس I2C مبدل MCP4725 را تعریف میکنیم که گفتیم به صورت پیشفرض 0x60 است.
#define MCP4725 0x60
در بخش ()void setup، ابتدا ارتباط I2C در پینهای (PB7 (SDA و (PB6 (SCL میکرو شروع میکنیم.
Wire.begin(); //Begins the I2C communication
سپس مود LCD را روی ۲*۱۶ قرار میدهیم و پیغام شروع به کار اولیهی آن را نیز تنظیم میکنیم.
lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("STM32F103C8"); lcd.setCursor(0,1); lcd.print("DAC with MCP4725"); delay(2000); lcd.clear();
در بخش ()void loop:
- ابتدا در buffer[0] بایت کنترلی را قرار میدهیم (0b01000000)
(010-Sets MCP4725 in Write mode) buffer[0] = 0b01000000;
- جملات بعدی مقادیر آنالوگ را از پین PA0 خوانده و آنها را به مقادیر دیجیتال در بازهی ۰ تا ۴۰۹۶ (۲۱۲، گفتیم که رزولوشن مبدل ما ۱۲ بیتی است) تبدیل میکنند.
adc = analogRead(PA0) ;
- و در بخش بعدی، مطابق با فرمولی که گفتیم، مقدار آنالوگ ولتاژ معادل هر کدام از مقادیر دیجیتال محاسبه میشود. لازم به ذکر است که ولتاژ مرجع در اینجا ۳.۳ ولت است.
float ipvolt = (3.3/4096.0)* adc;
- بیت MSB را به کمک یک شیفت ۴ بیتی به راست در buffer[1] قرار میدهیم و LSB را با شیفت ۴ بیتی به چپ در buffer[2].
buffer[1] = adc >> 4; buffer[2] = adc << 4;
- قسمت بعدی مقدار آنالوگ را از پین PA1 میخواند. این پین خروجی آیسی MCP4725 محسوب میشود. میتوان آن را به مولتیمتر نیز متصل کرد تا صحت خروجی معلوم شود.
unsigned int analogread = analogRead(PA1);
- سپس توسط فرمول زیر، مقدار ولتاژ از روی مقدار analogread محاسبه میشود.
float opvolt = (3.3/4096.0)* analogread;
- در قسمت ()void loop دستورات دیگری نیز وجود دارند که توضیح میدهیم.
برای مبادلهی اطلاعات با MCP4725:
Wire.beginTransmission(MCP4725);
برای ارسال بایت کنترل به I2C bus:
Wire.write(buffer[0]);
برای ارسال MSB به I2C:
Wire.write(buffer[1]);
برای ارسال LSB به I2C:
Wire.write(buffer[2]);
پایان مبادلهی اطلاعات:
Wire.endTransmission();
و برای نمایش نتایج بر روی LCD:
lcd.setCursor(0,0); lcd.print("A IP:"); lcd.print(adc); lcd.setCursor(10,0); lcd.print("V:"); lcd.print(ipvolt); lcd.setCursor(0,1); lcd.print("D OP:"); lcd.print(analogread); lcd.setCursor(10,1); lcd.print("V:"); lcd.print(opvolt); delay(500); lcd.clear();
تست پروژهی اتصال DAC به میکروی STM32
اگر با چرخاندن پیچ پتانسیومتر، مقدار ولتاژ ورودی ADC را تغییر دهیم، باید شاهد باشیم که خروجی DAC نیز تغییر کند. همان طور که در تصویر زیر میبینید؛ مقادیر ورودی را در ردیف اول LCD و مقادیر خروجی را در ردیف دوم LCD مشاهده میکنیم. یکی مولتیمتر هم به پین خروجی MCP4725 متصل میکنیم تا صحت ولتاژ نمایش داده شده روی نمایشگر را بررسی کنیم.
کد کامل و ویدئویی از اجرای مراحل پروژه را در ادامه میتوانید ببینید.
کد
#include<Wire.h> //Include Wire library for using I2C functions #include<SoftWire.h> #include <LiquidCrystal.h> //Include LCD library for using LCD display functions #define MCP4725 0x60 //MCP4725 address as 0x60 Change yours accordingly const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); unsigned int adc; byte buffer[3]; void setup() { Wire.begin(); //Begins the I2C communication lcd.begin(16,2); //Sets LCD in 16X2 Mode lcd.print("CIRCUIT DIGEST"); delay(1000); lcd.clear(); lcd.setCursor(0,0); lcd.print("STM32F103C8"); lcd.setCursor(0,1); lcd.print("DAC with MCP4725"); delay(2000); lcd.clear(); } void loop() { buffer[0] = 0b01000000; //Sets the buffer0 with control byte (010-Sets in Write mode) adc = analogRead(PA0); //Read Analog value from pin PA0 float ipvolt = (3.3/4096.0)* adc; //Finding voltage formula buffer[1] = adc >> 4; //Puts the most significant bit values buffer[2] = adc << 4; //Puts the Least significant bit values unsigned int analogread = analogRead(PA1) ; //Reads analog value from PA1 float opvolt = (3.3/4096.0)* analogread; //Finding Voltage Formula Wire.beginTransmission(MCP4725); //Joins I2C bus with MCP4725 with 0x60 address Wire.write(buffer[0]); //Sends the control byte to I2C Wire.write(buffer[1]); //Sends the MSB to I2C Wire.write(buffer[2]); //Sends the LSB to I2C Wire.endTransmission(); //Ends the transmission lcd.setCursor(0,0); lcd.print("A IP:"); lcd.print(adc); //Prints the ADC value from PA0 lcd.setCursor(10,0); lcd.print("V:"); //Prints the Input Voltage at PA0 lcd.print(ipvolt); lcd.setCursor(0,1); lcd.print("D OP:"); lcd.print(analogread); //Prints the ADC value from PA1 (From DAC) lcd.setCursor(10,1); lcd.print("V:"); lcd.print(opvolt); //Prints the Input Voltage at PA1 (From DAC) delay(500); lcd.clear(); }
ویدئو
منبع: ترجمه از سایت circuitdigest.com
امیدواریم آموزش «مبدل دیجیتال به آنالوگ یا DAC در STM32» برایتان مفید واقع شده باشد. در ادامه پیشنهاد میکنیم دیگر آموزشهای STM32 را نیز مطالعه کنید.
اگر این نوشته برایتان مفید بود لطفا کامنت بنویسید.