Cómo mostrar el valor del potenciómetro desde el microcontrolador dspic33

0

Soy nuevo en el mundo de los microcontroladores y estoy usando un controlador dsPIC33EP256MC506 y una placa de desarrollo dsPICDEM -2 MCLV para un proyecto. Estoy tratando de leer el valor del potenciómetro que está en la placa de desarrollo, pero tengo problemas. Solo quiero poder ejecutar el programa y mover, girar el potenciómetro y ver cómo el programa genera el valor. Sé que tengo que usar los puertos ADC de alguna manera para hacer esto, pero no estoy exactamente seguro de cómo usarlo. La documentación tampoco ha sido muy útil sobre cómo hacer esto en el programa. Si alguien puede dirigirme a la documentación que usa ADC para controlar el potenciómetro o ayudarme a comenzar con esto, sería genial.

Además, ¿alguien sabe dónde se mostrará este valor? Para mí, tiene sentido que se muestre en la pestaña de resultados de Variables, pero no parece que haya ningún valor para ninguna variable.

Microcontrolador: dsPIC33EP256MC506

Placa de desarrollo: dsPICDEM -2 MCLV

Programador / Depurador: REAL ICE

Compilador: MPLAB X - XC16

Gracias de nuevo!

#include <p33Exxxx.h>
/****************************CONFIGURATION****************************/

_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & POSCMD_XT & OSCIOFNC_OFF & IOL1WAY_OFF);
_FWDT(FWDTEN_OFF);
_FPOR(ALTI2C1_ON & ALTI2C2_ON);
_FICD(ICS_PGD1 & JTAGEN_OFF);

void initAdc1(void);
void Delay_us(unsigned int);
int  ADCValue, i;
int  main(void)
{
// Configure the device PLL to obtain 40 MIPS operation. The crystal frequency is 8 MHz.
// Divide 8 MHz by 2, multiply by 40 and divide by 2. This results in Fosc of 80 MHz.
// The CPU clock frequency is Fcy = Fosc/2 = 40 MHz.
PLLFBD = 38;                    /* M  = 40 */
CLKDIVbits.PLLPOST = 0;         /* N1 = 2  */
CLKDIVbits.PLLPRE = 0;          /* N2 = 2  */
OSCTUN = 0;
/* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0x3);
while (_LOCK == 0);             /* Wait for PLL lock at 40 MIPS */
initAdc1();
while(1)
{
    AD1CON1bits.SAMP = 1;         // Start sampling
    Delay_us(10);                 // Wait for sampling time (10 us)
    AD1CON1bits.SAMP = 0;         // Start the conversion
    while (!AD1CON1bits.DONE);    // Wait for the conversion to complete
    ADCValue = ADC1BUF0;          // Read the ADC conversion result
}
}
    void initAdc1(void) {
     /* Set port configuration */ 
     ANSELA = ANSELB = ANSELC  = ANSELE = 0x0000;
    //ANSELBbits.ANSB5 = 1;           // Ensure AN5/RB5 is analog
    ANSELBbits.ANSB0 = 1;
    ANSELAbits.ANSA0 = 1;

// A0 and B0 are inputs
TRISAbits.TRISA0 = 1;
TRISBbits.TRISB0 = 1;

/* Initialize and enable ADC module */

AD1CON1 = 0x0000;
AD1CON2 = 0x0000;
AD1CON3 = 0x000F;
AD1CON4 = 0x0000;
AD1CHS0 = 0x0000;
// 0000 0000 0000 0101
AD1CHS123 = 0x0000;
AD1CSSH = 0x0000;
AD1CSSL = 0x0000;
AD1CON1bits.ADON = 1;
Delay_us(20);
}
void Delay_us(unsigned int delay)
{
for (i = 0; i < delay; i++)
{
    __asm__ volatile ("repeat #39");
    __asm__ volatile ("nop");
}
}
    
pregunta KP123

3 respuestas

1

