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.