آموزش AVR با کدویژن قسمت ۸ مبدل آنالوگ به دیجیتال(۲)+ویرایش شد

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

همان طور که می بینید نام تابع را read_adc تعریف کرده و نوع آن را unsigned int تعریف کردیم و برای ورودی یک پارامتر از نوع unsigned char با نام adc_input تعریف کردیم که این پارامتر ورودی همان شماره پایه ADC خواهد بود که عددی بین ۰ تا ۷ است حال به تعریف دستورات داخل تابع می پردازیم که کد هایی که در قسمت شش تعریف کرده بودیم را در اینجا استفاده می کنیم

همان طور که میبینید دستورات آموزش قسمت ۶ را عینا در اینجا کپی کردیم با این تفاوت که در خط ۶ ورودی را مستقیما به رجیستر مربوطه اعمال کردیم و در خط ۱۰ مقدار خوانده شده ADC را با دستور return باز گرداندیم برنامه کلی و نحوه استفاده:

همان طور که دیدید تابع adc را قبل از تابع اصلی تعریف کردیم و در هر جا که نیاز باشد نام تابع و شماره پایه مورد نظر را می نویسیم تا مقدار آن پایه را برایمان ظاهر کند در بر نامه بالا پایه ۱ را به تابع ارسال کردیم شما می توانید اعداد ۰ تا ۷ را به تابع ارسال کنید مقدار adc هر پایه را بخوانید دانلود برنامه و فایل پروتئوس (لینک کمکی)

نوشتن تابع برای مبدل ADC
نوشتن تابع برای مبدل ADC

قسمت اضافه شده بعد از ویرایش شاید شما هم با این دستورات مشکل پیدا کنید که عملگر =| یعنی چه و برای چه چیز در بیشتر دستورات بالا استفاده شده همان طور که در قسمت های قبل گفته شد نام این عملگر   عملگر انتساب OR بیتی می باشد وبصورت فشرده شده برای کاهش حجم برنامه نویسی به صورت زیر نوشته می شود:

که در اصل عمل زیر را انجام می دهد:

که علامت | به معنی OR یا جمع است به طور مثال:

همان طور که دیدید a و b با هم جمع شده اند حال در اینجا از این عملگر به صورت زیر استفاده شده:

در اینجا ما قصد داریم مقدار بیت چهارم یا بیت ADIF را از رجیستر ADCSRA برابر مقدار یک قرار دهیم . به این صورت عمل کردیم که عدد ۱ را به مقدار ADIF یا ۴ به سمت چپ شیفت دادیم که حاصل داخل پارانتز به این صورت تغییر کرد.

بعد از به دست آمدن مقدار داخل پارانتز آن را با مقدار رجیستر ADCSRA جمع می کنیم : مقدار رجیستر ADCSRA هر مقداری می تواند باشد ولی برای فهم بهتر مقدار۱۲۸ یا مقدار باینری ۱۰۰۰۰۰۰۰   را برای آن در نظر گرفتیم:

که نتیجه همان یک شدن بیت چهارم رجیستر ADCSRA  بدون تغییر در سایر بیت های آن شد که اگر بجای =| از = تنها استفاده می شد همه بیت های رجیستر تغییر کرده و صفر می شدند و فقط بیت چهار آن یک می شد که باعث به هم ریختن تنظیمات قبلی روی بیت های این رجیستر می شد

