TODOPIC
Microcontroladores PIC => dsPIC => Mensaje iniciado por: leotardo en 24 de Mayo de 2007, 16:56:40
-
//aqui os dejo un ejemplo bicicleta de conversor ADC para un dspic30F4011,
//me llevo un par de noches largas.
//leo por orden de soft AN0, al que puse un potenciometro, me entero de lo que lee por PORTE,
//y por el OC3
//
// aunque la cosa funciona cada unos 100Us por interrupcion , en ella la lectura le lleva unos 3Us
// USO XTAL DE 20Mhz
//
//tanto rollo y al final solo hay que;
// ADCON3bits.ADCS=0b00100; // A/D Conversion Clock Select bits, TCY/2 • (ADCS<5> + 1)
// ADPCFGbits.PCFG0=0; //ya nace a 0
// ADCON1bits.ADON=1; // A/D Operating Mode bit, PONER AL FINAL
//
//
// la señal debe de ser potente, he visto que la conversion le mete grandes picos a la señal, (use potenciometro de 47K),
//con un C de 1Uf de alisado se silenciaron.
//
//PROHIBIDO PREGUNTAR, SUERTE.
//
#include "p30f4011.h"
_FOSC(CSW_FSCM_OFF & EC_PLL4); //sin cuentos de seguridad, clock externo x 4 pll
_FWDT(WDT_OFF); /* Turn off the Watch-Dog Timer. */
_FBORPOR( PBOR_OFF & BORV_45 & MCLR_EN & PWRT_64);
void __attribute__((__interrupt__,auto_psv)) _ISR _T3Interrupt(void);
void cebainterrupcion100u(void);
void cebapwm(void);
void cebaana(void);
char kk;
int main(void){
TRISF=0xffc0;
TRISE=0xffc0;
cebainterrupcion100u();
cebapwm();
cebaana();
while(1){
PORTFbits.RF0=1; //ports para segui con osciloscopio
PORTFbits.RF0=1;
PORTFbits.RF0=0;
}
}
void __attribute__((__interrupt__)) _T3Interrupt( void ){
IFS0bits.T3IF=0;
PORTFbits.RF1=1; //ports para segui con oscilo
PORTFbits.RF2=1; //ports para segui con oscilo
kk=2;
ADCON1bits.SAMP=1; // A/D Sample Enable bit, INICIA SAMPLEO
while(kk){kk--;}
ADCON1bits.SAMP=0; // A/D Sample Enable bit, FIN SAMPLEO, INICIA CONVERSION
PORTFbits.RF2=0;
PORTFbits.RF3=1;
// while (!IFS0bits.ADIF); // conversion done?
while (!ADCON1bits.DONE); {}// conversion done?
OC3RS=ADCBUF0+100; //el 100 es para que nunca llege a 0
PORTE=ADCBUF0;
PORTFbits.RF3=0; //en oscilos se queda en alto,
PORTFbits.RF1=0; //idem,,,??? misterios de la electronica,,,
}
void cebainterrupcion100u(void){
TMR3=0000;
PR3=1200;
T3CONbits.TON=1;
IFS0bits.T3IF=0; IPC1bits.T3IP=4; IEC0bits.T3IE=1; //T3,interrupcion de 100us, prioridad 4
}
void cebapwm(void) {
TRISDbits.TRISD2=0; //pin 22 out, usado como chivato
OC3CONbits.OCSIDL=0;
OC3CONbits.OCTSEL=1; //t3 selec
OC3CONbits.OCM=0b101; //pulsos continuos
OC3R=50; //arranque
// OC3RS=1000; //parada , CAMBIA EN INT T3
}
void cebaana(void){
IFS0bits.ADIF = 0; //Clear the A/D interrupt flag bit
IEC0bits.ADIE = 0; //Set the A/D interrupt enable bit
//ADCON1 A/D Control Register 1
//ADCON1bits.ADON=1; // A/D Operating Mode bit, PONER AL FINAL
ADCON1bits.ADSIDL=0; // Stop in Idle Mode bit
ADCON1bits.FORM=0b00; // Data Output Format bits. 00 = Integer (DOUT = 0000 00dd dddd dddd)
ADCON1bits.SSRC=0; // Clearing SAMP bit ends sampling and starts conversion
ADCON1bits.SIMSAM=0; // Simultaneous Sample Select bit
ADCON1bits.ASAM=0; // A/D Sample Auto-Start bit
//ADCON1bits.SAMP=1; // A/D Sample Enable bit, INICIA SAMPLEO
//ADCON1bits.DONE=1; // A/D Conversion Status bit, ESTA CONVIRTIENDO
//ADCON2 A/D Control Register 2
ADCON2bits.VCFG=0b000; // Voltage Reference Configuration bits
ADCON2bits.CSCNA=0; // Scan Input Selections for CH0+ S/H Input for MUX A Input Multiplexer Setting bit
ADCON2bits.CHPS=0b00; // Selects Channels Utilized bits, 00 = Converts CH0
//ADCON2bits.BUFS=0; // Buffer Fill Status bit
ADCON2bits.SMPI=0b0000; // 0000 = Interrupts at the completion of conversion for each sample/convert sequence
ADCON2bits.BUFM=0; // Buffer Mode Select bit,0 = Buffer configured as one 16-word buffer ADCBUF(15...0.)
ADCON2bits.ALTS=0; // Alternate Input Sample Mode Select bit 0 = Always use MUX A input multiplexer settings
ADCON3bits.SAMC=0b0100; // Auto-Sample Time bits 11111 = 31 TAD,,,00001 = 1 TAD
ADCON3bits.ADRC=0; // A/D Conversion Clock Source bit, 0 = Clock derived from system clock
ADCON3bits.ADCS=0b00100; // A/D Conversion Clock Select bits, TCY/2 • (ADCS<5> + 1)
//ADCHS A/D Input Select Register
//ADCHSbits.CH123NB=; // Channel 1, 2, 3 Negative Input Select for MUX B Multiplexer Setting bits
//ADCHSbits.CH123SB=; // Channel 1, 2, 3 Positive Input Select for MUX B Multiplexer Setting bit
//ADCHSbits.CH0NB=; // Channel 0 Negative Input Select for MUX B Multiplexer Setting bit
//ADCHSbits.CH0SB=; // Channel 0 Positive Input Select for MUX B Multiplexer Setting bits
//ADCHSbits.CH123NA=; // Channel 1, 2, 3 Negative Input Select for MUX A Multiplexer Setting bits
//ADCHSbits.CH123SA=; // Channel 1, 2, 3 Positive Input Select for MUX A Multiplexer Setting bit
ADCHSbits.CH0NA=0; // MUX A, 0 = Channel 0 negative input is VREFbit
ADCHSbits.CH0SA=0; // Channel 0 Positive Input Select for MUX A, 0 = Channel 0 positive input is AN0
// ^ESTE ES EL IMPORTANTE. SELECIONA PIN DE ENTRADA
//ADPCFG=; // A/D Port Configuration Register
ADPCFGbits.PCFG0=0; //definir pin como analogico
// ADPCFGbits.PCFG1=0;
// ADPCFGbits.PCFG2=0;
// ADPCFGbits.PCFG3=0;
//ADCSSL=; // A/D Input Scan Select Register ????????
ADCSSLbits.CSSL0=1; // A/D Input Pin Scan Selection bits
ADCSSLbits.CSSL1=1; // A/D Input Pin Scan Selection bits
ADCSSLbits.CSSL2=1; // A/D Input Pin Scan Selection bits
ADCSSLbits.CSSL3=1; // A/D Input Pin Scan Selection bits
ADCON1bits.ADON=1; // A/D Operating Mode bit, PONER AL FINAL
//result=ADCBUF0;
}
-
//PROHIBIDO PREGUNTAR, SUERTE.
Qué mala suerte, si está prohibido.
-
es que no tengo ni idea del asunto.
-
Aquí otro ejm para el ADC con el 30f4011, muestrea solo la entrada AN0.
Este es el programa principal
#include <p30f4011.h>
#include <uart.h>
#include <timer.h>
#include <adc10.h>
#include <libpic30.h>
#include <stdio.h>
char orden;
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void);
void configUART1();
void configADC10();
void configT1();
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void)
{ // interrupción cada 10mseg
T1CONbits.TCKPS = 2; /* Prescaler = 64 */
orden='B';
IFS0bits.T1IF = 0; /* borra el flag del timer1 */
}
int main(void)
{
unsigned int result;
configUART1();
configADC10();
configT1();
_TRISD1=0; _RD1=0; //RD1=0
printf("\n\rEmpieza la conversion\n\r");
ADCON1bits.ADON = 1; // prende el módula AD
orden='X';
while (1)
{
if (orden=='B')
{ // convierte ADC, chanel 0, entrada AN0
ADCON1bits.SAMP = 1; // comienza el muestreo y conversión automática
while (_DONE==0);
result = ReadADC10(0); // lee buffer0 o AN0
printf(" %u",result);
orden='X';
}
}
}
Y esta es la configuración del módulo AD, bit a bit;
void configADC10()
{
ConfigIntADC10(ADC_INT_DISABLE);
ADPCFG=0xFFFE; // RB0=AN0 entrada analógica
// config ADCON1
_ADON=0; // A/D converter is off (bit15)
_ADSIDL=1; // detención del módulo en modo IDLE (bit13)
ADCON1bits.FORM=0; // Formato Entero (bit 8-9)
ADCON1bits.SSRC=7; // conversión automática después del muestreo (bit 5-6-7)
_SIMSAM=0; // muestrea múliples canales individualmente en forma secuencial (bit 3)
_ASAM=0; // la captura se inicia cuando el bit SAMP se pone a uno (bit 2)
_SAMP=0; // los amplificadores de muestreo y retención no toman muestras (bit 1)
_DONE=0; // bit de estado de conversión 1.- finalizada (bit 0)
// config ADCON2
ADCON2bits.VCFG=0; // Vref+ =AVdd; Vref- =AVss (bit 13-14-15)
_CSCNA=0; // entradas no exploradas (bit10)
ADCON2bits.CHPS=0; // convierte el canal CH0 (bit 8-9)
_BUFS=0; // no tiene importancia, el dato es de 16 bits (bit 7)
ADCON2bits.SMPI=0; // genera interrupción con la primera secuencia de muestreo y conversión (bit 2-3-4-5)
_BUFM=0; // buffer configurado como palabra de 16 bits (bit 1)
_ALTS=0; // siempre usa el MUXA (bit 0)
// config ADCON3
ADCON3bits.SAMC=1; // Tiempo de muestreo automático =1*TAD (bit 8-9-10-11-12)
_ADRC=0; // señal de reloj obtenida del reloj del sistema (bit 7)
ADCON3bits.ADCS=7; // reloj de conversión = 7*TAD (bit 0-1-2-3-4-5-6)
// config ADCHS
ADCHS=0; // seleciona canal 0, entrada AN0, MUXA
// config ADCSSL
ADCSSL=0; // No seleciona canal
}