Autor Tema: dspic33 ADC simultaneo sin DMA sample automatico  (Leído 3648 veces)

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

Desconectado brutto

  • PIC10
  • *
  • Mensajes: 44
dspic33 ADC simultaneo sin DMA sample automatico
« en: 08 de Mayo de 2011, 12:48:00 »
hola, queria saber si alguien sabe como funciona el ADC del dspic33 configurado como simultaneo y con periodo automatico de muestras. He realizado un pequeño programa para aprender (que me ha costado bastante). Para sacar el valor del AN0 por el puerto serie me ha funcionado bastante bien, el problema ha sido cuando he intentado agregar un pin de entrada analogica mas, ya que este micro dspic33fj128mc202 solo tiene el ADC1BUF0 y usa DMA, lo cual dificulta mi aprendizaje porque no me entero de mucho para configurar el DMA. Asi que decidi intentar hacer el programa sin usar DMA saltando a una interrupcion con cada muestra del ADC.
Pongo el programa para ver si esta ok (funcionar funciona) y asi alguien me pueda explicar si cuando eliges muestras simultaneas con sample automatico cada muestra salta a interrupcion y en el orden de los canales CH0 CH1 CH2 CH3 de ahi que use el switch para elegir el canal:

#include "p33FJ128MC202.h"
#define __33FJ128MC20_H
#define FCY 40000000UL
#include <libpic30.h>
#include <uart.h>
#include <adc.h>

#define BAUDRATE 115200      // VALOR DE BAUDE RATE DE COMUNICACIÓN
#define BRGVAL ((FCY/BAUDRATE)/16)-1


/**** CONFIGURACION BITS ***/
_FOSCSEL(FNOSC_FRC);        // Select Internal FRC at Powerup
_FOSC(FCKSM_CSECMD    &     // Enable Clock Switching
    OSCIOFNC_OFF     &      // OSC2 is clock O/P                           
    POSCMD_HS)        ;     // XT oscillator
   

_FWDT(FWDTEN_OFF);                //watchdog disable
_FICD (JTAGEN_OFF&ICS_PGD2);      //jtad disable icd enable en PGD1
_FGS(GSS_OFF & GCP_OFF & GWRP_OFF);   // Code Protect OFF
_FPOR(FPWRT_PWR64);


#define led LATBbits.LATB5

int scan=1;
int ain0Buff=0;
int ain1Buff=0;

int main (void)
{   
   int i,a=0,adcvalor,adcvalor0=0,adcvalor1=0,int_dma=0;
   float valor=0;
   Oscilador_init();
   puertos_init();
   RS232_init();
   printf("\f");      //limpia pantalla hyperterminal
   ADC_init();



while (1)
{
   LATBbits.LATB5=1;
   for (i=0;i<2;i++)
   __delay_ms(100);
   a++;
   adcvalor=ain0Buff;
   valor=(3.3*adcvalor)/1024;
   printf("\fADC valor %u",adcvalor);
   printf("\r\nVoltaje  %.2f",valor);
   adcvalor=ain1Buff;
   valor=(3.3*adcvalor)/1024;
   printf("\r\nADC2 valor %u",adcvalor);
   printf("\r\nVoltaje2  %.2f",valor);
   printf("\r\nScan %u",scan);
}


} // FINAL VOID MAIN


void Oscilador_init(void)
{
//CONFIGURACION PARA CRYSTAL 10MHZ SALIDA 40MIPS (80MHZ).
    PLLFBD=30;             // M=32
    CLKDIVbits.PLLPOST=0;   // N1=2
    CLKDIVbits.PLLPRE=0;   // N2=2
   
    OSCCON = 0x3301;                                    // b0011 0011 0000 0001
    CLKDIV = 0x0000;
    // Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)
    __builtin_write_OSCCONH(0b011);
    __builtin_write_OSCCONL(0b001);

    // Wait for Clock switch to occur
    while (OSCCONbits.COSC != 0b011)

    // Wait for PLL to lock
    while(OSCCONbits.LOCK!=1) {};
}

void timer1_init(void)
{

}
   
void puertos_init(void)
{
   AD1PCFGL = 0xffff;         // PUERTO A como digital
   TRISA=0x00;   // PUERTO A como salidas
   TRISB=0x00;   // PUERTO B como salidas
   TRISBbits.TRISB6=1;
   LATA=0;
   LATB=0;
}

