مبدل دیجیتال به آنالوگ یا DAC در STM32

همه‌ی ما به این موضوع واقف هستیم که میکروکنترلرها با مقادیر دیجیتال کار می‌کنند اما دنیای واقعی دنیای سیگنال‌ها و مقادیر آنالوگ است. به همین علت به مبدل‌هایی نیاز داریم که بتوانند سیگنال‌های آنالوگ را گرفته و معادل دیجیتال آنها را برای میکروها آماده کنند تا میکرو بتواند آن مقادیر را پردازش کند. به این نوع از مبدل‌ها آنالوگ به دیجیتال (ADC) گفته می‌شود. در مقابل گونه‌ی دیگری هم هستند که در قسمت خروجی میکروها، مقدار نهایی به دست آمده را که یک مقدار دیجیتال است را تحویل گرفته، و معادل آنالوگ آنها را بازیابی می‌کنند تا آماده‌ی ورود به جهان واقعی شود. به این دسته هم مبدل های دیجیتال به آنالوگ (DAC) گفته می‌شود.

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

یک مثال ساده برای مبدل‌های DAC، در استودیوهای ضبط صدا و آواز است. تصور کنید که یک خواننده یا گوینده، در حال خواندن یا گفتن چیزی با استفاده از میکروفن است. امواج صوتی‌ای که توسط این فرد تولید می‌شوند، امواجی آنالوگ هستند. اما دستگاه ضبط صدا این امواج را به صورت دیجیتال ضبط می‌کند. سپس در زمانی که از دستگاه بخواهیم صدای تولید شده را بازپخش کند، از روی مقادیر دیجیتال ذخیره شده، معادل آنالوگ را تولید کرده و به عنوان خروجی به ما تحویل می‌دهد. اگر این خروجی به امواج آنالوگ تبدیل نشود توسط گوش ما قابل شنیدن و تشخیص به همان صورت اولیه که خوانده شده بود، نیست. بنابراین در این سیستم از هر دو مبدل ADC و DAC استفاده می‌شود که DAC  در قسمت خروجی و ADC در قسمت ورودی قرار دارند.

از مبدل‌های DAC در موارد فراوانی استفاده می‌شود که به عنوان مثال می‌توان به کنترل موتورها، کنترل شدت نور LEDها، تقویت‌کننده‌های صوتی، انکودرهای ویدئو، سیستم‌های دسترسی اطلاعات و … اشاره کرد.

در جلسات قبلی پروژه‌ی اتصال مبدل DAC به بورد آردوینو را به شما آموزش داده‌ایم که می‌توانید به آن دسترسی داشته باشید.

در این جلسه نیز قصد داریم چگونگی اتصال آن به میکروکنترلر STM32F103C8 را توضیح دهیم.

آنچه که برای انجام این پروژه نیاز داریم.

  • میکروکنترلر STM32F103C8
  • تراشه‌ی مبدل دیجیتال به آنالوگ MCP4725
  • پتانسیومتر 10K
  • LCD 16×2
  • برد بورد
  • سیم رابط برد بوردی

درباره‌ی مبدل MCP4725 DAC

این آی‌سی یک مبدل دیجیتال به آنالوگ ۱۲ بیتی است و خروجی‌های ولتاژ بین ۰ تا ۵ ولت تولید می‌کند. با استفاده از پروتکل I2C قابل کنترل است و دارای یک مموری EEPROM نیز هست.

همان‌ طور که گفتیم این مبدل ۱۲ بیتی است. به عبارت دیگر می‌توان گفت که رزولوشن آن ۱۲ بیت است. یعنی می‌توان مقادیر از ۰ تا ۴۰۹۶ (۲۱۲) را به آن داد و متناسب با هر ورودی یک سطح ولتاژ خروجی از ۰ تا ۵ دریافت کرد. اگر ۵ ولت را ولتاژ مرجع (Reference Voltage) بنامیم، بنابراین:

مطلب پیشنهادی:  ارتباط RS-485 بین STM32 و بورد Arduino Uno

فرمول محاسبه‌ی ولتاژ خروجی

O/P Voltage = (Reference Voltage / Resolution) x Digital Value

به عنوان مثال اگر مقدار دیجیتال خروجی برابر با ۲۰۴۸ باشد؛ خروجی آنالوگ به این ترتیب محاسبه می‌شود.

O/P Voltage = (5/ 4096) x 2048 = 2.5V

پایه‌های MCP4725

در دو تصویر زیر نمایی از پایه‌های این تراشه و توضیحات مربوط به هر پایه را می‌توانید ببینید.

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

پروتکل ارتباطی I2C در MCP4725

