Menu

Start ADC, do something else, reading value later (no need for AD_Delay) ?

Help
2 days ago
2 hours ago
  • Roger Jönsson

    Roger Jönsson - 2 days ago

    I have an interrupt routine playing back audio from memory to DAC. 18F27Q84.
    I simultaneously need to sample an analog input with the ADC. I could start it off, do the DAC-stuff and there would be enough delay for the ADC to complete its work without the need for a stand still with AD_Delay.

    The question is can I do something like this in GCbasic:
    StartADC - do some other stuff - GetADC
    or to do this I will have to fiddle with chip registers manually?

    Not that I absolutely need it now, but it would be elegant and effective maybe opening future possibilities.

     
  • Anobium

    Anobium - 2 days ago

    All possible. I would rationalise the ADC read ( using the existing sub routine ) but put the code inline to do what you want. Fiddling with registers ( lol ) is what the existing sub does anyway. You are moving from sequencial to inline.

    All doable.

     
  • Roger Jönsson

    Roger Jönsson - 2 days ago

    Yes, I understand that the existing sub is poking around with the registers. My question should have been: can I do it using GCbasic commands? (set it off, leave the chip to do its A/D magic and get the output later).

    Looking at a-d.h I figured it would be too hard for me to distill what I need. My guess is that it would be easier to try to figure out what register settings are needed, throw them in (I guess that is what you call inline code) and see if I can get it to show any sign of life.
    I will have at a-d.h again and see if I can copy it, maybe just stop it at the right moment, before it interrupts the convertion in order to read the value. But. There is a lot of code ot grasp. If I settle on just one chip maybe it is easier to set the registers manually (playing them until it responds back).

     
    • Anobium

      Anobium - 2 days ago

      The configuration ( not poking about! ) in shown in your ASM. This is the best place to look. This is configured for your chip and therefore works. It is not a case of copying the a-d.h , this is a case of use the ASM produced and copying the required GCBASIC instructions to your program. There will only be a few GCBASIC instructions required.

      This approach can be repeated across all 1500 microcontrollers. So, look in the ASM at the GCBASIC source added as part of the compilation for a specific microcontroller.

       
      👍
      1
  • Roger Jönsson

    Roger Jönsson - 21 hours ago

    I examined the asm for a long time, but I could not make out what to extract, so I took a look in the 18FxxQ84 manual to see if it would help. There was an ADC example which I managed to adopt and succeeded in getting working. So after seemingly wasting a lot of valuable time fiddling around, it turned out it was not wasted after all!
    I now have a AD-conversion routine that can be started off to do its thing while my code is running.
    Happy day! :)

    #CHIP 18F27Q84, 64
    #OPTION Explicit
    
    DIR PORTA.1 OUT
    DIR PORTA.3 IN
    Dim ADCresult as Byte
    
    //ANALOG TO DIGITAL CONVERSION on 18FxxQ84
    //Instead of waiting or pausing for polling, code can be running while conversion gets finished.
    
    //Extracted from the 18FxxQ84 manual (example page 916)
    ADCON1=0 ;
    ADCON2=0 ; Legacy mode, no filtering, ADRES->ADPREV
    ADCON3=0 ; no math functions
    ADREF=0 ; Vref = Vdd & Vss
    ADPCH=3 ; select RA3/AN3
    ADACQ=0 ; software controlled acquisition time
    ADCAP=0 ; default S&H capacitance
    ADRPT=0 ; no repeat measurements
    ADACT=0 ; auto-conversion disabled
    ADCON0=B'10010000'   //bit 2 high for 12bit (right justified), low = read 8-bit from ADRESH (left justified, zero-filled)
    
    //TRISA3 = 1 //PortA.3 = input (Tri-state control register)
    //ANSELA3=1 //PortA.3 analog input
    
    Do
        ADCON0.0=1  //--START-- conversion by setting flag. -Ready when this flag goes low (page 936)
        wait 20 us  //--WAIT-- can be REPLACED BY CODE or looking for ADCON0.0 flag going low
        ADCresult=ADRESH  //--READ-- 8bit through ADRESH, for 12bit (ADCON0.2=1) result at: ADRESL, ADRESH
        If ADCresult >128 then PORTA.1=1 else PORTA.1=0 //-OUTPUT (changes state at 1/2 VCC on PORTA.3)
    Loop
    
     
    👍
    1
  • Roger Jönsson

    Roger Jönsson - 5 hours ago

    With Bit 4=1 of ADCON0 as in the above example the built-in Analog-to-Digital Converter RC Oscillator (ADCRC) is used, giving a tad of 1-2us and total conversion time 10-20us for 8-bit.

    Using FOSC as source instead (+ prescaler /22) conversion is faster and is as fast as possible without violating the specification limits. Code change:

    ADCON0=B'10000000'   // Bit 4=0 FOSC. Needs prescaler. 
    ADCLK = 0x15 //= prescaler /22, = tad 0.67us and measuring about 7us (8-bit) and 9us (12bit)
    

    For 8-bit a wait of 10us (instead of 20us with ADCRC) now seems safe. One probably should check the ADCON0.0 flag going low to be perfectly safe, but I found it working without.

    While it is working it seems that I should have added some value to ADACQ (ADC Acquisition Time Control Register. ADACQL) = 3 (minium 3-10 is recommended, FOSC cycles). Higher ADACQ value = not as demanding on source being low impedance. With a value of 3 it still should be within 10us total, with a value of 10 the total time should be within 15us(?). The reason for this seemingly working with ADACQ=0 is likely due to only using a single channel/input.

     

    Last edit: Roger Jönsson 2 hours ago
  • Roger Jönsson

    Roger Jönsson - 5 hours ago

    Looking at the asm doing: - MYresult = ReadAD(AN3). -When starting the AD converter conversation it says:

    ;SET ADON ON                 
        bsf ADCON0,ADON,BANKED
    

    I guess what it does is setting the conversion flag: ADCON0.0=1 (ADCON0.0 being called "GO" in the manual).
    Reading the asm, how would I know what bit ADON is?
    Just to help me understand how the asm is working. I searched for ADON in the asm file but did not find an explainiation.

     
    • Anobium

      Anobium - 4 hours ago

      The bit mappings are in PICINFO.

       
  • Roger Jönsson

    Roger Jönsson - 3 hours ago

    I think I misunderstood how GCbasic ReadAD works.
    AD_Delay controls is the acquisition delay (during this time the value is sampled, a capacitor is charged up)?
    After that the voltage sampled gets measured internally, while ReadAD waits for the flag to signal ready before moving along?
    So the total time consumed is AD_Delay + for the logic to find the value and clear the flag.

    asm snippet:
    ;Enable AD Operations
    ;SET ADON ON
    bsf ADCON0,ADON,BANKED
    ;Acquisition Delay
    ;Wait AD_Delay //<- sampling starts and continues for 10us?
    movlw 2
    movwf SysWaitTemp10US,ACCESS
    banksel 0
    rcall Delay_10US
    ;Read A/D @1
    ;SET GO_NOT_DONE ON
    banksel ADCON0
    bsf ADCON0,GO_NOT_DONE,BANKED //<- flag is set, measuring of what is sampled starts?
    ;nop
    nop
    ;Wait While GO_NOT_DONE ON //wait until flag signals done?
    SysWaitLoop1
    btfsc ADCON0,GO_NOT_DONE,BANKED
    bra SysWaitLoop1
    ;Switch off A/D
    ;SET ADCON0.ADON OFF
    bcf ADCON0,ADON,BANKED

     
  • Anobium

    Anobium - 2 hours ago

    There is a minimum sample time ( the wait ) then internal processing ( which is the register.bit check).

     

Log in to post a comment.

Auth0 Logo