problema con la lectura de valores en caso

-5

Estoy usando el microcontrolador ATmega32-A y el compilador CodeVisionAVR. Puedo leer los valores de un AD7798 ADC externo con éxito. También estoy generando wave desde con un AD9833 utilizando la comunicación SPI. Estoy pasando la señal generada a un sensor, así como a un ADG1408-EP multiplexor. Utilizo el multiplexor para enviar la entrada de la forma de onda al sensor o la salida del sensor al ADC externo para la conversión.

Aquí hay un esquema simplificado:

Heescritoelsiguientecódigo:

unsignedadc,RawData,WaveFreq,WavePhase;unsignedintmux1,mux2;floatv1,v2,Analog_Voltage;voidrunCom(void){switch(Command){case(INF):RawData=readADC();printf("ADC RawData:%d\r\n", RawData);
            Analog_Voltage = voltage(RawData);
             printf("Demodulator Voltage Level:%f [v]\r\n",Analog_Voltage);
            Command = 0;
            break;

        case(WGF):
            if(Param < 500)
                SetWGFreq(Param);
            WaveFreq = Param;
            Command = 0;
            break;

        case(MUXSEL):
            printf("MUX selection. ");
            selcase(WaveFreq);
            Command = 0;
            break;
        default:
            Command = 0;
            break;
    }
}

void selcase(unsigned int arg)
{
    unsigned char c;
    c = getchar();

    switch(c){

        case '1':
            PORTB=0x00;
            SetWGFreq(arg);
            Delay(1000);
            mux1 = readADC();
            printf("muxchanel 1 ADC RawData:%d\r\n",mux1);
            v1 = voltage(mux1);
            printf("Muxchanel 1 Demodulator Voltage Level:%f [v]\r\n",v1);
            Command = 0;
            break;

        case '2':
            PORTB=0x04;
            SetWGFreq(arg);
            Delay(1000);
            mux2 = readADC();
            printf("muxchanel 2 ADC RawData:%d\r\n",mux2);
            v2 = voltage(mux2);
            printf("Muxchanel 2 Demodulator Voltage Level:%f [v]\r\n",v2);
            Command = 0;
            break;
        default:
            Command = 0;
            break;
    }
}

Desde el código anterior, puedo leer un valor convertido del ADC correctamente. Pero el problema es cuando cambio el multiplexor al canal 2 y leo el valor de ADC después de haber leído el valor de ADC del canal 1, leí el mismo valor que recibí para el canal 1.

Si leo el valor ADC del canal 2 dos veces seguidas, la segunda vez que lo leo es el valor correcto.

He intentado imprimir el valor de readADC en el comando INF . Estaba imprimiendo exactamente, no hay necesidad de entrar en el caso dos veces. En el comando INF , estaba dando exactamente el valor correcto cuando cambio el canal del multiplexor y lo verifiqué con el comando INF . Los valores están cambiando tan rápidamente cuando ingreso a la selección del multiplexor.

El único problema es en el caso del interruptor anidado. Estoy intentando imprimir valores de ADC, pero debo ingresar el caso dos veces para obtener el valor correcto. He intentado con la función de retardo también, pero el problema sigue siendo el mismo.

¿Por qué necesito realizar dos lecturas para obtener el resultado de conversión de canal del multiplexor correcto?

    
pregunta verendra

2 respuestas

0

Creo que tu problema está en esta línea:

while ((statusreg & 0x80) != 0);

Sinceramente, no estoy seguro de cómo funciona eso. Puede que se esté optimizando.

Lo que dice esa línea es: "mientras este bit en esta variable está establecido, no haga nada". Pero nunca estás actualizando la variable. Por lo tanto, si se configuró cuando entró, debería repetirse para siempre. Si se eliminó cuando se ingresó, debería pasar directamente. Lo que quieres es algo más como esto:

unsigned int readADC(void)
{
    init_io();

    AD7798_16(0x10, 0x0010);
    value = AD7798_16(0x50, 0xFFFF);
    while ((read_status() & 0x80) != 0)
    {
        #asm("nop");              //Or however you call assembly nop in CodeVision
    }
    adc = AD7798_16(0x58, 0xFFFF);
    return adc;
}

unsigned int read_status(void)
{
    return AD7798_8(0x40, 0xFF);;
}

De esa manera, leerá continuamente el registro de estado hasta que la conversión esté lista. El nop debería evitar que el compilador optimice el bucle que parece que está haciendo.

Es posible que también desee cambiar a usar el Modo de conversión única en su ADC. Eso debería ayudar a garantizar que inicie y complete una nueva conversión cada vez que cambie de canal. Por lo tanto, debería ayudar a evitar leer los resultados de conversiones anteriores.

    
respondido por el embedded.kyle
0

La solución para la publicación anterior es, tengo que configurar el retardo adecuado entre la selección de mux y la lectura ADC. La función de retardo que he usado en el código anterior no funciona. Ahora lo he cambiado. Su funcionamiento.

He cambiado el retraso como

delay_ms(100);
    
respondido por el verendra

Lea otras preguntas en las etiquetas