Autor Tema: Problemas al usar el AD del dspic33EP256MU806 con Vref+  (Leído 1632 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado mizzard

  • PIC10
  • *
  • Mensajes: 32
Problemas al usar el AD del dspic33EP256MU806 con Vref+
« en: 16 de Noviembre de 2012, 07:40:46 »
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>
Código: [Seleccionar]
#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>
Código: [Seleccionar]
#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!