بريم سراغ آموزش استفاده از ADC:
ADC چيست: مخفف ANALOG TO DIGITAL CONVERTER که به معناي تبديل کننده مقدار آنالوگ به ديجيتال هست.که روي بسياري از مدل هاي ميکروهاي PIC موجوده. 
رزوليشن در ADC: دقت تبديل ولتاژ آنالوگ به مقدار ديجيتال رو رزوليشن ميگن. مثلا اگر يک ADC رزوليشن 8 بيت داشته باشه به اين معناست که مقدار 5 ولت (يا حداکثر مقدار قابل اندازه گيري حالا هرچي که باشه) تقسيم بر 255 (مقدار کامل دسيمال 8 بيت) ميشه. که اگر اين تقسيم رو انجام بديم 5/255=0.0196 يعني اين ADC ميتونه ولتاژ مثلا 0 تا 5 ولت رو با دقت 0.196 ولت اندازه گيري کنه و به صورت يه عدد بين 0 تا 255 به ما برگردونه که 0 يعني 0ولت و 255 يعني 5 ولت (پس مشخصا اگر ADC مقدار 127 رو برگردونه ولتاژ 2.5 ولته)


در خانواده هاي PIC در سري 12F و 16F ماژول هاي ADC 8 يا 10 بيتي موجود داره. در يک سري از مدل هاي 18F ها يا مدلهاي بالاتر ADC 12 و 16 بيتي هم هست 

ما با ميکروي 18F452 ميخوايم ADC رو راه اندازي کنيم. و اين ميکرو روي 8 تا از پين هاش قابليت ADC رو داره
در عکس زير ميتونيم اين پايه هارو ببينيم:


کنار بعضي از پايه ها نوشته شده AN. اين پايه ها ميتونن ADC باشن. 
اين پايه ها بوسيله يک شماره از هم متمايز ميشن که به اون کانال ميگن. مثلا پايه شماره 8 ميکرو که پين E0 هستش کنارش نوشته شده AN5 يعني کانال 5 از ماژول ADC (دقت کنيد که در اين ميکرو تنها يه ماژول ADC وجود داره و اين 8 کانال روي همين ماژول مالتي پلکس ميشه پس در عين واحد فقط از يکي از اين پايه ها ميشه به عنوان ADC استفاده کرد)

دقت کنيد که پايه شماره 6 adc نيست!!

خب حالا ما در محيط پروتئوس ميخوايم يک ولتاژ به يکي از اين پايه ها بديم و اون رو اندازه گيري کنيم و روي lcd نمايش بديم:


حالا بايد بريم سراغ کامپايلر ccs و اينکه توي کامپايلر بايد چکار کنيم

با استفاده از دستور زير ميتوانيم رزوليشن adc را انتخاب کنيم:
[code=c]#device ADC=10[/code]

در دستور بالا adc در حالت 10 بيتي قرار گرفت. براي اين ميکرو ميتونيد از عدد 8 هم استفاده کنيد و در اين صورت adc ميکرو در حالت 8 بيتي قرار ميگيرد که دقت کمتري نسبت به 10 بيتي داره

حالا بايد داخل برنامه و قبل از اينکه از adc استفاده کنيد کلاک اون و پورت هايي که ميخوايد از اونا به عنوان adc استفاده کنيد رو انتخاب کنيم

بوسيله تابع زير ميتونيد کلاک adc رو مشخص کنيد:
[code=c]
setup_adc( ADC_CLOCK_INTERNAL );
[/code]

که در اينجا بجاي آرگومان تابع عبارت ADC_CLOCK_INTERNAL قرار گرفته.
کلا اين کلاک زمان نمونه برداري adc رو مشخص ميکنه که اينجا چون زياد نرخ نمونه برداري مهم نيست از گزينه ADC_CLOCK_INTERNAL استفاده کرديم. 
کمي پايين تر مشخص ميشه که چه گزينه هاي ديگه اي وجود داره براي اين تابع

بوسيله دستور زير ميتونيم کانال هاي adc که مورد استفاده قرار ميگيرن رو تعريف کنيم:
[code=c]
setup_adc_ports(AN0);
[/code]

