تولید موج سینوسی با AVR و DAC0800

توسط | 10 اسفند, 1398 | AVR, میکروکنترلر, وبلاگ | 49 دیدگاه ها

ساخت-موج-سینوسی-avr

آموزش AVR یوبرد

شاهکار 8بیتی اتمل

آموزش های رایگان AVR

فیلم های آموزش AVR

آموزش خصوصی AVR

اخبار جدید یوبرد در اینستاگرام

تولید موج سینوسی با AVR و DAC0800 تنها نیاز به راه اندازی پورت IO و ایجاد وقفۀ زمانی منظم دارد. به این صورت که با وقفۀ زمانی منظم، اعضای یک آرایه را در رجیستر PORTx قرار می دهیم. پایه های یکی از پورت ها به پایه های ورودی DAC0800 متصل اند. و مقادیر قرار گرفته در رجیستر PORTx، توسط آی سی DAC0800 به آنالوگ تبدیل می شوند. با وقفۀ زمانی منظم که می توانیم آن را با تایمر ایجاد کنیم، مقدار PORTx را تغییر می دهیم. بنابراین سیگنال آنالوگ خروجی تغییر می کند و اگر تغییرات با یک الگوی سینوسی باشد، سیگنال خروجی سینوسی است. در این نوشته به روش ساخت موج سینوسی با میکروکنترلرهای AVR و آی سی DAC0800 می پردازیم. این نوشته می تواند برای این کاربردها مفید باشد:

  • ساخت موج سینوسی سه فاز با AVR و DAC0800؛
  • فانکشن ژنراتور با AVR و DAC0800؛
  • اینورتر سینوسی با AVR و DAC0800؛
  • ساخت موج مثلثی با AVR و DAC0800؛
  • ساخت موج دندانه اره ای با AVR و DAC0800؛
  • و … .

فیلم آموزش تایمر در STM32                         (فیلم آموزش ARM STM32 مقدماتی)

فیلم آموزش تایمر پیشرفته در STM32

فیلم آموزش تایمر در AVR                             (فیلم آموزش میکروکنترلرهای AVR مقدماتی)

فیلم آموزش تایمر پیشرفته در AVR

فیلم آموزش تایمر در آردوینو                          (فیلم آموزش آردوینو مقدماتی)

فیلم آموزش تایمر پیشرفته در آردوینو

نمونه کدی را که در این نوشته بررسی می کنیم، در اتمل استودیو (میکروچیپ استودیو) برای میکروکنترلر ATmega64A نوشته ایم. فایل های پروژۀ اتمل استودیو به همراه فایل شبیه سازی نرم افزار پروتئوس در پیوست قرار دارند. این نمونه کد را در نرم افزار کدویژن نیز نوشته و در فایل پیوست قرار داده ایم. در ادامه ابتدا دربارۀ آی سی DAC0800 و خروجی آن صحبت می کنیم. سپس روش تولید موج سینوسی با آن را تشریح و در نهایت نمونه کد نوشته شده را بررسی می کنیم.

تولید-موج-سینوسی-dac

تصویر 1 – تولید موج سینوسی با AVR و DAC0800

آی سی DAC0800 و ملزومات راه اندازی آن

پیش از ورود به مبحث تولید موج سینوسی با AVR، ابتدا مختصراً آی سی DAC0800 را بررسی می کنیم. DAC0800 یک مبدل دیجیتال به آنالوگ هشت بیتی است. این DAC می تواند ورودی دیجیتال 8 بیتی را به سیگنال آنالوگ معادل تبدیل کند. خروجی DAC0800 دو جریان Sink در جهت مخالف هم است. که با مقاومت های پول آپ آن را به ولتاژ تبدیل می کنیم. مبدل دیجیتال به آنالوگ DAC0800 دارای 16 پایه است. هشت پایۀ آن برای دادۀ دیجیتال ورودی، دو پایه برای خروجی آنالوگ، دو پایه برای ولتاژهای مرجع، دو پایه برای تغذیۀ آی سی و دو پایه به نام های Threshold Control و Compensation است. پایه های مبدل دیجیتال به آنالوگ DAC0800 را در تصویر زیر می بینید.

پایه-پکیج

تصویر 2 – پایه های آی سی DAC0800

با توجه به مدار پیشنهادی دیتاشیت برای راه اندازی DAC0800، اتصالات آن را به صورت زیر برقرار کرده ایم. در این پروژه از ولتاژهای +15 و -15 ولت برای تغذیۀ DAC0800 (پایه های 13 و 3) استفاده کرده ایم. ولتاژ مرجع مثبت (پایۀ 14) و منفی (پایۀ 15) را 5 ولت و صفر در نظر گرفته ایم. این پایه ها را با مقاومت 5 کیلو اهم به 5 ولت و زمین متصل کرده ایم. با دو مقاومت 10 کیلو اهم نیز پایه های خروجی مثبت و منفی (پایه های 4 و 2) را پول آپ کرده ایم. پایه های 5 تا 12 به ترتیب به پایه های PA7 تا PA0 میکروکنترلر متصل می شوند. پایۀ 1 به زمین و پایۀ 16 با خازن 10 نانو فاراد به تغذیۀ منفی متصل می شوند. خازن های 100 نانو فاراد C2 و C3 نیز روی تغذیۀ مثبت قرار می گیرند.

نکته: شمارۀ پایه های ذکر شده بر اساس پکیج DIP این آی سی است.

نکته: خازن C1، سرامیکی و خازن های C2 و C3، الکترولیتی هستند.

مدار-راه-اندازی

تصویر 3 – مدار راه اندازی DAC0800 با AVR

محاسبۀ دامنۀ ولتاژ خروجی DAC0800

در دیتاشیت DAC0800 برای محاسبۀ جریان خروجی فرمولی آورده شده است. حداکثر جریانی که خروجی می کشد برابر است با:

Ifs = (Vref/Rref) * (255/256)

 