این تراشه‌ی DAC را می‌توانیم با هر میکروکنترلری که از پروتکل I2C پشتیبانی کند ارتباط دهیم. همان ‌طور که می‌دانیم این پروتکل ارتباطی تنها به دو سیم SDA و SCL احتیاج دارد. به صورت پیش‌فرض، آدرس I2C برای ماژول 0x60 ،MCP4725 است و پین های I2C در میکروی STM32F103C8 به این صورت هستند.

SDA:  PB7 or PB9, PB11.
SCL:  PB6 or PB8, PB10.

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

نمودار مدار و توضیحات مرتبط با آن

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

اتصال میکروکنترلر و LCD

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

اتصال مبدل DAC و میکروکنترلر

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

پتانسیومتر را هم به این ترتیب وصل می‌کنیم که پایه‌ی وسطی آن را به پین PA1 میکروکنترلر وصل می‌کنیم. (PA1 ورودی آنالوگ را دریافت کرده و آن را به دیجیتال تبدیل می‌کند)

پایه‌ی سمت چپ پتانسیومتر را به زمین و پایه‌ی سمت راستی را هم به پین ۳.۳ ولت میکرو وصل می‌کنیم.

به منظور روشن شدن بیشتر مسیری که پیش رو داریم؛ هدف ما در این آموزش این است مبدل دیجیتال به آنالوگ MCP4725 را به میکروی STM32 وصل کنیم و از پتانسیومتر 10K استفاده می‌کنیم تا برای پین PA0 که دارای مبدل ADC است، ورودی آنالوگ فراهم کنیم. این مبدل ADC مقدار آنالوگ دریافت شده را خود به معادل دیجیتال آن تبدیل خواهد کرد. پس از آن که مقادیر دیجیتال پردازش شدند، از طریق I2C bus برای مبدل MCP4725 ارسال می‌شوند و مبدل آنها را دوباره به دنیای آنالوگ بازخواهد گرداند.

می‌توان از پین PA1 میکرو نیز استفاده کرد تا بتوانیم خروجی آی‌سی مبدل را چک کنیم.

در نهایت هر دو مقدار ADC و DAC را بر روی نمایشگر LCD نشان خواهیم داد.

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

نوشتن برنامه‌ی میکرو

نیازی نیست که حتما پروگرمر 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:

  1. ابتدا در buffer[0] بایت کنترلی را قرار می‌دهیم (0b01000000)
(010-Sets MCP4725 in Write mode)
buffer[0] = 0b01000000;
  1. جملات بعدی مقادیر آنالوگ را از پین PA0 خوانده و آنها را به مقادیر دیجیتال در بازه‌ی ۰ تا ۴۰۹۶ (۲۱۲، گفتیم که رزولوشن مبدل ما ۱۲ بیتی است) تبدیل می‌کنند.
adc = analogRead(PA0) ;
  1. و در بخش بعدی، مطابق با فرمولی که گفتیم، مقدار آنالوگ ولتاژ معادل هر کدام از مقادیر دیجیتال محاسبه می‌شود. لازم به ذکر است که ولتاژ مرجع در اینجا ۳.۳ ولت است.
float ipvolt = (3.3/4096.0)* adc;
  1. بیت MSB را به کمک یک شیفت ۴ بیتی به راست در buffer[1] قرار می‌دهیم و LSB را با شیفت ۴ بیتی به چپ در buffer[2].
buffer[1] = adc >> 4;             
buffer[2] = adc << 4;
  1. قسمت بعدی مقدار آنالوگ را از پین PA1 می‌خواند. این پین خروجی آی‌سی MCP4725 محسوب می‌شود. می‌توان آن را به مولتی‌متر نیز متصل کرد تا صحت خروجی معلوم شود.
unsigned int analogread = analogRead(PA1);
  1. سپس توسط فرمول زیر، مقدار ولتاژ از روی مقدار analogread محاسبه می‌شود.
float opvolt = (3.3/4096.0)* analogread;
  1. در قسمت ()void loop دستورات دیگری نیز وجود دارند که توضیح می‌دهیم.
مطلب پیشنهادی:  اجرای RTOS بر روی میکرو کنترلر ARM

برای مبادله‌ی اطلاعات با 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 متصل می‌کنیم تا صحت ولتاژ نمایش داده شده روی نمایشگر را بررسی کنیم.

استفاده از مبدل دیجیتال به آنالوگ در بورد STM32F10C8

کد کامل و ویدئویی از اجرای مراحل پروژه را در ادامه می‌توانید ببینید.

کد

#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

مطلب پیشنهادی:  آموزش برنامه نویسی میکروکنترلرهای ARM [از شی گرایی تا توابع CMSIS]

امیدواریم آموزش «مبدل دیجیتال به آنالوگ یا DAC در STM32» برایتان مفید واقع شده باشد. در ادامه پیشنهاد می‌کنیم دیگر آموزش‌های STM32 را نیز مطالعه کنید.

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *