0

So I have a PIC 16F88, and I managed to do a couple things with it, but now I was wondering how to get analog to digital conversion?

I've tried many examples out there in the internet, but no success :( if anyone could give a light on how to use the ADCON0/1 and stuff like that, I will appreciate.

Thanks a lot.

Edit: this is my code:

START
    banksel TRISA
    clrf    TRISB
    movlw   0xff
    movwf   TRISA
    movlw   b'11000111'
    movwf   OPTION_REG
    movlw   b'00000001'
    movwf   ADCON1
    banksel PORTB
    clrf    PORTB   
LOOP
    btfss   PIR1,ADIF
    goto    LOOP
    bsf ADCON0,GO   
WAIT
    btfsc   ADCON0,GO
    goto    WAIT
    movf    ADRESH,W
    movwf   PORTB,W
END
RicardoE
  • 1,665
  • 6
  • 24
  • 42
  • What means "no success"? Please tell/show us what you have tried and what exactly doesn't work. – Frank Bollack May 22 '12 at 09:53
  • ok, suppose I want to convert RA0 from analog to digital, then I use this code: INICIO banksel TRISA clrf TRISB movlw 0xff movwf TRISA movlw b'11000111' movwf OPTION_REG movlw b'00000001' movwf ADCON1 banksel PORTB clrf PORTB LOOP btfss PIR1,ADIF goto LOOP bsf ADCON0,GO WAIT btfsc ADCON0,GO goto WAIT movf ADRESH,W movwf PORTB,W END but it does not work :(, the converted value should output in portb.. – RicardoE May 22 '12 at 09:54
  • hhmmm I will edit the question with what I have. – RicardoE May 22 '12 at 09:56
  • I don't see any code. Please edit your initial question and add any information or code there. – Frank Bollack May 22 '12 at 09:56

1 Answers1

0

From the PIC datasheet:

The ADRESH:ADRESL registers contain the 10-bit result of the A/D conversion. When the A/D conversion is complete, the result is loaded into this A/D result register pair, the GO/DONE bit (ADCON0<2>) is cleared and the A/D interrupt flag bit ADIF is set. The block diagram of the A/D module is shown in Figure 11-1.

After the A/D module has been configured as desired, the selected channel must be acquired before the conversion is started. The analog input channels must have their corresponding TRIS bits selected as inputs. To determine sample time, see Section 11.1. After this acquisition time has elapsed, the A/D conversion can be started. The following steps should be followed for doing an A/D conversion:

  1. Configure the A/D module: • Configure analog pins / voltage reference / and digital I/O (ADCON1) • Select A/D input channel (ADCON0) • Select A/D conversion clock (ADCON0) • Turn on A/D module (ADCON0)
  2. Configure A/D interrupt (if desired): • Clear ADIF bit • Set ADIE bit • Set GIE bit 3. Wait the required acquisition time.
  3. Start conversion: • Set GO/DONE bit (ADCON0)
  4. Wait for A/D conversion to complete, by either: • Polling for the GO/DONE bit to be cleared OR • Waiting for the A/D interrupt
  5. Read A/D Result register pair (ADRESH:ADRESL), clear bit ADIF if required.
  6. For next conversion, go to step 1 or step 2 as required. The A/D conversion time per bit is defined as TAD. A minimum wait of 2TAD is required before next acquisition starts.

You are not waiting the acquisition time before starting the conversion. Everything else seems right.

Adam Casey
  • 949
  • 2
  • 8
  • 24
  • So not only does one have to wait for the required acquisition time when initializing the ADC but also at the end of each ISR? Given a TAD of 6us per bit when using FRC one is looking at 6us * 10 bits + 1us = 67us. Do you put a __delay_us(67) in the ADC ISR? I'm not used to putting delays in ISRs but it doesn't look like there is any other option. – sizzle Apr 09 '14 at 20:00
  • 1
    No, don't put a delay in the ISR. The interrupt is called when the GO/DONE bit is cleared. It's not that clear in the Microchip docs, but one wait is enough. – Adam Casey Apr 10 '14 at 19:17
  • Thanks for the reply. I ended up figuring out how to service the ADC interrupt. I use Timer1 to set the GO/DONE bit and restart the ADC interrupt every second. I only need an ADC value every second so this works out well. – sizzle Apr 10 '14 at 23:01