Ifs به معنای جریان حداکثر پایۀ خروجی است. اگر تمام پایه های دیجیتال ورودی 1 شوند، جریانی که از پایۀ Iout عبور می کند برابر Ifs خواهد بود. اگر تمام ورودی های دیجیتال صفر باشند، جریانی که از Iout بار (پایۀ 2) عبور می کند، برابر Ifs است. زمانی که Iout در ماکزیمم خود است، Iout بار (پایۀ 2) در مینیمم خود است. با توجه به مطالب گفته شده و تصویر زیر داریم:

Ifs4 = - Ifs2
Ifs4 = Ifs
Ifs4 = -Ifs
Ifs = (Vref/Rref) * (255/256)

KVL(*): Vo1 = VCC - R Ifs4 = VCC - R Ifs
KVL(**): Vo2 = VCC - R Ifs2 = VCC + R Ifs

Vout(p-p) = Vo2 - Vo1 = 2R Ifs = 2R (Vref/Rref) * (255/256)

 

جریان های خروجی آی سی از مقاومت های پول آپ روی پایه های 2 و 4، کشیده می شود. بنابراین ولتاژی روی این پایه ها می افتد. در KVL(*) و KVL(**) این ولتاژها را محاسبه کرده ایم. با توجه به مقادیر مقاومت های این پروژه، ولتاژ پیک تو پیک موج سینوسی خروجی برابر است با:

Vout(p-p) = Vo2 - Vo1 = 2 * 10k * (5/5k) * (255/256) = 19.92v

 

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

تصویر 4 – شماتیک برای محاسبۀ ولتاژ خروجی DAC0800

می توانیم تنها یکی از خروجی های آی سی را استفاده کنیم. اما در این صورت ولتاژ دارای آفست خواهد بود. برای حذف آفست خروجی و به دست آوردن تفاضل Vo1 و Vo2 می توانیم از تقویت کنندۀ تفاضلی استفاده کنیم. در تصویر زیر یک تقویت کنندۀ تفاضلی که با استفاده از یک اپ امپ ساخته ایم، آمده است. ورودی های این تقویت کنندۀ تفاضلی همان خروجی های آی سی DAC0800 هستند. گین آن نیز با توجه به مقدار مقاومت ها برابر 1 است. بنابراین خروجی آن برابر Vo2 – Vo1 است. زمانی که Vo2 در حداکثر مقدار خود است، Vo1 مینیمم است و بالعکس. پس اگر موج سینوسی روی آنها ایجاد شود، با هم 180 درجه اختلاف فاز خواهند داشت. بنابراین دامنۀ شکل موج حاصل از تفاضل آنها، دو برابر دامنۀ هر یک از آنهاست. در ادامه به تولید موج سینوسی با AVR و DAC0800 می پردازیم.

تقویت-کننده-تفاضلی

تصویر 5 – تقوییت کنندۀ تفاضلی با گین 1 با اپ امپ LM741

روش تولید موج سینوسی با AVR و DAC0800

برای کار با مبدل دیجیتال به آنالوگ DAC0800 و راه اندازی آن با میکروکنترلرهای AVR یا هر میکروکنترلر دیگر، باید یک دادۀ 8 بیتی به صورت موازی به پایه های ورودی آن بدهیم. اگر مقادیر صفر تا 255 را به ورودی آن بدهیم، خروجی آن از صفر تا ولتاژ حداکثر تغییر می کند. برای این که موج سینوسی در خروجی داشته باشیم، دادۀ 8 بیتی را باید طبق الگوی سینوسی به آن بدهیم. برای این کار می توانیم از Lookup table سینوسی استفاده کنیم. Lookup tableها را می توانیم از سایت هایی که آنها را تولید می کنند کپی کنیم. این مقادیر، یک Lookup table هشت بیتی 256 تایی با الگوی سینوسی است:

131 , 134 , 137 , 140 , 144 , 147 , 150 , 153 , 156 , 159 , 162 , 165 , 168 , 171 , 174 , 177 ,
180 , 183 , 185 , 188 , 191 , 194 , 196 , 199 , 201 , 204 , 206 , 209 , 211 , 214 , 216 , 218 ,
220 , 222 , 225 , 227 , 229 , 230 , 232 , 234 , 236 , 237 , 239 , 240 , 242 , 243 , 245 , 246 ,
247 , 248 , 249 , 250 , 251 , 252 , 252 , 253 , 254 , 254 , 255 , 255 , 255 , 255 , 255 , 255 ,
255 , 255 , 255 , 255 , 255 , 254 , 254 , 253 , 252 , 252 , 251 , 250 , 249 , 248 , 247 , 246 ,
245 , 243 , 242 , 240 , 239 , 237 , 236 , 234 , 232 , 230 , 229 , 227 , 225 , 222 , 220 , 218 ,
216 , 214 , 211 , 209 , 206 , 204 , 201 , 199 , 196 , 194 , 191 , 188 , 185 , 183 , 180 , 177 ,
174 , 171 , 168 , 165 , 162 , 159 , 156 , 153 , 150 , 147 , 144 , 140 , 137 , 134 , 131 , 128 ,
125 , 122 , 119 , 116 , 112 , 109 , 106 , 103 , 100 , 97  , 94  , 91  , 88  , 85  , 82  , 79  ,
76  , 73  , 71  , 68  , 65  , 62  , 60  , 57  , 55  , 52  , 50  , 47  , 45  , 42  , 40  , 38  ,
36  , 34  , 31  , 29  , 27  , 26  , 24  , 22  , 20  , 19  , 17  , 16  , 14  , 13  , 11  , 10  ,
9   , 8   , 7   , 6   , 5   , 4   , 4   , 3   , 2   , 2   , 1   , 1   , 1   , 1   , 1   , 1   ,
1   , 1   , 1   , 1   , 1   , 2   , 2   , 3   , 4   , 4   , 5   , 6   , 7   , 8   , 9   , 10  ,
11  , 13  , 14  , 16  , 17  , 19  , 20  , 22  , 24  , 26  , 27  , 29  , 31  , 34  , 36  , 38  ,
40  , 42  , 45  , 47  , 50  , 52  , 55  , 57  , 60  , 62  , 65  , 68  , 71  , 73  , 76  , 79  ,
82  , 85  , 88  , 91  , 94  , 97  , 100 , 103 , 106 , 109 , 112 , 116 , 119 , 122 , 125 , 128

 

