desktop

Problema con el ADC en PIC18 y XC8

Saludos. Tengo un problema al usar el ADC de una placa con un PIC18F67J50
Lo que pasa es que al configurar el ADC, no me muestra los valores reales de voltaje, tengo una escala de 0 a 3.3 V. utilizando la alimentación interna del PIC.

El ADC sólo me está capturando de 0 a 1.8 V.
Cuando está en éste valor, los registros ADRESH y ADRESL me devuelven 1024, para valores mas altos se queda en 1024.

Probé midiendo el voltaje en el pin del PIC y cuando está realizando la captura, eleva el voltaje.

¿Hay alguna forma de saber si el ADC del PIC no está funcionando correctamente?

Dejo adjunto el código que uso.
PHP:
#include <xc.h>
#include <stdio.h>
#include <pic18f67j50.h>
#define _XTAL_FREQ 19660800
#include "flex_lcd.h"

// CONFIG1L
#pragma config WDTEN = OFF      // Watchdog Timer Enable bit (WDT disabled (control is placed on SWDTEN bit))
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable bit (Reset on stack overflow/underflow disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG1H
#pragma config CPUDIV = OSC1    // CPU System Clock Postscaler (No CPU system clock divide)
#pragma config CP0 = OFF        // Code Protection bit (Program memory is not code-protected)

// CONFIG2L
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator, HS used by USB)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Two-Speed Start-up (Internal/External Oscillator Switchover) Control bit (Two-Speed Start-up disabled)

// CONFIG2H
#pragma config WDTPS = 32768    // Watchdog Timer Postscaler Select bits (1:32768)

// CONFIG3L

// CONFIG3H
#pragma config CCP2MX = DEFAULT // ECCP2 MUX bit (ECCP2/P2A is multiplexed with RC1)
#pragma config MSSPMSK = MSK7   // MSSP Address Masking Mode Select bit (7-Bit Address Masking mode enable)

void main(void) {
    
    int i;
    unsigned char buffer1[20];
    int adc;
    
    TRISAbits.RA0=0;
    PORTA=0;
    
    //Configuracion para usar el CAD    
    //Analog Port Configuration bits // 1 digital 0 analog
    ANCON0bits.PCFG7 = 1; // AN7
    ANCON0bits.PCFG4 = 1; // AN4
    ANCON0bits.PCFG3 = 1; // AN3
    ANCON0bits.PCFG2 = 1; // AN2
    ANCON0bits.PCFG1 = 1; // AN1
    ANCON0bits.PCFG0 = 1; // AN0
    ANCON1bits.PCFG11 = 1; // AN11
    ANCON1bits.PCFG10 = 0; // AN10
    
    ADCON0bits.VCFG = 0b00; //Voltage Reference Configuration bits (Vref- Vref+) ( Vss Vdd)    
    ADCON0bits.CHS = 0b1010; //Analog Chanel Select bits 
    
    ADCON1bits.ACQT = 0b101; // A/D Acquisition Time Select bits // 12 TAD
    ADCON1bits.ADCS = 0b011; // A/D Conversion Clock Select bits // usar el reloj RC
    ADCON1bits.ADCAL = 0; // A/D Calibration bit (1 Calibration is performed on next A/D conversion / 0 Normal A/D Conversion operatino)
    ADCON1bits.ADFM = 1; //A/D Result Format Select bit (1 Right / 0 Left) justified

    ADCON0bits.ADON = 1; // prender el modulo CAD
  
    //LCD
    Lcd_Init();
    Lcd_Cmd(LCD_CLEAR);
    Lcd_Cmd(LCD_CURSOR_OFF);
    __delay_ms(100);
    
    
    for(i=3; i>0; i--){
        sprintf(buffer1,"Cuenta %03d", i); // guardamos en el string Buffer1 la palabra
        Lcd_Out2(1,1,buffer1); // escribimos en el reglon1 espacion1
        __delay_ms(1000);
    }
    
    Lcd_Out(2,1, "Prueba LCD");
    __delay_ms(600);
    Lcd_Cmd(LCD_BLINK_CURSOR_ON);
    __delay_ms(1000);
    Lcd_Cmd(LCD_UNDERLINE_ON);
    __delay_ms(1000);
    Lcd_Cmd(LCD_CURSOR_OFF);
    __delay_ms(1000);
    
    while(1){
        PORTAbits.RA0 = 1;
        __delay_ms(1000);
        PORTAbits.RA0 = 0;
        __delay_ms(1000);
        
        ADCON0bits.GO_DONE = 1; // A/D Conversion Status bit // cuando pasa a 0 la captura esta realizada
        while(ADCON0bits.GO_DONE);
        __delay_ms(100);
        adc=ADRESH;
        adc=adc<<8;  
        adc=adc+ADRESL;
        
        Lcd_Cmd(LCD_CLEAR);
        sprintf(buffer1,"ADC %04d",adc);
        Lcd_Out2(1,1,buffer1);
        sprintf(buffer1,"H %04d L %04d",ADRESH,ADRESL);
        Lcd_Out2(2,1,buffer1);                
    }
    return;
}
Gracias por sus respuestas.
 
Última edición por un moderador:
Atrás
Arriba