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

یکی از لوازم جانبی داخلی در این نوع میکروکنترلر تبدیل سیگنال آنالوگ به دیجیتال (ADC) میباشد.
این مبدل کننده ها در بعضی پهنای 8 بیت و در بیشتر آنان پهنای 10 بیت دارند. طبق گفته سازنده خطای آنان کمتر از نصف کمترین بیت است( 1/2 LSB ).
در بعضی از این نوع ولتاژ مبنا با رفرنس را هم میتوان خود تعیین نمود.
این تبدیل کننده ها را معمولا میتوان در میکروکنترلر ها بصورت چند کانال هم استفاده کرد, با توجه به اینکه در یک زمان واحد نمیتوان از کانالهای متعددی استفاده کرد.
کانالها را میتوان بصورت سری با پشت سر هم به مدار ADC متصل کرد.
در این نوشته من از میکروکنترلر PIC18F2550/4055 استفاده میکنم ولی اصول آن برای انواع دیگر نیز صادق میباشد.
در میکروکنترلر فقط پورت یا پایه هایی که با ANx مشخص شده اند را میتوان در رابطه با ADC استفاده کرد, حرف A نشاندهنده آنالوگ بودن در این نوع از پایه ها است.
برای استفاده از تبدیل کننده باید اول آنرا تنظیم کرد, برای این کار 3 مکان با رجیستر 8-بیتی وجود دارد.
این مکانها ADCON0 , ADCON1 , ADCON2 نام دارند.

