Hola a todos!
Estoy desarrollando un proyecto con el dspic33ep256mu806 y utilizo el compilador PCWHD de CCS, la version 4.128
El problema que tengo es que el AD trabaja perfectamente cuando trabaja entre el rango de Avdd y AVss, pero cuando quiero ponerle una tensión de referencia en el pin RB0, sigue trabajando igual (quiero que trabaje entre Vref+ y AVss)
(la tensión Vref+ será de 3V y Vdd del PIC y Avdd del AD es de 3.3V)
Este es el codigo q utilizo:
<main.h>
#include <33EP256MU806.h>
//#device adc=10
#FUSES NODEBUG //No Debug mode for ICD
#FUSES PUT128 //Power On Reset Timer value 128ms
#FUSES NOWDT //No Watch Dog Timer
#FUSES PR_PLL
#FUSES HS
#FUSES ICSP1
#FUSES OSCIO
#FUSES CKSFSM
#FUSES NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
// Oscillator
#WORD CLKDIV = 0x0744 //PLLPOST(6,7) - PLLPRE(0,1,2,3,4)
#BIT PLLPOST_0 = CLKDIV.6
#BIT PLLPOST_1 = CLKDIV.7
#BIT PLLPRE_0 = CLKDIV.0
#BIT PLLPRE_1 = CLKDIV.1
#BIT PLLPRE_2 = CLKDIV.2
#BIT PLLPRE_3 = CLKDIV.3
#BIT PLLPRE_4 = CLKDIV.4
#WORD PLLFBD = 0x0746 //PLLDIV(0,1,2,3,4,5,6,7,8)
#BIT PLLDIV_0 = PLLFBD.0
#BIT PLLDIV_1 = PLLFBD.1
#BIT PLLDIV_2 = PLLFBD.2
#BIT PLLDIV_3 = PLLFBD.3
#BIT PLLDIV_4 = PLLFBD.4
#BIT PLLDIV_5 = PLLFBD.5
#BIT PLLDIV_6 = PLLFBD.6
#BIT PLLDIV_7 = PLLFBD.7
#BIT PLLDIV_8 = PLLFBD.8
#WORD OSCCON = 0x0742 // OSWEN(0) - NOSC(8,9,10)
#BIT OSWEN = OSCCON.0
#BIT NOSC_0 = OSCCON.8
#BIT NOSC_1 = OSCCON.9
#BIT NOSC_2 = OSCCON.10
#use delay(crystal=4000000,clock=120000000)
// SOFTWARE SERIAL PORT
#use rs232(stream = DEBUG, xmit=PIN_B7, rcv=PIN_B6, baud=115200, parity=N, bits=8)
// AD CONFIG REGISTERS
// INPUTS AND ANALOG PINS
#byte TRISB = 0x0E10
#bit TRISB0 = TRISB.0
#bit TRISB1 = TRISB.1
#bit TRISB2 = TRISB.2
#byte ANSELB = 0x0E1E
#bit ANSB0 = ANSELB.0
#bit ANSB1 = ANSELB.1
#bit ANSB2 = ANSELB.2
#byte ADC1BUF0 = 0x0300
#byte AD1CON1 = 0x0320
#bit VCFG_2 = AD1CON1.15
#bit VCFG_1 = AD1CON1.14
#bit VCFG_0 = AD1CON1.13
#byte AD1CON2 = 0x0322
#byte AD1CON3 = 0x0324
#byte AD1CON4 = 0x0332
#byte AD1CHS123 = 0x0326
#byte AD1CHS0 = 0x0328
#byte AD1CSSH = 0x032e
#byte AD1CSSL = 0x0330
#bit ADON = AD1CON1.15
#bit SAMP = AD1CON1.1
#bit DONE = AD1CON1.0
<main.c>
#include <math.h>
#include <stdio.h>
#include <string.h>
const unsigned int READ_SAMPLE_TIMES=20; // us
unsigned int16 leeCanalADC(unsigned int canal);
#INT_TIMER1
void tmr1_Interrupt(void){
set_timer1(15535); // 200 ms
if(cTMR1<10){
cTMR1++;
}
else if(cTMR1>=10){
// Update every AD reading each 2 sec
bActualizarInfo=true;
cTMR1=0;
}
}
void main(){
// Para tratar la respuesta de las funciones
// signed int respuestaFuncion=0;
unsigned int16 lecturaADC = 0;
unsigned int16 valorMedio = 0;
float resultVoltios = 0.0;
unsigned int numMuestras=0;
// Main oscillator XT/HS con PLL -> Fin = 4 MHz
OSWEN = 1;
NOSC_0 = 1;
NOSC_1 = 1;
NOSC_2 = 0;
// PLLPRE=0 Luego N1=2
PLLPRE_0 = 0;
PLLPRE_1 = 0;
PLLPRE_2 = 0;
PLLPRE_3 = 0;
PLLPRE_4 = 0;
// PLLPOST=0 Luego N2=2
PLLPOST_0 = 0;
PLLPOST_1 = 0;
// PLLDIV=118 Luego M=120
PLLDIV_0 = 0;
PLLDIV_1 = 1;
PLLDIV_2 = 1;
PLLDIV_3 = 0;
PLLDIV_4 = 1;
PLLDIV_5 = 1;
PLLDIV_6 = 1;
PLLDIV_7 = 0;
PLLDIV_8 = 0;
delay_ms(500);
// AD CONFIG
TRISB0 =1; // RB0 -> INPUT
ANSB0 = 1; // Analog AN0 -> RB0
TRISB1 =1; // RB1 -> INPUT
ANSB1 = 1; // Analog AN1 -> RB1
/*
TRISB2 =1; // RB2 -> INPUT
ANSB2 = 1; // Analog AN2 -> RB2
*/
AD1CON1=0x0000;
// AD1CON2=0x2000; // The same as the following two lines
/*
VCFG_2=0; // Vref+ - GND
VCFG_1=0;
VCFG_0=1;
*/
AD1CSSL=0x0000; // no scan
AD1CON3=0x8000; // internal;
AD1CHS0= 0x0001; //CHANNEL 1
// TIMERS
setup_timer1(TMR_INTERNAL|TMR_DIV_BY_256);
// TMR_INTERNAL = fuente de reloj interna 16bits
// El timer se incrementa cada:
// 1/120MHz * 2 {ciclo instruc} * 256 {preescaler} = 4,26 useg = aprox 4 useg
// INTERRUPTS
// SERIAL
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(INT_RDA3);
enable_interrupts(INT_RDA4);
// Timer1
set_timer1(15535);
enable_interrupts(INT_TIMER1);
enable_interrupts(INTR_GLOBAL);
delay_ms(3000);
fprintf(DEBUG,"Start\r\n");
while(true){
if (bActualizarInfo){
// CHANNEL 1
lecturaADC = leeCanalADC(1);
// resultVoltios = (3.0/1024.0)*lecturaADC;
fprintf(DEBUG,"\r\nCanal 2: %lu",lecturaADC);
// fprintf(DEBUG,"\r\nCanal 2: %.3f",resultVoltios);
// DEBUG <--------------
bActualizarInfo = false;
}
}
}
unsigned int16 leeCanalADC(unsigned int canal){
unsigned int16 *pADCVal=0;
// AD1CHS0= (0x0000 + (byte)(canal)); // Canal 1 or 2
/*
// PUEDO PONER ESTO EN CONFIG INICIAL DEL CAD ->FUNCION
AD1CSSL=0x0000; // no scan
AD1CON3=0x8000; // internal;
// PUEDO PONER ESTO EN CONFIG INICIAL DEL CAD ->FUNCION
*/
// AD1CON2=0x2000; // Vref+ - GND
delay_us(READ_SAMPLE_TIMES); //some delay
ADON = 1; // ADC ON
SAMP = 1; // start sampling
delay_us(READ_SAMPLE_TIMES); //some delay
SAMP = 0; //stop sampling and start conversion
while(!DONE); //while conversion not done stay here
pADCVal=&ADC1BUF0; //when conversion done save value form buffer to variable.
ADON = 0; // ADC OFF
return (*pADCVal);
}
Me he leido todo el capitulo que hace referencia al AD del datasheet pero no sé que más hacer. Además, he probado en otra placa y me sigue pasando lo mismo.
Alguna idea?
Muchas gracias de antemano!