37 دیدگاه در “آموزش AVR با کدویژن قسمت ۸ مبدل آنالوگ به دیجیتال(۲)+ویرایش شد

  1. سلام. ممنون از مطالب مفیدی ک قرار دادید. من یه قسمتی رو متوجه نشدم اون هم اینکه چرا در عباراتی مثل زیر به جای” =l ” فقط “=” قرار ندادید؟
    ;(ADCSRA |= (1<<ADIF

  2. سلام ی سوال دارم
    من ی مدار دو قسمتی ساختم(البته هنوز پیاده نکردم تو پروتیوس و برنامه نویسی ام)
    قسمت اول اتمگا۱۶ هست که ولتاژ آنالوگ ی سنسورگازو به دیجیتال تبدیل میکنه بعد با فرستنده ی RF اونو میفرسته به مدار دوم
    قسمت دوم اتمگا۱۶+ گیرنده RF که اون ولتاژ دیجیتالو میگیره و باید روی LCD نمایش بده که مشکل اینجاست که عدد نمایشی که مثلا باید ۱۵۰۰ باشه
    مداوم تغییر میکنه به ۱۵۰۰ و ۰۰۰۰ و ثابت نیست بین جواب و صفر مداوم تغییر میکنه.
    چیکار کنم؟
    meisamfeli71@gmail.com

  3. سلام.خسته نباشید
    ممنون از آموزشتون واقعا عالیه برنامه رو خط به خط توضیح دادین منتظر مطالب بعدی هستم.با تشکر

  4. سلام خسته نباشید
    آموزشاتن خیلی خیلی مفیدن
    می شه لطفا نحوه اتصال کار حافظه به میکرو و انتقال اطلاعات از میکرو به کارت حافظه رو هم توضیح بدید.
    یه مثال باتوضیح مثل همین نمونه آموزشاتون بذارید عالیه

  5. سلام من آموزش های شما را مو به مو پیگیری می کنم و احساس می کنم بسیار عالی مطالب توضیح داده می شه با تشکر از شما منتظر مطالب بعدی هستم

  6. سلام
    ممنون ازمطالبی که مینویسید با بیان ساده و روان همه مطالبو توضیح دادین.
    چرا ادامه نمیدید؟
    منتظر مطالب بعدیتون هستم.
    با تشکر.

  7. من آموزش های سایتای دیگه رو هم میخونم
    هیچ کدوم به این کاملی و به این زیبایی و ظرافت نیست.
    خداقوت واقعا.
    لطفا باز هم آموزش ها رو ادامه بدین..

  8. سلام
    ببخشین من یه پروژه دارم دررابطه با lcd اما نمیدونم برنامه کدویژنشو بنویسم لطفا کمکم کنین”بافعال نمودن پایه adc وگرفتن ولتاژ انالوگ ازیک پتاسیومتر یک دیودنوری روشن یا خاموش میشود وضعیت دیود روی lcd نشون بدین”اينم سوال پروژمه

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

    1. سلام
      احتمالا مشکلی در نحوه بستن مدار وجود دارد اینطور که من از گفته های شما متوجه شدم چون با تغییر خروجی سنسور گاز برنامه بهم میریزد بیشتر به مدارات شما ربط دارد

  10. سلام ،میشه این برنامه رو خط ب خط توضیح بدید؟واقعا ممنون از اموزشاتون
    ADMUX=adc_input | ADC _VREF_TYPE &0xff
    Delay_us(10
    ADCSRA|=0x40
    While ( (ADCSRA&0x10)==0
    ADCSRA|=0x10
    return ADCW
    تایپ کردم اشکال پرانتز و سیمیکالن نگیرین فقط میخوام بدونم این خطها تو برنامه معنیش چیه ،واسه شما برنامتون فرق داره با این،خواهش میکنم توضیح بدید
    ممنون

  11. سلام
    ممنون از آموزش خوبتون

    سوالم اینه که چرا تابع read_adc رو از جنس unsigned int تعریف کردید؟ مگر ADCW ده بیتی نیست؟ اینجوری که نمیشه با هشت بیت ارسالش کرد؟

    1. unsigned int یک متغییر ۲ بایتی یا ۱۶ بیتی هست که مقداری بین ۰ تا ۶۵۵۳۵ رو میتونه تو خودش جا بده حالا متغییر adc یک متغییر ۱۰ بیتی هستش که مقداری بین ۰ تا ۱۰۲۳ داره پس مشکلی پیش نمیاد.

  12. سلام ممنون از اموزش خوبتون
    در انتها شما نوشتید که مقدار در ADCW ذخیره میشه مگه نباید توی رجیستر ADCH یا ADCL ذخیره بشه ؟؟
    اگه بخوایم همزمان چندتا بایه رو وصل کنیم و نمونه گیری کنیم متغیرها رو کجا ذخیره میشه

    1. adcw مقدار کلی رو در مبنایی ده دهی به ما میده و همون مقدار بیتی که ذخیره شده در دو رجیستر ADCL و ADCH به ما نشون میده.
      ما همزمان نمیتونیم چند پایه رو باهم اندازه گیری کنیم چون میکرو فقط یک واحد مبدل داره و اون چند پایه ای که هست زمان تبدیل ما با رجیستر ها انتخابش میکنیم و اون پایه به واحد adc وصل میشه و مقادیر در همون دو رجیستر ADCL وADCH ذخیره میشه
      و چون سرعت تبدیل بالا هست به نظر اینطور میاد که همزمان تبدیل انجام میشه و میتونیم مثلا پنج تا متغییر تعریف کنیم و ولتاژ هر پایه رو در این متغیر ها ذخیره کنیم

    1. با توجه به سنسورتون باید تبدیل کنین
      مثلا در lm35 به ازای هر درجه سانتی گراد افزایش دما ولتاژ در پایه خروجی ۱۰ میلی ولت(یا ۰٫۰۱ ولت) افزایش پیدا میکنه که با یه تناسب ساده میشه دما رو بدست بیارین که کمترین ولت صفر و بیشترین ولت خروجی ۱۰۰ هست
      پس هر زمان ولتاژ خروجی ۱ ولت بود یعنی دما ۱۰۰ درجه هست و هر وقت صفر بود دما صفر درجه هست
      و چون ولتاژ ورودی رو به پایه adc میکرو وصل میکنیم و adc نیز عددی بین ۰ تا ۱۰۲۳ رو که به ازای ولتاژ ۰ ولت تا ۵ ولت رو میده
      برای تبدیل هم این تناسب رو میشه نوشت: مقدار خوانده شده از adc رو ضرب در ۵۰۰۰ میلی ولت(همون ۵ ولت) تقسیم بر ۱۰۲۳ مساوی است با مقدار میلی ولت که به پایه adc اعمال میشه که تقسیم بر۱۰۰ بکنی میشه همون درجه سانتی گراد (خیلی بد توضیح دادم تو قیمت نظرات نمیشه تناسب رو نوشت اگه متوجه نشید بگید تو پست بعدی بزارم تو سایت)
      یا به عبارت دیگه اگه عدد خوانده شده در adc رو ضرب در ۰٫۴۸۸۷ بکنید دما بدست میاد
      بطور مثال هنگام اجرای تابع read_adc عدد ۵۰ بدست اومد ضرب در عدد ۰٫۴۸۸ بکنید میشه حدودا ۲۴٫۵ درجه

  13. سلام و خسته نباشید بابت مطالت بسیار مفیدتون. سوال داشتم از خدمتتون . فرض کنید ۶۰ عدد کلید دارم که میخوام به میکرو بدم و با فشردن هر کلید یه جمله خاص نمایش داده بشه . چون تعداد ورودی ها زیاد هست فکر کنم با adc اینکارو انجام بدم بهتره ولی نمیدونم چجوری روی ال سی دی نمایش بدم . ممنون میشم راهنماییم کنید.

  14. اقا سلام بسیر جامع و خوب بود.
    فقط سوال
    الان من نمونه گیریو انجام دادم و تبدیل هم کردم. الان میخوام عددی که داره بهم نشون میده رو تبدیلش کنم به یک عدد کوچک تر یعنی مثلا اگه الان عدد ۱۰۲۳ هست روی ال سی دی عدد ۲۰ رو برای من نشون بده دقیقا عمل تقسیم رو کجای برنامه و چجوری باید قرار بدم؟؟

  15. سلام مهندس خوبید من نیاز دارم ۴ تا پرت A TO D بخونم اما برنامه امم مشکل پیدا کرده چطوری از طریق ۱ ریجستر ۴ تا پرت رو بخونم

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

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