No estás esperando a que se complete la conversión.

El algoritmo para las operaciones ADC es el siguiente:

  1. Inicializar ADC y Pin para canal analógico
  2. Comience la conversión
  3. Espere a que se complete la conversión
  4. Lea el búfer de resultados cuando se complete la conversión
  5. Vaya al paso 3

En su caso, no está esperando o leyendo el búfer de resultados. Hoja de datos es lo suficientemente útil como para entender los registros.

    
respondido por el Swanand
1

Primero, necesitas sentarte y leer la documentación. Para alguien nuevo, la documentación para el A / D puede tomar un par de horas para revisar y resumir. Date cuenta por adelantado que va a llevar algo de tiempo invertir. Los accesos directos solo hacen que pierdas mucho más tiempo más tarde, como estás viendo.

Para los chips de 16 bits (dsPIC y PIC 24), hay dos partes en la documentación. Los detalles de cualquier periférico se describen en profundidad en el capítulo del Manual de referencia familiar para ese periférico. Vaya a la página del producto para la parte particular que está utilizando para obtener el capítulo de FRM que se aplica a la versión particular del A / D que tiene su chip. Lea eso. Completamente. No hay atajos.

La hoja de datos de la parte luego da los parámetros particulares para el A / D que se describió generalmente en el FRM. Esto incluye cuántos A / D tiene la pieza, cuál es el tiempo mínimo para T AD , cuántos y qué canales analógicos se implementan, etc.

Ahora que entiende el hardware A / D, piensa en cómo usarlo dentro de su aplicación. Estos periféricos son muy flexibles, por lo que cualquier implementación solo usará un subconjunto de las posibles capacidades o modos.

Dado que solo desea obtener lecturas A / D a partir del código de primer plano a solicitud (no es una buena estrategia a largo plazo, pero es aceptable para una demostración rápida), configure A / D para realizar una muestra automática después de que se complete la conversión. De esa manera, solo necesita establecer un bit para obtener la siguiente lectura. Para obtener cada lectura:

  1. Asegúrese de que haya transcurrido suficiente tiempo desde la conversión anterior para un tiempo de muestra suficientemente largo.

  2. Establezca el bit para iniciar una nueva conversión.

  3. Espere a que finalice la conversión.

  4. Lea el resultado A / D.

Nunca hagas esto:

AD1CON1 = 0x0000;
AD1CON2 = 0x0000;
AD1CON3 = 0x000F;
AD1CON4 = 0x0000;
AD1CHS0 = 0x0000;
// 0000 0000 0000 0101
AD1CHS123 = 0x0000;
AD1CSSH = 0x0000;
AD1CSSL = 0x0000;

Los valores de codificación rígidos como este, sin ninguna indicación de lo que significan, son una programación extremadamente irresponsable . No solo son solo números sin ningún indicio de lo que significan los bits, sino que aquí ni siquiera hay un comentario sobre las líneas de asignación. El único comentario que hay es que da un número sin contexto y no tiene sentido.

Tomar atajos con comentarios de código, al igual que los atajos que leen la documentación, es falso ahorro. Hazlo bien. Te ahorrará tiempo. Y, pedirle a otros que vean el código no documentado es simplemente grosero.

    
respondido por el Olin Lathrop
0

También debe detectar cuándo los datos están listos para leer, es decir, cuando el indicador de interrupción de ADC lo indica. Tiene un controlador de interrupción personalizado del formulario void _ISR _NOPSV _ADC1Interrupt (void), o espera a que se establezca el indicador en main (), por ejemplo si (_AD1IF) {/ lee del búfer /}.

Parece que no tienes habilitada una interrupción, lo que iría en la línea _ADC1IE = 1 ;. Si tuviera más tiempo, podría ayudar más, el mejor lugar para comenzar es con la Hoja de datos, habrá hojas de datos específicas para ADC.

    
respondido por el Mike

Lea otras preguntas en las etiquetas