void RS232_init(void)
{
    RPINR18 = 0x06;         // Make Pin RP6 U1RX
    RPOR4bits.RP8R = 0x03;  // Make Pin RP8 U1TX
    U1MODEbits.STSEL = 0;          // 1-stop bit
    U1MODEbits.PDSEL = 0;           // No Parity, 8-data bits
    U1MODEbits.ABAUD = 0;           // Auto-Baud Disabled
    U1MODEbits.BRGH = 0;           // Low Speed mode
    U1BRG = BRGVAL;             // BAUD Rate Setting
    U1STAbits.UTXISEL0 = 0;       // Interrupt after one Tx character is transmitted
    U1STAbits.UTXISEL1 = 0;
    IEC0bits.U1TXIE = 0;          // Disenable UART Tx interrupt
    U1MODEbits.UARTEN = 1;          // Enable UART
    U1STAbits.UTXEN = 1;          // Enable UART Tx 

}


void ADC_init(void)
{
   AD1PCFGL=0b11111100;      //Pin AN0 AN1 analogicos
   TRISAbits.TRISA0=1;      //configurar pin como entrada
   TRISAbits.TRISA1=1;      //configurar pin como entrada

   AD1CON1bits.ASAM = 1;         // 1 = Sampling begins immediately after last conversion. SAMP bit is auto-set.
   AD1CON1bits.SSRC = 7;         // auto sampling and convert
   AD1CON1bits.AD12B = 0;         // select 10-bit, 1 channel ADC operation       
   
   AD1CON2bits.CHPS=0b10;         //converts CH0,CH1,CH2,CH3
   AD1CON2bits.ALTS=0;            //always uses channel input selects for Sample A

    AD1CON3bits.SAMC=10;         // auto sample time
    AD1CON3bits.ADCS=64;          // conversion clock select    

   AD1CHS0bits.CH0NB=0;      //CH0 neg -vref SAMPLE B
   AD1CHS0bits.CH0SB=0;      //CH0 positive AN0 sample B
   AD1CHS0bits.CH0NA=0;      //CH0 neg -vref SAMPLE A
   AD1CHS0bits.CH0SA=0;      //CH0 positive AN0 sample A

   AD1CHS123bits.CH123NB=0;   //CH1 CH2 CH3 neg -vref SAMPLE B
   AD1CHS123bits.CH123SB=1;    //CH1 positive AN3, CH2 positive AN1, CH3 positive AN2 SAMPLE B
   AD1CHS123bits.CH123NA=0;   //CH1 CH2 CH3 neng -vref SAMPLE A SAMPLE A
   AD1CHS123bits.CH123SA=0;   //CH1 positive AN0, CH2 positive AN1, CH3 positive AN3 SAMPLE A

   AD1CSSL=0;
   
   AD1CON1bits.SIMSAM=1;      //samples CH0 CH1 CH2 CH3 simultaneos
   AD1CON2bits.SMPI=0;            //DMA address cada x operaciones

   IPC3bits.AD1IP=6;            //Prioridad 6 en la interrupcion DMA

   IEC0bits.AD1IE=1;            //enable ADC interrupt
   IFS0bits.AD1IF = 0;          // reset ADC interrupt flag              
   AD1CON1bits.ADON = 1;           // turn on ADC module            
}



int numero_scan=0;
int numero_sample=0;

void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt(void)
{
   switch(numero_scan)
   {
      case 0:
         ain0Buff=ADC1BUF0;      //CHO
         break;
   
      case 2:
         ain1Buff=ADC1BUF0;      //CH1
         break;

      default:
      
      break;
   }
   
   scan++;
   numero_scan++;
   if (numero_scan>2) numero_scan=0;

   IFS0bits.AD1IF = 0;      // Clear the ADC1 Interrupt Flag
}


cuando configuras el adquisicion simultanea con canales CH0 CH1 CH2 se hace siempre las 4 adquisiciones o tiene en cuenta los pines habilitados como analogicos? el scan esta en 0 para no usarlo, no se si sera por eso o no. Es que el AN1 lo tengo en el CH2 segun datasheet.

¿alguien tiene algo de informacion clara para usar el DMA con el ADC? no me entero de nada con el datasheet y las explicaciones de microchip poruq eno hay ejemplos de adquisicion de datos al DMA.

gracias.

Desconectado blackcat

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 600
Re: dspic33 ADC simultaneo sin DMA sample automatico
« Respuesta #1 en: 08 de Mayo de 2011, 18:52:22 »
En el manual de referencia hay una buena explicacion ...

De hecho, hay un ejemplo de muestras automaticas en el DMA que si funciona.

Saludos!
Control Automático, DSP & Microcontroladores

Desconectado brutto

  • PIC10
  • *
  • Mensajes: 44
Re: dspic33 ADC simultaneo sin DMA sample automatico
« Respuesta #2 en: 09 de Mayo de 2011, 14:39:35 »
parece que el simultaneo no funciona sin dma, o yo no se como leer las muestras. En muestras alternas si me funciona ok, a traves del timer3 y del pwm1

gracias


 

anything