که اينجا در آرگومان تابع عبارت AN0 قرار گرفته چون در اين مثال فقط از اين کانال استفاده ميکنيم. در ميکروهاي قديمي انتخاب هاي محدودي براي اين قسمت وجود داره مثلا نميتونيد فقط از AN0 و AN1 به عنوان آنالوگ استفاده کنيد و مجبوريد کانال AN3 رو هم ADC بکنيد!
اما در ميکرو هاي جديد مثلا 16F1829 يا 18F46K80 هر پايه رو که بخوايد ميتونيد استفاده کنيد
براي اين که گزينه هاي قابل انتخاب رو ببينيم به ويزار CCS ميريم 

ويزار رو که باز کرديد از منوي سمت چپ به بخش ANALOG بريد

(اين ويزارد مال CCS ورژن 5 هستش)

در قسمت 1 ميتونيد رزوليشن رو انتخاب کنيد 
در قسمت 2 ميتونيد کلاک ADC رو انتخاب کنيد 
در قسمت 3 هم اون انتخاب هايي که گفتم رو ميتونيد ببينيد. مثلا در گزينه 7 ميتونيد يه ولتاژ به پايه A3 بديد که اين ولتاژ به عنوان ولتاژ رفرنس منظور ميشه. ابن کار براي زماني استفاده ميشه که ولتاژي که ميخوايد اندازه بگيريد بيشتر از مثلا 2 ولت نيست. در اين حالت ميتونيد با انتخاب اين گزينه و اعمال ولتاژ 2 ولت به پايه A3 ماکزيمم مقدار قابل اندازه گيري توسط ADC رو روي 2 ولت تنظيم کنيد و دقت کار رو بالاتر ببريد. با انتخاب گزينه هفتم پايه هاي A0 و A1 به عنوان پايه هاي ADC در نظر گرفته ميشن.

بعد از دستورات مربوط به تنظيمات بايد ببينيم با چه توابعي ميتونيم از ADC مقدار رو بگيريم.
قبل از گرفتن مقدار از ADC بايد اول مشخص کنيم که از کدوم کانال ميخوايم مقدار رو بگيريم که چون ما فقط کانال AN0 رو به عنوان ورودي ADC تنظيم کرديم خود ميکرو مقدار رو از پايه A0 ميخونه اما اگر چند پايه رو به عنوان ورودي در نظر بگيريم حتما بايد کانال مورد نظر رو قبل از قرائت مقدار مشخص کنيم

با دستور زير ميتونيم کانال ADC رو مشخص کنيم:
[code=c]
set_adc_channel(7);
delay_us(10);
[/code]

مثلا اينجا کانال 7 انتخاب شده 
اون تاخير 10 ميکرو ثانيه هم براي اينه که مالتي پلکسري که قراره بين کانال هاي مختلف سوئيچ کنه فرصت اين کار رو داشته باشه

حالا ديگه ميتونيم با دستور زير مقدار ADC رو بخونيم:
[code=c]
adc_value = read_adc();
[/code]

در اينجا مقدار ADC رو خونديم و توي متغير adc_value قرارش داديم 

حالا اگر رزوليشن رو روي 8 بيتي تنظيم کرده باشيم مقدار adc_value مقداري بين 0 تا 255 و اگر 10 بيتي تنظيم کرده باشيم مقداري بين 0 تا 1023 رو داره
پس موقع تعريف متغير (اينجا adc_value) حواستون به 8 يا 16 بيتي بودنش باشه 

اين مقداري که خونده شده يه مقدار ديجيتاله و دقيقا خود ولتاژ نيست. که خيلي راحت ميشه اون رو به ولتاژ تبديل کرد با فرمول زير:
[code=c]
volts =adc_value * 5/1023.0; [/code]

5 بخاطر اينه که الان در مثال ما رفرس ADC روي 5 ولته و در واقع ماکزيمم مقدار قابل اندازه گيري 5 ولته. 1023 هم بخاطر اينه توي مثال ما رزوليشن 10 بيت انتخاب شده. و تقسيم اين دو عدد بخاطر اينه که ببينيم هر بيتي که تابع read_adc برميگردونه ارزشش چند ولته 
volts هم يه متغير اعشاريه

اينم فايل شامل سورس برنامه هگز و شماتيک :
http://s5.picofile.com/file/8151577892/ADC.rar.html