ADCON0 : ADCON0

  • بیت صفر (ADON) برای فعال کردن ADC بکار میرود.
  • بیت یک (GO/DONE) برای دستور شروع تبدیل است بشرطی که بیت قبلی (ADON) روشن باشد.
    مایکروچیپ تاکید میکند که این 2 بیت را نباید در یک دستور استفاده کرد, بدین معنی که دستور اول برای فعال کردن ADC و دستور بعدی باید برای شروع کردن تبدیل باشد.
  • بیتهای 2 تا 5 (CHS3 ... CHS0) شماره کانال را مشخص میکنند, در نوع میکروکنترلر 28-پایه از 10 کانال و نوع 44-پایه از 13 کانال میتوان استفاده کرد. این کانالها یا پایه ها با ANx مشخص شده اند.
  • ADCON1 : ADCON1

  • بیتهای 0 تا 3 (PCFG3 ... PCFG0) برای تنظیم این پایه های خارجی (ANx) میباشد. خصوصیت این پین ها (آنالوگ یا دیجیتال بودن) بعد از یک ریست, بستگی به اینکه آیا در تنظیمات اصلی میکروکنترلر (Configuration Bits) بیت (CONFIG3H.1:PBADEN) فعال باشد یا نه, تفاوت دارد, بدینصورت که یا همگی دارای خصوصیت آنالوگ هستند یا نیمی از آنان.
    در حالت معمولی (default) این بیت (PBADEN=1) است و این یعنی تمام پایه هایی که دارای نامهای ANx هستند بصورت آنالوگ قرار دارند.
  • بیتهای (VCFG1/VCFG0) برای تعیین منبع ولتاژ رفرنس با ولتاژ مبنای ADC استفاده میشود.
    این ولتاژ با میتواند خارجی باشد ( در روی پایه های AN2 و AN3 ) یا داخلی که مساوی ولتاژ روی میکروکنترلر ( معمولا 5 ولت ) است.
    اگر از ولتاژ خارجی استفاده شود پایه AN2 پتانسیل منفی ( Vref- ) و پابه AN3 پتانسیل مثبت ( Vref+ ) آنرا باید داشته باشد.
    در بعضی از انواع PIC که دارای مقایسه کننده (Copmerator) هستند, یک ولتاژ رفرنس قابل تغییر نیز وجود دارد که میتوان از آن استفاده کرد.
  • ADCON2 : ADCON2

  • بیتهای (ADCS2 ... ADCS0) پهنای پالس تبدیل کننده ( TAD ) را بر اساس اوسیلاتور مدار تعیین میکنند. این زمانی است که ADC برای تبدیل یک بیت احتیاج دارد. برای تمام 10-بیت به 11 عدد از این زمان نیاز دارد.
  • بیت های (ACQT2 ... ACQT0) مقدار زمانی را تعیین میکنند که باید سپری شود تا ولتاژ آنالوگ ما در خازن داخلی ADC شارژ شود ( acquisition time ), این مدار نمونه برداری و نگهداری کردن است .( Saple and Hold ) اگر این زمان رعایت نشود ADC ولتاژ اشتباهی را تبدیل میکند!
  • بیت ADFM عدد حاصل تبدیل را شکل بندی میکند, زیرا عدد نهایی در 2 بایت قرار دارد و میتوانیم توسط این بیت تعیین کنیم که آیا از سمت راست خوانده شود یا از سمت چپ.
  • مکانهای ADRESH:ADRESL عدد حاصل از تبدیل را نگهداری میکنند.
    برای استفاده بطور کلی باید :
      1. تنطیم کنیم
      2. بمقدار زمان نمونه برداری صبر کنیم
      3. تبدیل را شروع کنیم , منتطر پایان کار ADC باشیم
      4. عدد حاصل را بخوانیم
      5. در اینجا بستگی به اینکه آیا تنظیم جدید لازم است یا خیر و اینکه آیا بصورت متوالی میخواهیم انداره گیری کنیم به مرحله 1 یا 2 میرویم.

    بالا پایین

    مشخصات ADC :
    برای استفاده صحیح از ADC باید مشخصات آنرا بدانیم.

    ADC Model این مدل ADC است.
    در قسمت پایین سمت راست دیاگرام رابطه مقاومت کلید داخلی (Rss = Sampling Switch) با منبع تغذیه داده شده است. بر این اساس با منبع تغذیه 5 ولتی, حداکثر مقاومت داخلی کلید برابر 2 کیلو اهم است.
    طبق گفته سازنده, مقاومت داخلی یا امپدانس منبع ولتاژ آنالوگ نباید از 2500 اهم بیشتر باشد زیرا باعث یک افت ولتاژ( Offset ) خواهد شد و این از دقت مدار میکاهد.
    این افت ولتاژ بدلیل تغییر ٍثابت زمانی که به خازن ورودی و مقاومت منبع آنالوگ مربوط است بوجود میاید.
    اگر نتوان در مقاومت داخلی منبع آنالوگ تغییری بوجود آورد باید از یک تقویت کننده عملیاتی بعنوان تبدیل کننده امپدانس استفاده کرد.
    Buffer این نمونه یک تبدیل کننده امپدانس است. مقاومت خروجی آنها در حالت ایده آل نزدیک صفر است.
    مقاومت R برای این است که در عین حال بتوان از ANx بعنوان I/O معمولی نیز استفاده کرد.
    مقدار آن حدود 1 کیلو اهم است, در این صورت ADC این مقاومت را میبیند که کمتر از حداکثر مجاز (2.5 کیلو اهم) میباشد.


    ADC Formel بر طبق این مدل شرکت مایکروچیپ معادلات زیر را برای محاسبه زمان نمونه برداری ( acquisition time ) ارایه میدهد.
    در این فرمولها مقادیر داده شده را بغیر از درجه هوای محیط و مقاومت منبع آنالوگ را نمیتوانیم تغییر دهیم. این مقدار TACQ برای درجه هوای 85 درجه و حداکثر مقاومت منبع آنالوگ محاسبه شده. و حداقل زمانی است که باید قبل از شروع تبدیل ( GO = 1 ) صبر شود تا اندازه گیری دقیق و بدون خطا شود.


    ADC Formel این تصویر زمان بندی ADC است.
    با دانستن زمان TACQ و این نکته که ADC برای 10-بیت به
    T = TACQ + TAD + (11xTAD) نیاز دارد میتوان حداکثر فرکانس سیگنال ورودی را محاسبه کرد.

    t = TACQ + TAD + (11*TAD)
    t = 2,45µS + 1µS + (11*1µS)
    t = 14,45µS

    با توجه به اینکه برای تبدیل یک سیگنال دیجیتال به آنالوگ حداقل به 2 نمونه (Sample) احتیاج داریم, حداکثر سیگنال ورودی برابر است با :
    f signal = 1/(2*14,45)µS = 34,602 KHz
    این حداکثر مرزی است که اگر زمان نمونه برداری درست انتخاب شود میشود فرکانس سیگنال سینوسی (متواتر) را بدست آورد ولی شکل سیگنال از بین میرود. برای اینکه شکل واقعی سیگنال را داشته باشیم به تعداد زیادتری از نمونه ها (Sample) نیاز داریم. این نکته مهم است اگر بخواهیم از این ADC برای ساختن یک اسیلوسکوپ دیجیتالی استفاده کنیم.
    همچنین میتوان زمان نمونه برداری را بصورت اتوماتیک نیز انچام داد, این کار ما را از داشتن مقداری از کد یا دستوراتی که برای این تاخیر لازم است بی نیاز میکند.
    برای اینکار از بیتهای (ACQT2 ... ACQT0) در ADCON2 استفاده میکنیم. حداقل این زمان برابر با
    ACQT2:ACQT0 = 001 = 2TAD میباشد.
    اگر بخواهیم زمان TACQ را خود تعیین کنیم باید این 3 بیت را پاک کنیم. (ACQT2:ACQT0 = 000)


    بالا پایین

    اکنون با مثالی از این اطلاعات استفاده میکنیم. داده های ما بدین قرار است:
    - اوسیلاتور مدار 16 مگاهرتز
    - پایه مورد نظر AN0
    - ولتاژ مبنای اندازه گیری Vref همان ولتاژ تغذیه

    اول این پایه را در حالت ورودی (Input) قرار میدهیم. این پایه در پورت A قرار دارد و باید در حافظه یا رجیستر TRISA بیت مربوط به آنرا فعال کنیم. TRISA.TRISA0 = 1
    حالا باید خود ADC را تنظیم کنیم:
    در ADCON0 بیتهای CHS3:CHS0 را پاک میکنیم, CHS3:CHS0 = 0000 -> Channel 0 (AN0)
    در ADCON1 بیتهای VCFG1:VCFG0 را پاک میکنیم VCFG1:VCFG0 = 0000 -> Voltage Reference = Vdd/GND

    ADC Port cfg بر طبق این جدول بیتهای PCFG3:PCFG0 را تنظیم میکنیم.
    اینجا میخواهیم که فقط AN0 خاصیت آنالوگ داشته باشد.
    PCFG3:PCFG0 = 1110 -> only AN0 is analog



    ADC ADFM در ADCON2 بیت ADFM بصورت سمت راست فرم بندی میکنیم.
    ADFM = 1 -> Right justified
    این یعنی عدد حاصل از اندازه گیری (10-بیت) در سمت راست یک عدد 16 بیتی قرار دارد.



    در اینجا چون اوسیلاتور ما 16 مگاهرتز است باید گزینه Fosc/16 را برای TAD انتخاب کنیم.
    زیرا حداقل زمان برای TAD نباید از 0.8 میکروثانیه کمتر باشد. (datasheet)
    ADCS2:ADCS0 = 101 -> Conversion Clock TAD

    و چون میخواهیم که زمان نمونه برداری اتوماتیک باشد گزینه 2TAD را انتخاب میکنیم.
    ACQT2:ACQT0 = 001 -> Acquisition Time = 2 TAD
    با این انتخاب دمای محیط میتواند تا حدود 63 درجه بالا رود و حداکثر مقاومت منبع آنالوگ هم 2,5 کیلو اهم بماند!.

    بالا پایین

    تنضیمات بپایان رسید حالا میتوانیم ADC را فعال کنیم و آماده اندازه گیری هستیم.
    شروع اندازه گیری با Go = 1 است.
    در اینجا برای اطلاع از بپایان رسیدن اندازه گیری 2 روش وجود دارد, یکی اینست که این بیت (GO) را بطور مرتب چک کنیم (polling) و هنگامی که صفر میشود یعنی اندازه گیری تمام شده و میتوانیم عدد حاصل را بخوانیم.
    دومین روش استفاده از اینترراپت است, زیرا ADC زمانی که بپایان تبدیل میرسد بیت ADIF را فعال میکند.
    مزیت استفاده از اینترراپت اینست که در بین زمان شروع و پابان میتوانیم کارهای دیگری نیز انجام دهیم, توجه کنید که زمان یک اندازه گیری تقریبا برابر است با 15 میکروثانیه, و در این زمان با اوسیلاتور 16 مگاهرتزی میتوان 60 دستور را انجام داد!
    برای استفاده از اینترراپت باید در رچیستر INTCON بیت های GIE/GIEH P و EIE/GIEL را فعال کرده باشیم.
    ارجهیت (Priority) اینترراپت را در رجیستر IPR1 توسط بیت ADIP مشخص میکنیم.
    در رجیستر PIE1 با فعال کردن بیت ADIE اینترراپت آماده استفاده است.
    در قسمت اینترراپت با چک کردن بیت ADIF میتوان عدد نتیجه را خواند.
    این یک نمونه از کد میتواند باشد:
       
    ;#################################################
    Init_ADC:
    bsf     TRISA,0,ACCESS    ; RA0/AN0 = Input , پین بصورت ورودی
    clrf    ADCON0,ACCESS     ; CHS3:CHS0= 0000 ,  انتخاب کانال 0 , ADON=0 , GO/#DONE=0 
    movlw   0x0E              ; b'00001110'  , VCFG1:VCFG0 = 0 , PCFG3:PCFG0 = 1110
    movwf	ADCON1,ACCESS     ; Vref = Vdd-GND ولتاژ مبنا برابر 5 ولت , AN0 = آنالوگ 
    movlw   0x1D              ; b'10001101' , ADFM = 1, ACQT = 2TAD, TAD = Fosc/16
    movwf	ADCON2,ACCESS
    bsf     ADCON0,0,ACCESS   ; ADON = 1 , ADC روشن
    bsf     ADCON0,1,ACCESS   ; GO/#DONE = 1 , شروع اندازه کیری
    ;#################################################
      
      
    اگر بصورت Polling منتظر نتیجه باشیم میتوان بدینصورت باشد:
    در اینجا برنامه آنقدر صبر میکند تا بیت (GO/DONE = 0) باشد و بعد به ادامه برنامه میپردازد.
       
    ;#################################################
    loop:
    btfsc   ADCON0,1,ACCESS   
    bra     loop 
    movf	ADRESL,W           ; Read Result Low Byte
    movwf	Result_Low
    movf	ADRESH,W           ; Read Result High Byte
    movwf	Result_High
    ;#################################################
     
      
    اگر در Interrupt منتظر نتیجه باشیم, میتواند بدینصورت :
       
    ;#################################################
    ISR:                       ; Interrupt Service Routine
    .
    .
    ADC_ISR:                   ; Begin of ADC Interrupt
    btfss   PIR1,ADIF,ACCESS   ; Check ADIF 
    bra     ISR_do             ; Jump if NOT ADIF aktive
    movf	ADRESL,W           ; Read Result Low Byte
    movwf	Result_Low
    movf	ADRESH,W           ; Read Result High Byte
    movwf	Result_High
    bcf     PIR1,ADIF,ACCESS   ; clear ADC Interrupt flag 
    ADC_ISR_End:               ; Service other Interrupt
    .
    .
    retie                      ; Return from Interrupt
    ;#################################################
     
      
    ناگفته نماند که در این نوع از میکروکنترلر, ADC را میتوان توسط قسمت CCP2 و یک اتفاق ویژه یا حالت بخصوصی (Special Event Trigger) بطور اتوماتیک نیز فعال کرد.
    برای اینکار باید CCP2 را در رجیستر CCP2CON تنظیم کرد (CCP2M3:CCP2M0 = 1011).
    استفاده از این خاصیت برای زمانی که شما مایل باشید در مدت زمانی مخصوص مثلا یک میلی ثانیه, یک نمونه برداری کنید بسیار مناسب است و شما را از نوشتن مقداری زیادی کد راحت میکند.
    این ADC همچنین میتواند در حالت خواب (sleep) نیز به اندازه گیری ادامه دهد. برای اینکار باید Takt یا اوسیلاتور ADC حتما اوسیلاتور داخلی (RC oscillator) باشد.

    شما با استفاده از این ADC میتوانید بسیار ساده یک دستگاه اندازه گیری مثل ولت متر, آمپر متر و غیره را با میکروکنترلر بسازید. ( فانتزی شما مرزی ندارد)
    برای نمونه من برای آزمایش این موضوع یک برنامه نوشته ام که از ADC یک اسیلوسکوپ میسازد, پهنای باند این اسیلوسکوپ طبیعتا پایین است ولی برای فرکانس هایی در محدوده صوتی قابل استفاده است و جنبه آموزشی دارد تا یک برنامه حرفه ای.
    این برنامه را از اینجا ADC_OSC.zip میتوانید دانلود کنید.
    این فایل فشرده فقط حاوی برنامه قابل اجرا (exe.) است اگر مابل به دریافت تمامی کد باشید در قسمت نظرات شما با من ارتباط حاصل کنید.

    بالا پایین