اگر این مقادیر با تأخیر زمانی منظم به ورودی DAC داده شوند، خروجی آن 256 پله تغییر سطح ولتاژ است. که این 256 پله تغییر سطح ولتاژ، یک شکل موج سینوسی را به وجود می آورد. هر چه تعداد مقادیر Lookup table بیشتر باشد، خروجی بیشتر به موج سینوسی شبیه است. تعداد مقادیر Lookup table در پروژۀ این نوشته را 256 مقدار در نظر گرفته ایم.

خروجی-سینوسی

تصویر 6 – پله های خروجی DAC حاصل از تبدیل مقادیر Lookup table به ولتاژ آنالوگ و تشکیل موج سینوسی

محاسبۀ فرکانس موج سینوسی خروجی DAC

برای این که فرکانس موج سینوسی ثابت باشد، مقادیر Lookup table باید در فواصل زمانی ثابت به DAC0800 داده شوند. این فاصلۀ زمانی را با تایمر 1 در AVR خواهیم ساخت. حال می خواهیم رابطۀدورۀ تناوب موج سینوسی را با تعداد پله هایی که تایمر می شمارد به دست آوریم. شکل موج سینوسی خروجی، 256 پله دارد. بنابراین دوره تناوب موج سینوسی که نام آن را T می گذاریم برابر 256 * t است. t همان فاصلۀ زمانی ثابت است که با تایمر 1 ساخته می شود. تایمر را روی مد CTC با مقدار TOP برابر OCR1A تنظیم و وقفۀ مقایسۀ A را نیز فعال می کنیم. در این صورت شمارندۀ تایمر (TCNT1) از صفر تا مقدار رجیستر OCR1A می شمارد و وقفۀ مقایسه اتفاق می افتد. در روتین این وقفه مقادیر Lookup table را در پورت A قرار می دهیم. دوباره تایمر از صفر تا OCR1A می شمارد و وقفۀ مقایسه دوباره اتفاق می افتد. در این هنگام مقدار بعدی Lookup table را در پورت A قرار می دهیم. زمان بین دو وقفۀ تایمر، همان t است. وقتی 256 بار وقفه اتفاق بیفتد، 256 مقدار Lookup table به ترتیب با وقفۀ زمانی t در پورت A قرار می گیرند. در این پروژه مقدار فرکانس کلاک تایمر 1، همان کلاک CPU یعنی 8 مگاهرتز است. به تصویر زیر دقت کنید. مقدار رجیستر OCR1A نسبت به فرکانس موج سینوسی (freq) از فرمول زیر به دست می آید. برای تغییر فرکانس موج سینوسی، OCR1A باید تغییر کند. که با قرار دادن مقدار فرکانس مورد نظر در فرمول، مقدار OCR1A محاسبه می شود.

تایمر 1 و 3 در AVR

T = 1/freq = 256 * t , t = OCR1A * (1/F_CPU)

1/freq = 256 * (OCR1A *(1/F_CPU))

OCR1A = F_CPU / (256 * freq) , F_CPU = 8MHz

OCR1A = 31250/freq

 

رابطه-فرکانس-موج-سینوسی-ocr1a

تصویر 7 – تولید موج سینوسی با AVR و DAC0800، رابطۀ بین فرکانس موج سینوسی و رجیستر OCR1A

نمونه کد تولید موج سینوسی با AVR و DAC0800

ابتدا فرکانس CPU را 8 مگاهرتز دیفاین و پس از آن کتابخانه هایی را فراخوانی کرده ایم. در ادامه Lookup table سینوسی را در یک آرایه آورده ایم.

#define F_CPU	8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "Libs/clcd.h"

unsigned char const_source[256] ={
131 , 134 , 137 , 140 , 144 , 147 , 150 , 153 , 156 , 159 , 162 , 165 , 168 , 171 , 174 , 177 ,
180 , 183 , 185 , 188 , 191 , 194 , 196 , 199 , 201 , 204 , 206 , 209 , 211 , 214 , 216 , 218 ,
220 , 222 , 225 , 227 , 229 , 230 , 232 , 234 , 236 , 237 , 239 , 240 , 242 , 243 , 245 , 246 ,
247 , 248 , 249 , 250 , 251 , 252 , 252 , 253 , 254 , 254 , 255 , 255 , 255 , 255 , 255 , 255 ,
255 , 255 , 255 , 255 , 255 , 254 , 254 , 253 , 252 , 252 , 251 , 250 , 249 , 248 , 247 , 246 ,
245 , 243 , 242 , 240 , 239 , 237 , 236 , 234 , 232 , 230 , 229 , 227 , 225 , 222 , 220 , 218 ,
216 , 214 , 211 , 209 , 206 , 204 , 201 , 199 , 196 , 194 , 191 , 188 , 185 , 183 , 180 , 177 ,
174 , 171 , 168 , 165 , 162 , 159 , 156 , 153 , 150 , 147 , 144 , 140 , 137 , 134 , 131 , 128 ,
125 , 122 , 119 , 116 , 112 , 109 , 106 , 103 , 100 , 97  , 94  , 91  , 88  , 85  , 82  , 79  ,
76  , 73  , 71  , 68  , 65  , 62  , 60  , 57  , 55  , 52  , 50  , 47  , 45  , 42  , 40  , 38  ,
36  , 34  , 31  , 29  , 27  , 26  , 24  , 22  , 20  , 19  , 17  , 16  , 14  , 13  , 11  , 10  ,
9   , 8   , 7   , 6   , 5   , 4   , 4   , 3   , 2   , 2   , 1   , 1   , 1   , 1   , 1   , 1   ,
1   , 1   , 1   , 1   , 1   , 2   , 2   , 3   , 4   , 4   , 5   , 6   , 7   , 8   , 9   , 10  ,
11  , 13  , 14  , 16  , 17  , 19  , 20  , 22  , 24  , 26  , 27  , 29  , 31  , 34  , 36  , 38  ,
40  , 42  , 45  , 47  , 50  , 52  , 55  , 57  , 60  , 62  , 65  , 68  , 71  , 73  , 76  , 79  ,
82  , 85  , 88  , 91  , 94  , 97  , 100 , 103 , 106 , 109 , 112 , 116 , 119 , 122 , 125 , 128 };

 

