آموزش AVR با کدویژن قسمت 6 مبدل آنالوگ به دیجیتال(1)

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

در این قسمت از آموزش قصد داریم تا به بررسی مبدل آنالوگ به دیجیتال یا ADC بپردازیم.این مبدل که بر روی اکثر AVR ها موجود است وظیفه تبدیل سیگنال های آنالوگ به دیجیتال را دارد به طور مثال بیشتر سنسور های موجود در بازار خروجی آنالوگ دارن که خروجی آنها قابل فهم برای میکرو نیست برای اینکار می توان سیگنال آنالوگ را به دیجیتال تبدیل کرده و عملیات مورد نظر را بر روی آن انجام داد مثلا سنسور دمای LM35 یک سنسور دما با خروجی آنالوگ است که ولتاژی بین 0 تا 1 ولت را می دهد و به ازای هر یک درجه دما در خروجی 0.1 ولت اضافه می شود اما اگر این سنسور را مستقیما به میکرو وصل کنیم میکرو در ورودی پایه خود ولتاژ 0 ولت را نشان خواهد داد چون میکرو فقط ولتاژ 0 ولت و 5 ولت را می شناسد برای حل این مشکل قسمتی را به میکرو اضافه کرده اند تا بتواند ورودی های آنالوگ را اندازه گرفته و عددی متناظر با آن را نمایش دهد که اگر از این سیستم برای تبدیل ولتاژ آنالوگ استفاده کنیم عددی بین 0 الی 1024 را به ما نمایش خواهد داد که عدد 0 بیان گر ولتاژ 0 ولت و عدد 1023 بیانگر ولتاژهای 5 و بیشتر از آن است وسایر اعداد تقسیمی از این اعداد خواهد بود مثلا اگر میکرو عدد 823 را نمایش دهد بیان گر چه ولتازی می باشد؟ با یک تناسب ساده ولتاژ 3.98 ولت بدست می آید

(5volt * 823)/1023=3.98Volt

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

همان طور که می دانید برای استفاده از امکانات میکرو رجیستر هایی وجود دارد که با تنظیم آن ها می توان امکانات میکرو را و فعال کرده و از آنها استفاده کرد در ادامه به بررسی و تنظیم این رجیستر ها حواهیم پرداخت. ممکن است با دیدن این رجیستر ها کمی بترسید 🙂 ولی نگران نباشید چون خواهید دید که هنگام برنامه نویسی ، با این رجیستر ها زیاد درگیر نخواهید شد.

واحد ADC میکرو دارای تنظیمات مختلفی اعم از سرعت نمونه برداری دقت نمونه برداری انتخاب ولتاژ مرجع حالت تبدیل و.. غیره می باشد

ADC دارای دو حالت تبدیل FREE و Single می باشد که در حالت Single بعد از هر تبدیل میکرو منتظر می ماند تا توسط برنامه ای که کابر نوشته عمل تبدیل را دوباره انجام دهد ولی در حالت FREE میکرو به طور خودکار عمل تبدیل را انجام داده و مقدار آن را در رجیستر مربوطه اش ذخیره می کند.

ولتاژ مرجع:ولتاژی است که میکرو سیگنال آنالوگ را با آن مقایسه کرده و عمل تبدیل را انجام می دهد .در اکثر میکرو ها سه ولتاژ مرجع وجود دارد در برخی میکرو ممکن است کمتر از مقدار فوق باشد در حالت کلی ولتاژ های مرجع به صورت زیر است:

ولتاژ مرجع داخلی 2.56 ولت ، ولتاژ مرجع روی پایه AREF و ولتاژ مرجع روی پایه Avcc  که انتخاب هر کدام از آنها توسط تنظیم رجیستر ها انجام میگیرد.

رجیستر ها:

رجیستر اول ADMUX:

رجیستر ADMUX
رجیستر ADMUX

همان طور که در شکل بالا ملاحظه می کنید دو 6 و 7 از رجیستر ADMUX برای انتخاب ولتاژ مرجع به کار می رود

 

ولتاژ مرجع

REFS1

REFS0

در این حالت ولتاژ روی پایه Aref انتخاب می شود

0

0

ولتاژ روی پایه Avcc به عنوان ولتاژ مرجع انتخاب می شود

0

1

بدون کاربرد

1

0

انتخاب ولتاژ مرجع داخلی 2.56 ولت

1

1

 

