No se pudo usar ADC con los pines RA4 o RA5 en PIC16F18325

0

Soy nuevo en la programación de PIC16F (aunque tengo una gran experiencia con Arduino) y actualmente estoy explorando el ADC de mi PIC16F18325

El circuito es bastante simple: el resultado del anuncio se muestra en una pantalla LCD de 16x2.

PORTC se usa para controlar la pantalla LCD, RA0 y RA1 son utilizados por el programador / depurador, RA3 se usa para MCLR. RA2 / 4/5 no están en uso.

Si configuro el ADC para usar RA2 como su canal de entrada, todo funciona bien (el valor mostrado es razonable)

Pero si trato de usar RA4 o RA5 como canal de entrada ADC, obtengo valores sin sentido.

Las únicas líneas de código que cambio son solo TRISA, ANSELA y ADCON0.

Entonces empecé a preguntarme si RA4 y RA5 tienen algún significado especial y deben configurarse de alguna otra manera, pero puedo encontrar información útil. Tengo la sensación de que me estoy perdiendo algo obvio, pero simplemente no puedo verlo.

Editar 1

Como la gente sugirió, traté de reescribir el código para que fuera más legible para los humanos. Desafortunadamente, las constantes como ANA2, etc. no están definidas (o no sé cómo obtenerlas), así que tuve que definirlas manualmente. Aún así, el circuito funciona bien solo con ANA2 y no con los demás. (parece que RA4 y RA5 están internamente conectados a algo, pero no sé qué, ni cómo desactivar este comportamiento)

/*
 * File:   main.c
 * Author: [email protected]
 *
 * Created on November 14, 2016, 3:21 PM
 */

#pragma config RSTOSC = HFINT32, WDTE = OFF, FEXTOSC = OFF
#define _XTAL_FREQ 32000000
#define FVR 2.048
#define RES (FVR / 1023.0)
#include "lcd.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <xc.h>

#define ANA5    0b101
#define ANA4    0b100
#define ANA2    0b010
#define ADCRC   0b111

volatile uint8_t count = 0;
volatile uint8_t status = 0;
const char S[2] = {' ', ':' };

float get_voltage(void);
float get_temp(void);
void putch(char c);
void interrupt handler(void);

void main(void) {

    /* Configure PORT C as output, and initialize it at zero.*/
    TRISC = 0;
    LATC = 0;

    /* Configure Timer0 */
    // T0CON1 = 0b01111000;  // HFINTOSC 16 MHz, ASYNC, 1:256 pre scaler
    T0CON1bits.T0CS =  0b011;        // HFINTOSC
    T0CON1bits.T0CKPS = 0b1000;      // 1:256 ps
    T0CON1bits.T0ASYNC = 1;


    //T0CON0 = 0b10010000;  // ENABLED, 16 bit, 1:1 post scaler
    T0CON0bits.T0OUT = 0;
    T0CON0bits.T016BIT = 1;
    T0CON0bits.T0EN = 1;

    TMR0H = 0;
    TMR0L = 0;
    TMR0IF = 0;
    TMR0IE = 1;
    /* Timer0 interrupt should happen every second */

    /* Configure FVR */
    //FVRCON = 0b11001010;    // ENABLED, 2.048 V
    FVRCONbits.ADFVR = 2;   // 2.048 V
    FVRCONbits.CDAFVR = 2;  // 2.048 V
    FVRCONbits.TSEN = 1;    // Enabled


    /* Configure ADC */
    TRISA  = 0b00110100;           // Make RA5/4/2 suitable for ADC
    ANSELA = 0b00110100;

    ADCON1 = 0b11110011;        // right jst, ADCRC OSC, Ref+ = FVR, Ref- = VSS
    ADCON1bits.ADFM   = 1;      // Right Justification
    ADCON1bits.ADCS   = ADCRC;  // ADCRC
    ADCON1bits.ADNREF = 0;      // VSS
    ADCON1bits.ADPREF = 3;      // FVR

    ADACT = 0b0011;             // AutoTrigger on Timer0 Interrupt

    // Select one channel and activate ADC
    ADCON0bits.CHS =  ANA5;
    //ADCON0bits.CHS =  ANA4;
    //ADCON0bits.CHS =  ANA2;
    ADCON0bits.ADON = 1;                  // Enable ADC
    __delay_us(15);            // Wait acquisition delay (2 us data-sheet says)

    // enable ADC interrupts
    ADIF = 0;
    ADIE = 1;
    PEIE = 1;

    LCD_init(); // initialize LCD

    // Just wait for interrupts :) 
    ei();   
    while(1);   
}

void putch(char c) {
    LCD_putc(c);
}

void interrupt handler()
{
    uint16_t tmp;
    if(ADIF) {
        ADIF = 0;
        LCD_move(0, 0);
        printf("%-8u", count++);
        LCD_move(1, 0);
        tmp = ADRES;
        printf("%.1f C", get_temp());
        return;
    }
    if(TMR0IF) {
        TMR0IF = 0;
        LCD_move(0, 15);
        putch(S[status]);
        status = !status;
        /*if(!ADGO) {
            ADGO = 1;
        }*/
        return;
    }
}

float get_voltage()
{
    return (float)ADRES / 1023.0 * FVR;
}

float get_temp()
{
    return 100 * get_voltage();
}
    
pregunta lmureu

0 respuestas

Lea otras preguntas en las etiquetas