روتین وقفۀ مقایسۀ A تایمر 1 را هم به این شکل می نویسیم. هر بار مقدار شمارندۀ تایمر (TCNT1) به مقدار OCR1A برسد، یک وقفۀ مقایسه اتفاق می افتد. و این روتین وقفه اجرا می شود. دفعۀ اول، عضو صفرم آرایۀ const_source در PORTA قرار می گیرد. دفعۀ دوم، عضو یکم آرایه و به همین ترتیب اعضای صفرم تا عضو شمارۀ 255 در PORTA قرار می گیرند. شرط if برای این است که مقدار ph1 از 255 بیشتر نشود و دفعۀ بعد دوباره عضو صفرم آرایه در PORTA قرار بگیرد. پورت A میکروکنترلر به ورودی DAC متصل است و نتیجۀ تداوم این روند، شکل موج سینوسی در خروجی DAC است.

ISR(TIMER1_COMPA_vect)
{
	static unsigned int ph1=0;
	PORTA = const_source[ph1];
	ph1++;
	if(ph1 > 255) ph1 = 0;
}

 

در تابع main ابتدا چند متغیر تعریف کرده و مقدار اولیۀ فرکانس را 10 هرتز قرار داده ایم. مقدار delay_const را که در نهایت در OCR1A قرار می گیرد، طبق فرمول به دست آورده ایم. در سطر بعد پورت A را برای اتصال به DAC و پورت D را برای اتصال به LCD خروجی کرده ایم. به دو پایۀ PE4 و PE5 دو دکمه برای تغییر فرکانس متصل کرده ایم. در اینجا با یک کردن بیت های 4 و 5 رجیستر PORTE، پول آپ داخلی آنها را فعال کرده ایم. در سطرهای بعد تایمر 1 را در مد شمارۀ 4 پیکربندی کرده ایم. مقدار OCR1A آن هم برابر delay_const قرار داده ایم. سپس وقفۀ مقایسۀ تایمر 1 را فعال، LCD را راه اندازی و پرچم کلی وقفه ها را فعال کرده ایم. در LCD نیز مقدار فرکانس اولیه را نمایش داده ایم.