بیت های MUX0 تا MUX4 برای انتخاب پایه ADC مورد نظر انتخاب خواهد شد که نحوه انتخاب در خود عکس موجود است.

بیت ADLAR هم بعدا توضیح داده خواهد شد.

رجیستر ADCSRA:

 

رجیستر ADCSRA
رجیستر ADCSRA

بیت 7 یا ADEN بیت فعال سازی مبدل ADC است برای فعال کردن ADC این بیت باید مقدار 1 و برای غیر فعال کردن مقدار 0 به بدهید.

بیت 6 یا ADSC بیت شروع تبدیل می باشد که در حالت Single اگر یک شود تبدیل شروع شده و پس از پایان خود به خود صفر می شود و درحالت FREE با یک کردن این بیت تبدیل شروع می شود .

بیت 5 یا ADATE بیت است که وقتی یک باشد میکرو یک منبع را برای شروع خودکار تبدیل انتخاب می کند این منبع می تواند یک پایه یا یک تایمر باشد یعنی در صورتی که یک پایه یک شد عمل تبدیل خود به خود آغاز شود . برای انتخاب منبع مورد نظر باید بیت های ADTS در رجیستر SFIOR را تنظیم کرد که بعدا توضیح داده خواهد شد.

بیت 4 یا ADIF بیتی است که وقتی عمل تبدیل پایان یافت مقدار 1 در آن ذخیره می شود.

بیت 3 یا ADIE بیتی است که در صورت یک بودن در صورتی که تبدیل پایان پذیرد مقدار بیتی قبلی یا 4 ار برابر یک خواهد کرد یا به عبارت دیگر فعال ساز بیت 4 هست

بیت های ADPS0 تا ADPS2 مقدار فرکانس ADC را تعیین می کنند بدین صورت که با تنظیم این 3 بیت فرکانس ADC تقسیمی از فرکانس اصلی AVR خواهد بود

ADPS2

ADPS1

ADPS0

مقدار تقسیم

0

0

0

2

0

0

1

2

0

1

0

4

0

1

1

8

1

0

0

16

1

0

1

32

1

1

0

64

1

1

1

128

فرکانس ADC = فرکانس اصلی سیستم تقسیم بر مقدار تقسیم

رجیستر های ADCL و ADCH

این رجیستز ها مقدار خروجی تبدیل را در خود ذخیره می کنند .اگر یادتان باشد در رجیستر اول بیت ADLAR را گفتیم بعدا توضیح داده خواهد شد آن بیت اینجا استفاده خواهد شد بدین صورت که اگر بیت ADLAR در رجیستر ADMUX صفر باشد خروجی ADC به ترتیب راست به چپ در رجیستر های ADCL و ADCH ذخیره خواهد شد ولی اگر یک باشد مقادیر از چپ به راست در این دو رجیستر ذخیره خواهد شد.

زمانی که ADLAR=1 باشد

زمانی که ADLAR=1 باشد
رجیستر ADCH , ADCL

زمانی که ADLAR=0 باشد

زمانی که ADLAR=0 باشد
رجیستر های ADCH , ADCL

رجیستر SFIOR: در اینجا نیازی به توضیح این رجیستر نیست فقط باید بیت ADATE یا بیت 5 ADCSRA را صفر قرار دهید تا ایت رجیستر استفاده نشود. در صورتی که نیاز به دانستن این رجستر دارید از طریق نظرات اطلاع دهید.

حال شروع به راه اندازی واحد ADC می کنیم:

مرحله اول:

1- اول باید ولتاژ مرجع را از بین 3 ولتاژ مرجع موجود انتخاب کنیم

2- مقدار تقسیم فرکانسی را مشخص کنیم

3-سپس واحد ADC را روشن کنیم.

تنظیمات اولیه راه اندازی ADC انجام شد.

مرحله دوم خواندن مقدار آنالوگ از یک پایه:

1-پایه مورد نظر را از طریق رجیستر ADMUX انتخاب می کنیم

2-با یک کردن بیت ADSC از رجیستر ADCSRA تبدیل را آغاز می کنیم.

3-منتظر می مانیم تا تبدیل تمام شود این کار با چک کردن بیت ADIF از نظر یک شدن است.

4-بیت ADIF دوباره یک میکنیم.

حال تبدیل تمام شده و مقدار آن در رجیستر های ADCH و ADCL موجود است

حال یک برنامه می نوسیم تا مقدار آنالوگ پایه مثلا 5 را بخواند و در روی LCD نشان دهید

