• PicŪ Basic


  • ADC interval with Special Event Trigger

    This article is in response to a user asking "Is it possible to use the Adin command in a timer based interrupt routine?"
    This solution was provided by forum member Barak and uses the internal Timer3 interrupt flag CCP2IF. There is no software inside the interrupt, instead the software waits in a loop for CCP2IF to be set and then takes the required action. This approach provides a fixed interval and avoids having a large amount of code inside an interrupt routine and any need to save registers.

    Here is Barak's solution.
    You can generate ADC with fixed interval with the Special Event Trigger. Example for 18FXXK20 running at 64MHz with 200uS interval:

    Code:
    SpecialEvent_setup: 
    CCP2CON = %00001011 ' set for trigger special event ADC
    T3CON = %10111000 ' set timer 3 as clock source for CCP2 and prescale 1:8
    Symbol TMR3ON = T3CON.0 ' Timer 3 enable on bit
    Symbol CCP2IF = PIR2.0 ' CCP2 interrupt flag bit
    Symbol CCP2Reg = CCPR2.Word ' alias for CCP2 registers
    CCP2Reg = $190 ' load CCP2 registers with 400 for 200uS sampling/Fs=5KHz 
     
    ADC_Setup: 
    ADCON0 = %00001100 ' CHS<3:0> 0011 for AN3
    ADCON1 = %00000000 ' VSS -ref and VDD +ref. 
    ADCON2 = %00010110 ' Bit 7=0 left justify, bit 5-3 = ACQT 4 TAD, bits 2-0 = Fosc/64
    Symbol ADON = ADCON0.0 ' ADC enable bit
    Symbol GO_DONE = ADCON0.1 ' ADC status bit cleared after acq 
     
    Process:
    While 1 = 1
    GoSub ADCEvent ' wait for the next CCP2 event
    ' Process here
    ' you have less than 200uS to calculate and process 
    ' before going back to the top of the loop to wait 
    ' for the next ADC Event 
    Wend
     
    ADCEvent: 
    While CCP2IF = 0 : Wend ' Poll the CCP2 interrupt flag
    CCP2IF = 0 ' clear the flag for next time
    While GO_DONE = 1 : Wend ' Poll the GO_DONE flag for completion of conversion
    Samp = ADRESH ' load 8 MSB from AN3 conversion to variable
    Return