int main(void)
{
	unsigned int delay_const=0;
	unsigned char freq=10;
	char lcd_str[16];
	
	delay_const=(unsigned int) 31250/freq;

	DDRA=0xFF;
	DDRD=0xFF;
	PORTE=(1<<PORTE5) | (1<<PORTE4);

	TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
	TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
	OCR1AH=(delay_const>>8);
	OCR1AL=(delay_const&0xFF);

	TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (1<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);

	lcd_init(16);
	lcd_clear();
	sprintf(lcd_str,"Frequency = %d",freq);
	lcd_puts(lcd_str);
	
	sei();

 

نتیجه-مقدار-اولیه-فرکانس

تصویر 8 – تولید موج سینوسی با AVR، مقدار اولیۀ فرکانس

تغییر فرکانس موج سینوسی

برای تولید موج سینوسی با AVR با فرکانس متغیر، دو دکمه به پایه های PE4 و PE5 متصل کرده ایم. با فشردن دکمۀ روی PE5 چون که به صورت داخلی پول آپ است، بیت پنجم رجیستر PINE صفر می شود. بنابراین برنامۀ درون if اول اجرا می شود. فرکانس یک واحد کم می شود و مقدار delay_const با توجه به فرمول به دست می آید. delay_const یک مقدار 16 بیتی است. 8 بیت با ارزش آن را در OCR1AH و 8 بیت کم ارزشش را در OCR1AL قرار داده ایم. در سطرهای بعد محدودۀ 1 تا 100 هرتز برای مقدار فرکانس در نظر گرفته ایم. سپس مقدار فرکانس را در LCD نمایش داده ایم. با فشردن دکمۀ روی PE4، برنامه وارد if دوم می شود و فرکانس یک واحد افزایش می یابد. در اینجا هم مثل if قبلی OCR1A مقداردهی و فرکانس در LCD نمایش داده می شود. وقتی مقدار OCR1A تغییر می کند، تعداد پله های شمارش تایمر و در نتیجه مقدار t هم تغییر می کند. این تغییر در نهایت باعث می شود که فرکانس موج سینوسی تغییر کند. در تصویر زیر موج سینوسی فرکانس متغیر با AVR با فرکانس های 25 هرتز و 70 هرتز آمده است.

نکته: در مقداردهی به رجیسترهای 16 بیتی در AVR دقت شود که اول باید در بایت با ارزش نوشت و سپس در بایت کم ارزش.

پورت IO در AVR

while (1)
{
		
	if(!((PINE & (1<<5)) == (1<<5)))
	{
		_delay_ms(200);
		freq--;
		delay_const=(unsigned int) 31250/freq;
		OCR1AH=(delay_const>>8);
		OCR1AL=(delay_const&0xFF);
		if (freq>100) freq=100;
		if (freq<1) freq=1;
		lcd_clear();
		sprintf(lcd_str,"Frequency = %d",freq);
		lcd_puts(lcd_str);
	}
		
	if(!((PINE & (1<<4)) == (1<<4)))
	{
		_delay_ms(200);
		freq++;
		delay_const=(unsigned int) 31250/freq;
		OCR1AH=(delay_const>>8);
		OCR1AL=(delay_const&0xFF);
		if (freq>100) freq=100;
		if (freq<1) freq=1;
		lcd_clear();
		sprintf(lcd_str,"Frequency = %d",freq);
		lcd_puts(lcd_str);
	}
}

 

نتیجه-تولید-موج-سینوسی

تصویر 9 – نتیجۀ نهایی راه اندازی DAC با AVR و تولید موج سینوسی با AVR و DAC0800

نتایج تولید موج سینوسی با AVR و DAC0800

  1. در راه اندازی DAC با میکروکنترلرهای AVR یا میکروکنترلرهای دیگر، در صورتی که نوع ارتباط DAC، ارتباط موازی باشد، تنها نیاز است ورودی DAC را به یک پورت میکروکنترلر متصل کنیم و مقادیر دیجیتال را روی آن پورت قرار دهیم.
  2. آی سی DAC0800 تعداد 8 پایۀ ورودی دارد که مقادیر دیجیتال را به صورت موازی می گیرد. دو پایۀ خروجی هم دارد که سیگنال های آنالوگ روی آنها قرار می گیرد.
  3. ولتاژ خروجی DAC0800 به ولتاژ مرجع، مقاومت روی پایۀ ولتاژ مرجع و مقاومت های پول آپ خروجی بستگی دارد.
  4. می توان با یک تقویت کنندۀ تفاضلی دو خروجی DAC0800 را به یک خروجی تبدیل کرد و ولتاژ آفست را حذف کرد.
  5. در تولید موج سینوسی با DAC باید مقادیری که توالی آنها الگوی سینوسی دارد، در زمان های منظم به ورودی DAC داده شوند.
  6. هر چه تعداد مقادیر Lookup table بیشتر باشد، خروجی DAC به شکل موج مورد نظر شبیه تر است.
  7. وقفه های زمانی منظم را می توان به روش های مختلفی ساخت. یکی از این روش ها استفاده از تایمر است.
  8. در استفاده از تایمر به روش های مختلفی می توان وقفه های زمانی منظم ایجاد کرد. یکی از این روش ها استفاده از مد CTC تایمر است.
  9. در پروژۀ این نوشته، برای تغییر فرکانس کافی است تعداد پلیه های شمارش تایمر تغییر کند. که این کار با تغییر OCR1A صورت گرفته است.
  10. فرکانس موج سینوسی خروجی با مقدار OCR رابطۀ عکس دارد. هر چه مقدار OCR کمتر شود، فرکانس موج سینوسی خروجی بیشتر می شود و بالعکس.


 

رضا بداغی

رضا بداغی

عضو هیئت مدیره یوبرد، طراح و برنامه نویس سیستم های دیجیتال مبتنی بر میکروکنترلر، طراح PCB و مدرس آموزش های میکروکنترلر، طراحی PCB و برنامه نویسی میکروکنترلر

سفارش پروژه میکروکنترلر یوبرد

زیرساخت مطمئن صنعت

جدیدترین تاپیک های AVR

برنامه-نویسی-میکروکنترلر-ویژوال-استودیو

برنامه نویسی میکروکنترلرها با ویژوال استودیو

نصب VisualGDB روی ویژوال استودیو، ساخت پروژه برای برنامه نویسی میکروکنترلرها با ویژوال استودیو، ساخت پروژه برای STM32 در ویژوال استودیو، کدنویسی STM32 در ویژوال استودیو، ساخت پروژه برای AVR در ویژوال استودیو، ساخت پروژه برای LPC در ویژوال استودیو، ساخت پروژۀ آردوینو در ویژوال استودیو

رله-relay

رله، سوییچ تحریک پذیر

تعریف رله، تاریخچه، طرز کار رلۀ الکترومکانیکی، اصطلاحات، انواع الکترومکانیکی، رلۀ حالت جامد، رلۀ هیبریدی، رلۀ حرارتی و انواع تحریک شونده با عوامل غیر الکتریکی، انواع موجود در صنعت برق و برق صنعتی، رلۀ ایمنی و برخی انواع حفاظتی، رلۀ دیجیتال، لزوم استفاده و راه اندازی رله، مشخصات الکتریکی

پروتکل-i2c-protocol

پروتکل I2C، ادغامی از USART و SPI توسط Philips

پروتکل I2C، تاریخچه I2C، ویژگی ها و کاربردهای I2C، عبارات و اصطلاحات I2C، باس، اتصالات و گسترش شبکه I2C، سیگنال های I2C، قالب داده و آدرس در I2C، انتقال داده در I2C، آدرس دهی 10 بیتی، قابلیت Multi-master، حکمیت، مشخصات الکتریکی و زمانی، مقدار مقاومت های پول آپ، Clock Stretching

سون-سگمنت-seven-segment

سون سگمنت، نمایشگر هفت قسمتی

سون سگمنت چیست؟ انواع 7-segment، تاریخچه 7-segment، ساختار 7-segment و نمایش در آن، تعداد ارقام و 7-segmentهای مالتی پلکس، کاربردها، انواع اندازه ها و رنگ ها و مدار راه اندازی 7-segment، بایاس 7-segment، مقدار مقاومت در راه اندازی 7-segment، درایور سون سگمنت، پایه های 7-segment

49 دیدگاه ها

  1. با سلام من یک اینورتر تبدیل برق باطری به برق شهر 220 ولت دارم ولی خروجی ان شبه سینوسی یا همان مربعی است میخواستم آن را به سینوسی کامل تبدیل کنم میشه لطفااگه مدار یا غیره …دارید برام ایمیل کنید اینورترم 150 وات هست ممنون میشم با تشکر

    پاسخ
    • سلام. بنده برای این کار مدار تست شده ندارم. همچنین نمیدونم اینورتری که دارید دارای چه ساختاری هست. اگه اینورتری که دارید توی خروجیش از ترانس افزاینده استفاده شده، میشه در اولیۀ ترانس فیلتر RC قرار داد و مربعی رو تا حدودی به سینوسی شبیه کرد. البته با این کار دامنۀ سیگنال کاهش پیدا میکنه. همچنین مقاومت چون در مسیر جریان بالا قرار میگیره باید توان بالا باشه. شاید نیازی به مقاومت نباشه و تنها با موازی کردن یه خازن با اولیۀ ترانس این کار انجام بشه. مقدار خازن هم بستگی به ساختار اینوتر داره.

      پاسخ
  2. سلام جناب مهندس وقتتون بخیر ممنون بایت مطلبتون
    اگه میشه بفرمایید که امکان تغییر دامنه موج سینوسی از طریق avr هم وجود داره و چطور میشه این کار رو انجام داد.

    پاسخ
    • سلام. بله این کار امکان پذیره. توی این قسمت:

      PORTA = const_source[ph1];

      اگه مقدار const_source رو در یک عدد کمتر از 1 ضرب کنید، مقادیری که روی پورت A قرار میگیره به نسبت اون عدد کاهش پیدا میکنه. به این شکل:

      PORTA = gain * const_source[ph1];

      همچنین مقدار قرار گرفته توی پورت A باید عدد صحیح باشه. پس به این شکل تغییر پیدا میکنه:

      PORTA = (unsigned char) (gain * const_source[ph1]);

      الان اگه مقدار متغیر gain که float هستش بین 0 و 1 تغییر کنه، دامنۀ سیگنال هم بین صفر و حداکثر تغییر میکنه.

       

      پاسخ
  3. سلام اقای مهند میشه بفرمایید چطور میشه دامنه موج سینوسی خروجی رو تغییر داد

    پاسخ
    • توی سوال قبلیتون جواب دادم.

      پاسخ
  4. سلام جناب مهندس خیلی مچکرم بابت پاسخگوییتون به سوالات
    من میخوام یک اینورتر بسازم به اینصورت که این شکل موج سینوسی رو با یک شکل موج مثلثی فرکانس بالا حدود 15KHZ مقایسه کنم شما اپ امپی رو میتونید پیشنهاد بدید که در ورودی دو شکل موج سینوسی و مثلثی رو دریافت و مقایسه کنه و در خروجی سیگنال منطقی صفر و یک با سطح ولتاژ ۵ ولت بده
    خیلی سپاس گزارم

    پاسخ
    • سلام. خواهش میکنم. برای این که توی خروجی اپ امپ سیگنال صفر و 5 بگیرید میشه از اپ امپ های single supply استفاده کنید. فقط مشکلش اینه که شما اگه ولتاژ تغذیه مثبت این اپ امپ رو 5 ولت بدید و ولتاژ تغذیۀ منفی اون رو به زمین وصل کنید، خروجی اون دقیقاً صفر و 5 نمیشه. چون امپ ها همیشه ولتاژ اشباع شون مقداری از ولتاژ تغذیه شون کمتره (مثلاً 1 ولت). برای مثال خروجی میشه 1 ولت و 4 ولت. برای رفع این مشکل میشه اپ امپ با تغذیۀ دوبل استفاده کرد. طوری که ولتاژ تغذیۀ منفی رو 1- بذارید و ولتاژ تغذیۀ  مثبت رو 6 ولت. در این صورت اون اختلاف جبران میشه و خروجی شما میشه صفر و 5. البته کار خوب اینه که همین مدار هم از به اشباع رفتنش جلوگیری بشه تا توی اون فرکانس عملکرد بهتری داشته باشه. برای این کار میشه ازمدارات جلوگیری از اشباع که با دیود و مقاومت ساخته میشن استفاده کرد. که در این صورت میشه مقدار خروجی رو با تغییر مقدار اون مقاومت ها طوری تغییر داد که خروجی بین 0 و 5 تغییر وضعیت بده. همچنین میشه ولتاژها رو هم مثلاً 12- و 12 گذاشت. حالا برای بحث فرکانس هم بهتره یه اپ امپ با slew rate  بالاتر از 20 v/us بذارید. اپ امپ LF351 رو الان با پی اسپایس با موج مثلثی 15 کیلوهرتز تست کردم خروجی جالبی نداشت. slew rate این اپ امپ 16 هستش. اپ امپ با slew rate بالاتر چیزی به ذهنم نمیرسه. خواهش میکنم. موفق باشید.

      پاسخ
    • سلام وقت بخیر
      مهندس جان میشه این مقایسه رو تو خود میکرو انجام داد؟
      مثلا به جای این که مقادیر سینوسی رو توی پورت Aقرار بدیم توی رجیستر OCRn یک تایمر دیگه مثلا تایمر ۳ قرار بدیم و مود این تایمر رو رو حالت pwm تصحیح فاز بذاریم

      پاسخ
    •  سلام. بله میشه. مدهای Fast PWM هم میشه استفاده کرد. در این صورت تو خروجی یه موج PWM داریم که عرض پالس اون با دامنۀ مقدار سینوسی تغییر میکنه. البته باید این مورد هم در نظر بگیریم. اگه فرضاً فرکانس کلاک واحد تایمر 8 مگاهرتز باشه، زمان هر پله میشه 0.125 میکروثانیه. برای رسیدن به فرکانس 15 کیلوهرتز باید زمان 66.6 میکروثانیه سپری بشه. بنابراین نیازه که تعداد 533 پله طی بشه. بنابراین باید حداقل مقدار TCNTx برابر 65003 باشه. حالا برای این که مقایسه بین TCNTx و OCRxy انجام بشه، باید تغییر مقدار موج سینوسی بین 65003 و 65536 باشه. مگر این که از مدهای کمتر از 16 بیت مثلاً مد 10 بیتی یا 9 بیتی استفاده کنیم. که در این صورت محاسبات متفاوته.

      پاسخ
  5. سلام اقای مهندس من یه مشکلی دارم تو شبیه سازی در پروتئوس اینکه وقتی کلید ها رو برای تغییر فرکانس میزنم فرکانس تغییر نمیکنه بلکه باید چند بار بزنم تا فرکانس یک واحد تغییر کنه به نظر شما مشکل از چیه؟

    پاسخ
    • سلام. این مشکل ممکنه به دلیل مطابق نبودن گذر زمان پروتئوس با واقعیت باشه. اگه کلید رو نگه دارید فرکانس تغییر میکنه. اما بازم زمان تغییرش بیشتر از زمان واقعیه. همچنین ممکنه فرکانس کاری انتخاب شده توی برنامه با فرکانس انتخاب شده توی پروتئوس متفاوت باشه. تو پروتئوس روی میکروکنترلر دابل کلیک کنید و مقدار CKSEL Fuses رو روی حالت Int RC 8MHz قرار بدید. چون توی برنامۀ نوشته شده (توی پیوست) هم 8 مگاهرتز انتخاب شده. موفق باشید.

      پاسخ
  6. سلام جناب مهندس وقت بخیر
    من میخواستم هنگام شروع به کار مدار،فرکانس موج خروجی از ۱ شروع بشه و به صورت خودکار تا ده هرتز در مدت ۲ ثانیه افزایش پیدا کنه و روی ده هرتز ثابت بشه و بعد بشه با کلید ها فرکانس رو تغییر داد.
    من خواستم با یک تایمر جدا این کار رو انجام بدم اما جواب نگرفتم اگه شما راهنمایی کنید ممنون میشم

    پاسخ
    • سلام. خیلی ممنون. تنها کاری که باید انجام بدید اینه که مقدار اولیۀ متغیر freq رو 1 بذارید.حالا بعد از روشن شدن میکروکنترلر باید با یه تاخیر زمانی یک واحد یک واحد به مقدار freq اضافه بشه. تا جایی که به 10 برسه. حالا این تاخیر زمانی ممکنه با توابع delay به وجود بیاد یا با یه تایمر. و بهتره با تایمر باشه. یه متغیر رو توی وقفۀ تایمر ++ کنید. (منظورم یه تایمر دیگه ست.) بعد شرط بذارید که هر وقت مقدارش مثلاً به 250 رسید، یه واحد به freq اضافه بشه. بعد مقدار freq هم توی همون شرط بذارید که در صورتی این کار انجام بشه که مقدار freq کمتر از 10 باشه. در غیر این صورت تو همون روتین وقفۀ تایمر هم شمارش تایمر رو غیر فعال کنید و هم میتونید کلاً تایمر رو غیر فعال کنید. چنین کدی مثلاً توی روتین وقفۀ سرریز تایمر 3 بنویسید:

      ISR(...){
      static counter = 0;
      counter++;
      if((counter>250) && (freq<=10))
      {
      counter=0;
      freq++;
      }
      else
      {
      غیر فعال کردن تایمر 3 و وقفۀ اون;
      }
      TCNT3=0x...;
      }

       

      این مقدار 250 رو مثال عرض کردم. ببینید با توجه به فرکانسی که برای تایمر انتخاب میکنید، چه مقداری باید بدید که 10 تا شمارش رو توی 2 ثانیه انجام بده. همچنین ممکنه نیاز باشه برای رسیدن به مقدار صحیح، آخر روتین وقفه به TCNT هم مقداری بدید که از اون شروع به شمارش کنه.

      در نظر داشته باشید که قبل از فعال کردن پرچم کلی وقفه ها، تایمر 3 رو هم فعال کرده باشد. همچنین دقت کنید که تایمر مربوط به این کار رو قبل از تایمر مربوط به تعیین فرکانس موج خروجی فعال کنید. تو این مثال برای این پروژه، اول تایمر 3 و بعد تایمر 1 رو فعال کنید.

       

      پاسخ
    • سلام جناب مهندس خیلی ممنون بابت راهنمایی هاتون
      من طبق فرمایش شما عمل کردم و این کدی رو که عکسشو تو لینک زیرگذاشتم نوشتم اما اصلا کار نمیکنه و خروجی هیچ تفاوتی با قبل نداره.
      عکس کدی که نوشتم تو لینک زیر هست

      پاسخ
    • سلام. خواهش میکنم. خب ببنید شما باید به این روش عمل کنید. اول تایمر 3 و وقفه ش رو مطابق کد زیر پیکربندی کنید. بعد برید سراغ تایمر 1. یعنی وقفۀ تایمر 3 رو هم قبل از پیکربندی تایمر 1 پیکربندی کنید.

      // Timer/Counter 3 initialization
      // Clock source: System Clock
      // Clock value: 1000.000 kHz
      // Mode: Normal top=0xFFFF
      // Timer Period: 2 ms
      // Timer3 Overflow Interrupt: On
      TCCR3A=(0<<COM3A1) | (0<<COM3A0) | (0<<COM3B1) | (0<<COM3B0) | (0<<COM3C1) | (0<<COM3C0) | (0<<WGM31) | (0<<WGM30);
      TCCR3B=(0<<ICNC3) | (0<<ICES3) | (0<<WGM33) | (0<<WGM32) | (0<<CS32) | (1<<CS31) | (0<<CS30);
      TCNT3H=0xF8; // TCNT3 = 63536
      TCNT3L=0x30;
      ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (1<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);

       

      الان تایمر 3 از 63536 تا 65535میشمره که میشه 2000 پله. فرکانس CPU تو این پروژه 8 مگاهرتزه. مطابق کد بالا، تقسیم فرکانسی 8 برای تایمر 3 انتخاب شده. بنابراین کلاک تایمر میشه 1 مگاهرتز. 2000 پله که طی بشه، زمان بین هر سرریز برابر 2000 تا 1 میکروثانیه میشه که میشه 2 میلی ثانیه. حالا میخوایم هر 200 میلی ثانیه یک واحد به فرکانس اضافه بشه، که توی 2 ثانیه، فرکانس از 1 بشه 10 هرتز. بنابراین تو وقفه این کد رو می نویسیم.

      // Timer3 overflow interrupt service routine
      interrupt [TIM3_OVF] void timer3_ovf_isr(void)
      {
      static unsigned char counter=0;
      // Reinitialize Timer3 value
      TCNT3H=0xF830 >> 8;
      TCNT3L=0xF830 & 0xff;        
      // Place your code here
      counter++;
      if(counter>=100)
      {
        counter=0;
        freq++;
        if(freq>=10)
        {
          TCCR3A=0x00;
          TCCR3B=0x00;
          TCNT3H=0x00;
          TCNT3L=0x00; 
          ETIMSK &=~ (1<<TOIE3);
        }
      }
      }

       

      در این صورت هر 2 میلی ثانیه ک وقفه اتفاق بیفته، یه واحد به counter اضافه میشه. تا این که مقدار counter برابر 100 بشه. این نشون میده که 200 میلی ثانیه سپری شده. حالا هر 200 میلی ثانیه یک واحد به freq اضافه میشه. وقتی فرکانس برابر 10 میشه، برنامه وارد شرط پایانی میشه و تایمر 3 و وقفۀ اون غیر فعال میشه. و دیگه از اون به بعد افزایش مقدار freq با تایمر 3 انجام نمیشه.

      اون کد قبلی مشکلش این بود که چون همون اول مقدار counter کم بود وشرط اول صحیح نبود، وارد else میشد و کلاً تایمر 3 رو غیر فعال میکرد. ولی این کد دیگه اینطوری نیست

      فقط دقت کنید که این روند 9 بار تکرار میشه. چون مقدار اولیۀ فرکانس برابر 1 هرتزه. بنابراین افزایش فرکانس با تایمر 3 در کل 1.8 ثانیه طول میکشه. شما میتونید به جای اون مقدار 100مقدار 111 رو قرار بدید. که البته باز هم مقدار دقیق بدست نمیاد. و زمان این افزایش فرکانس میشه 1998 میلی ثانیه.

      موفق باشید.

      پاسخ
    • دوست عزیز متغیر freq هم به صورت عمومی volatile تعریف کنید.

      پاسخ
  7. برنامه بالا به زبان بيسيك موجود دارين ٢-اگر برنامه ساده تري با حق الزحمه پرداخت كنيم خدمتتون سريع برام مينويسين فقط با كليدي كم و زياد بشه يا با ورودي adc فركانسش كم وزياد بشه در محدوده هرتز تا ١٠٠ كيلو حداكثر ممنون ميشم سريع بهم خبرشو بدين

    پاسخ
    • سلام. خیر این نمونه کد رو فقط به زبان C نوشتیم. متاسفانه در حال حاضر پروژه انجام نمیدم. در ضمن برای رسیدن به فرکانس 100 کیلوهرتز باید تعداد اعضای آرایۀ const source رو کم کنید. اینجوری با فرکانس تایمر 8 مگاهرتز، با تعداد اعضای آرایۀ 80 تا، میشه فرکانس 100 کیلوهرتز ساخت. و خب چون تعداد عضوهای اون ارایه کم میشه، موج خروجی با موجی که توی تصاویر این نوشته میبینید متفاوته و کمتر شبیه سینوسیه.

      پاسخ
  8. سلام . کدهای داده شده در کد ویژن وارد کردم کلی error داد که…..!!!!!

    پاسخ
    • سلام. توی پیوست پروژۀ کدویژن هست. فایل پیوست رو دانلود کنید. بدون ارور کامپایل کردم. اگه برای شما ارور بده احتمالا کدویژن شما مشکل داره. من از کدویژن نسخۀ 3.12 استفاده می کنم. موفق باشید

      پاسخ
  9. مهندس میشه لطفا مفهوم خط زیر را توضیح بدید:
    خروجی DAC0800 به صورت جریان Sink است که با استفاده از مقاومت پول آپ به ولتاژ تبدیل می شود

    پاسخ
    • یعنی این که توی پایه های خروجی، ترانزیستورها open-colector هستند. همون طوری که توی تصویر مدار داخلیش مشخصه. کلکتور ترانزیستورها از داخل به تغذیه متصل نیست. همچنین موقع روشن شدن این ترانزیستورها، جریان به سمت داخله. اگه مقاومت پول آپ از پایۀ خروجی به VCC وصل کنیم، و ترانزیستور یا ترانزیستورها روشن بشن، جریان از VCC خارج از مدار، از مقاومت پول آپ عبور میکنه و وارد پایۀ DAC میشه. در واقع پایۀ خروجی DAC جریان رو میکشه. وقتی که چنین پایۀ خروجی جریان رو بکشه میگیم جریان sink. در مقابل جریان سورس وجود داره. که اگه پایۀ خروجی یه آی سی، جهت جریانش رو به بیرون باشه، بهش میگیم جریان source. حالا با قرار دادن مقاوت میشه این جریان ها رو به ولتاژ تبدیل کرد. توی DAC0800 ولتاژ پایۀ خروجی میشه ولتاژ تغذیه منهای ولتاژی که در اثر جریان sink روی مقاومت میفته. موفق باشید

      پاسخ
  10. ممنون بابت مطالب آموزشی خوب.
    AD1866 رو از کجا میتونیم بخریم؟

    پاسخ
    • خواهش میکنم. زنده باشید. برای خریدش فروشگاه های اینترنتی رو بررسی کنید

      پاسخ
  11. سلام مهندس جان خسته نباشید.میشه درباره خواندن سون سگمنت بوسیله atmega64 واینکه چرا دیتای مربوط به سگمنت d نیاز به خوندن نداره توضیح بدین …ممنون از سایت بسیار خوبتون…

    پاسخ

یک دیدگاه بنویسید

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

دیگر آموزش های یوبرد

آموزش زبان C و MISRA-C یوبرد

گام نخست دنیای میکروکنترلر

آموزش طراحی PCB و نویز یوبرد

تجسم دنیای الکترونیک

آموزش لحیم کاری و IPC-A-610 یوبرد

ساخت دنیای الکترونیک

آموزش میکروکنترلرهای ARM STM32 یوبرد

شروع بازی ST

آموزش آردوینو یوبرد

جادۀ آسفالت میکروکنترلر

آموزش FreeRTOS یوبرد

زمان واقعی در میکروکنترلر و پردازنده های کوچک با FreeRTOS

آموزش ماژول های SIM800 یوبرد

تلفن همراه صنعت

آموزش زبان ++C و ++MISRA-C یوبرد

لمس شی گرایی در میکروکنترلرها

آموزش میکروکنترلرهای LPC یوبرد

یادگار فیلیپس

آموزش های شاخص

دانلود

لطفا برای دریافت لینک دانلود اطلاعات خواسته شده را وارد نمایید
ضبط پیام صوتی

زمان هر پیام صوتی 4 دقیقه است