برنامه فوق واحد ADC را روشن فرکانس میکرو را تقسیم بر 128 کرده و فرکانس ADC را برابر آن قرار می دهد (یعنی فرکانس میکرو که در اینجا 8 مگا هرتز می باشد را تقسیم بر 128 می کند که برابر 62500 هرتز یا 62.5 کیلوهرتز می شود) سپس پایه ADC5 را انتخاب کرده عمل تبدیل را انجام داده سپس مقداری که به صورت خودکار در ADCW ذخیره شده را در LCD نمایش می دهد . LCD به پورت D وصل شده است

نحوه تنظیم پورت LCD
نحوه تنظیم پورت LCD

نحوه بستن مدار:

نحوه بستن مدار ADC
نحوه بستن مدار ADC

 دانلود فایل ها و برنامه این پروژه  (لینک کمکی

همان طور که در پروژه بالا مشاهده کردید میکرو ولتاژی که به پایه ADC5 وصل شده را با ولتاژ مرجع که به پایه AVCC وصل است مقایسه کرده و مقدار 10 بیتی آن را که عددی بین 0 تا 1023 خواهد بود را روی LCD نشان می دهد.میکرو زمانی مقدار 1023 را نشان خواهد داد که ولتاژ وصل شده به پایه ADC5 برابر یا بیش از ولتاژ مرجع باشد پس با یک تناسب ساده می توان فهمید چه ولتاژی روی پایه ADC5 وجود دارد:

ولتاژ وصل شده به پایه ADC برابر است با ولتاژ مرجع (5) ضرب در مقدار خروجی ADC  تقسیم بر 1023

Volt ADC5 = (5*614)/1023 = 3V

حال می خواهیم برای راحت کار کردن با ADC توابعی برای آن بسازیم و براحتی در هر پروژه از آن استفاده کنیم.این قسمت در سری دوم آموزش قرار خواهد گرفت

برای دیدن سری دوم این آموزش اینجا کلیک کنید

توجه قسمت زیر به درخواست دوستان اضافه شد:

دوستان سوال کرده بودنند که چجوری با شیفت دادن رجیستر رو تنظیم میکنیم.برای ساده تر شدن این موضوع این قسمت اضافه شد:

حال می خواهیم بیت REFS0 را برابر 1 و بیت REFS1 را برابر 0 قرار دهیم این بیت ها در رجیستر ADMUX قرار دارند به تصویر زیر نگاه کنید در صورتی که REFS0 برابر با 1 و REFS1 برابر با صفر باشد ولتاژ مرجع ADC برابر با ولتاژ پایه AVCC خواهد شد.

رجیستر ADMUX

در آموزش بالا بروش زیر عمل شده بود تا این دو بیت از رجیستر تنظیم شود در این روش از شیفت دادن استفاده شده بود که کمی گنگ بود:

کد اول:

 

همان طور که در تصویر بالا می بینید این دو بیت، بیت 6 و بیت 7 هستند پس می توان به صورت زیر نیز این تنظیم را انجام داد:

کد دوم:

همان طور که میبینید کد دوم فرق چندانی با کد اول خود ندارد و هر دو کد دو بیت مورد نظر را تنظیم میکنند ولی کد دوم تنظیم های قبلی بر روی بیت های 0 تا 5 را بهم میریزد پس کد اول بهتر است ولی حالا شیفت های بالا چه معنی میدهد:

نکته اینجاست که REFS1 همان عدد هفت و REFS0 همان عدد شش می باشد کد فوق در واقع بصورت زیر است:

کد فوق به این معنی می باشد که عدد 0 را هفت بار به چپ شیفت بده یعنی اگر عددی داشته باشیم که بصورت 11111111 باشد بعد از اعمال کد فوق به این صورت در خواهد آمد 01111111

پس کد اول را می توان به این صورت نوشت:

در صورتی که سوالی بود از طریق نظرات این قسمت اعلام نمایید.

59 دیدگاه در “آموزش AVR با کدویژن قسمت 6 مبدل آنالوگ به دیجیتال(1)

  1. سلام:
    من یه مشکلی داشتم وقتی برنامه رواجرامیکنم فقط یک باراندازه گیری میکنه انینم برنامه :#include
    #include
    #include
    #include
    #asm
    .equ __lcd_port=0x12 ;PORTA
    #endasm
    void main(void)
    {
    unsigned char ch;
    char str[16];
    lcd_init(16);
    lcd_clear();
    lcd_putsf(“THE NAME OF GOD”);
    delay_ms(500);
    lcd_clear();
    lcd_putsf(“ADC INIT AND RUN”);
    ADMUX=0b11000011;
    ADCSRA=0b11000111;
    delay_ms(500);
    lcd_clear();
    lcd_putsf(“START!”);
    SFIOR=0xff;
    ch=0b101;
    ADMUX |= ch;
    ADCSRA.6=1;
    while(!(ADCSRA & (1<<ADCSRA.4)));
    ADCSRA.6=1;
    ADCSRA|=(1<<ADCSRA.4);

    sprintf(str,"ADC5 = %d",ADCW);
    delay_ms(1000);
    lcd_clear();
    lcd_puts(str);
    }

    1. سلام
      دقیقا منظورتون رو متوجه نشدم
      ولی اگه میخوایید برنامه مدام اندازه گیری کنه و نشون بده باید قسمت اندازگیری برنامه را درون یک حلقه قرار بدید که برنامه شما این قسمت رو نداره برای راحت تر شدن این کار بهتره یک تابع درست کنید که در قسمت دوم همین آموزش هست در لینک زیر:
      آموزش ADC قسمت دوم
      در صورتی که مشکلی بود مطرح نمایید.

    1. سلام ممنون
      Refs0 و refs1 بترتیب بیت 6 و بیت هفتم از رجیستر ADMUX هستند
      حال می خواهیم REFS0 برابر 1 و REFS1 را برابر 0 قرار دهیم تا پایه avcc به عنوان مرجع انتخاب شود که با دستور شیفت عدد 1 را شش بار به چپ شیفت میدهیم:
      REFS0>>1(توجه:هر کاری کردم شیفت به چپ نشون داده بشه نشد و در مرورگر شیفت به راست دیده میشه پس شما باید شیفت به چپ بنویسید)
      و عدد 0 را هفت بار به چپ شیفت می دهیم:
      REFS1>>0
      که اگر رجیستر ADMUX برابر 00000000 باشد بعد از انجام عملیات فوق بصورت 01000000 درخواهد آمد

      1. سلام میشه میشه دوباره نحوه انتخاب صفر یا یک بودن یک رجیستر با شیفت به صورت کامل توضیح بدی
        من اون قسمت نمیفهمم که چه طوری هفت بار ششیفت میدی چون REFS0>>1 فقط یک بار شیفت دادی که.
        ممنون ازتو.

    1. سلام ممنون.
      ولی این آموزش ترجمه لینکی که شما دادید نیست و فقط عکس ها مشابه هستند و آموزش ها متفاوت.

  2. سلام
    من میخام از دوتا ADC به صورت همزمان و تو هر لحظه استفاده کنم. این برنامه رو می نویسم ولی درست جواب نمیده:
    while (1) {
    a=read_adc(0);
    b=read_adc(1);

    }
    تمام تنظیمات اولیه و تعریف تابع به درستی انجام شده. بعد اینکه اولی رو نوشتم باید کار دیگه انجام بشه؟ مثلا ریست یا چیز دیگه
    ممنون میشم اگه راهنماییم کنید

      1. خیلی ممنون
        نگاه کردم، منم همین کارو کردم. الان یه سوال، این برنامه تو خروجی چی رو نشون میده؟ ولتاژای ورودی رو؟! اونا رو نشون نمیده که؟! من ولتاژا رو عوض می کنم هیچ تغییری تو خروجی اتفاق نمیفته.

        1. خود ولتاژ رو نشون نمیده ولی عددی متناسب با ولتاژ ورودی پایه های مربوطه رو نشون میده که میتونید به سادگی به ولتاژ تبدیل کنید. حالا اگه تغییر میدید ولتاژ رو تغییر نمیکنه شاید مشکل از پروتئوس باشه

  3. پروژه من در مورد ساخت تقویت کننده ecgو دیدن سیگنال قلب (pqrs) در lcdگرافیکی هستش.
    میخواستم بدونم فقط قسمت برنامه نویسی تو کدویژن و پروتیوس چطوری باید باشه ؟ چطوری تبدیل a2dرو باید انجام بدم؟؟
    شمامیتونید برنامه اش رو برام بنویسید؟ قیمتش چقدر میشه؟لطفا به ایمیلم میل بزنید

  4. با سلام

    اگر بخواهم از چند سنسور استفاده کنم ، آیا باید رجیستر sfior را تنظیم کنم، در صورت امکان این رجیستر را توضیح دهید

    با تشکر

  5. سلام
    ممنون از آموزش خوبتون.
    میخواستم ببینم این کاری که شما با شیفت دادن انجام میدید تا بقیه بیت ها به هم نخوره مقداراشون آیا معادل با همین دو خط کد زیر میتونه باشه؟ یا نه؟

    ADMUX|=0b01000000
    ADMUX&=0b10111111

  6. با سلام
    وبسایت بسیار خوبی رو راه اندازی کردین.
    اموزش کد ها تون حرف نداره.
    ممنون.
    خوشحال میشم اگه بتونم باهاتون همکاری داشته باشم.

  7. با سلام و تشکر از آموزش ها.
    اگه میشه تو برنامه نویسی ساده تر و ابتدایی توضیح بدین . چند تا سوال دارم :
    ۱٫چرا از دستور شیفت به چپ یا شیفت به راست استفاده کردین ؟؟ و چرا بصورت باینری و هگز ننوشتین ؟؟ مثلا این خط ADMUX=(1<<REFS0)|(0<<REFS1); چجوری میشه ؟؟ خب همین و با باینری توضیح بدید ؟
    ۲٫ تو این خط ADCSRA|=(1<<ADSC); چرا از یا ( | ) استفاده کردین
    ۳٫ ! به چ معناست
    کلا من با شیفت ها و ADC مشکل دارم لطفا ساذه تر بگین چند تامثال بزنید من همه مطالب بالا رو خوندم ولی بازم گنگ هست برام .!!!!!!

  8. سلام خیلی ممنون از آموزش ها تون یه سوال داشتم اینکه:

    می خواستم ببینم چه جوری میشه adc های atmega16 رو در یک میلی ثانیه خوند یعنی سرعت نمونه برداری adc یک میلی ثانیه باشه (در یک دقیقه ۶۰۰۰۰ بار adc خونده بشه) . (البته من با کد ویزارد کار میکنم)
    ممنون میشم از راهنماییتون…

  9. سلام
    خیلی ممنون از اموزشهای خوبتون
    توی این nوخط مشکل دارم توی فهمش میشه یکم توضیح بدین
    ch=0b101; // پایه ۵ را جهت تبدیل انتخاب می کنیم
    ADMUX |= ch; //پایه ۱ را از رجیستر مربوطه انتخاب می کنیم (این قسمت بایه ی ۵ انتخاب نمیشه؟)

  10. سلام خسته نباشید.
    مطالب عالی بود.
    فقط یه سوال داشتم:
    شما گفتین در این پروژه ولتاژ مرجع را پایه AVCC در نظر گرفتیم پس چرا پایه AREF را هم به پنج ولت متصل کردین؟
    نمیشه پایه AREF را بدون اتصال باشه؟
    ممنون میشم اگه جواب بدین.

  11. سلام
    سوال من اینه که چرا از تنظیمات avrcodevision استفادع نمی کنید و با استفادع از رجیستر ها کار می کنید

    1. هدف از آموزش کدویژن نحوه یاد گرفتن avr از پایه بود و اگه از تنظیمات کدویزارد استفاده کنید کار کردن با رجیستر ها رو یاد نخواهید گرفت.همچنین با کدویزارد فقط تنظیمات اولیه رو میشه تنظیم کرد و اگه بخواهید در وسط برنامه رجیستری رو تغییر بدید باید بصورت دستی کار کنید.

  12. هر چی از خدا میخوای ازت بگیره به جاش صد برابرش و بهت بده…
    پدر من درومد سر adc. ولی الان کامل یاد گرفتمش

  13. سلام و خسته نباشید سوالی داشتم برای تولید با کیفیت تر در خروجی adc درون میکرو ولتاژ مرجع باید کوچک تر گرفته بشه حداقل مقدارش می تونه چند باشه ؟

  14. بسیار عالی
    من نمیدانستم میتوان در نرم افزار پرتیوس از امکان A2D که در میکرو AVR هست در شبیه سازی استفاده کرد
    شما به من خیلی کمک کردید
    آدرس این صفحه را در لیست استاد های من( http://listostad.blogfa.com/ ) ( به عنوان تشکر ) قرار میدهم .

    ممنونم
    مبینی EP3MIR

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

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