AD7730: No se puede comunicar a través de SPI

0

He intentado comunicarme con este dispositivo sin éxito. Alguien tiene algún consejo. O alguien ha trabajado con éxito con él. Implementé hasta ahora solo una función de lectura y escritura y el código psuedo aquí debajo.

Tabla XX. Pseudocódigo para configurar AD7730 para la conversión continua y la operación de lectura continua

Write 02 Hex to Serial Port / * Escribe en el registro de comunicaciones. Próxima operación como Write to Mode Register * /

Escriba 2180 Hex to Serial Port / * escribe en el registro de modo, iniciando conversiones continuas de 0 mV a +10 mV Rango de entrada * /

Escriba 21 hexadecimal en puerto serie / * Escrituras en el registro de comunicaciones Configuración de la siguiente operación como lectura continua desde el registro de datos * /

Establezca la línea DIN de AD7730 baja / * Asegura que la parte no se reinicie mientras esté en modo de lectura continua * /

READ_DATA: Espere RDY Low / * Espere a que el pin RDY baje para indicar Actualización de salida * /

Lectura de datos de 24 bits del puerto serie / * Resultado de conversión de lectura del registro de datos de AD7730 * /

Repita hasta READ_DATA hasta que todos los datos se recopilen

Escriba 30 hex. a puerto serie / * Finaliza la operación de lectura continua y coloca la parte en el modo en que espera la escritura en el registro de comunicaciones * /

Mi código de lectura y escritura

unsigned long AD7730_readRegistry(uint8_t regAddress, int bytes){

    uint8_t data[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
    unsigned long receivedData = 0x00;

    data[0] = CR_SINGLE_R|AD7730_COMM_ADD(regAddress);
    spi_write(data[0]);
    spi_read(data, bytes);

    if(bytes == 3){
        receivedData += ((unsigned long)data[0] << 16);
        receivedData += ((unsigned long)data[1] << 8);
        receivedData += ((unsigned long)data[2]);
    }
    if(bytes == 2){
        receivedData += (data[0] << 8);
        receivedData += (data[1]);
    }
    if(bytes == 1){
        receivedData += (data[0]);
    }
    return receivedData;
} 

void AD7730_writeRegistry(uint8_t regAddress, uint32_t regValue, int bytes){

    uint8_t data[5] = {0x00, 0x00, 0x00, 0x00, 0x00};

        data[0] = CR_SINGLE_W|AD7730_COMM_ADD(regAddress);
        if(bytes == 3){
            data[3] = ((regValue  & 0x0000FF));
            data[2] = ((regValue >> 8) & 0x00FF00);
            data[1] = ((regValue >> 16) & 0xFF0000);
        }
        if(bytes == 2){
            data[2] = ((regValue & 0x0000FF));
            data[1] = ((regValue >> 8) & 0x00FF00);
        }
        if(bytes == 1){
            data[1] = regValue;
        }
        for(int i = 0; i < bytes; i++){
             spi_write(data[i]);
        }
}

int main(void)
{

    Config32MHzClock_Ext16M();

    init_stream(F_CPU);
    AD7730_spi_init();
    AD7730_hardwareReset();
    sei();

    AD7730_writeRegistry(AD7730_MODE_REG, 0x2180, 2);
    AD7730_writeRegistry(AD7730_DATA_REG, CR_START_CONT, 1);
    PORTD.OUTCLR = SPI_MOSI_bm;

    while (1) 
    {   
            AD7730_readRegistry(AD7730_DATA_REG, 3);
            AD7730_WaitReady();
    }
}

hoja de datos enlace

ACTUALIZACIÓN !!!! Estas dos funciones configuran el dispositivo en cualquier modo y lectura continua.

// Modo específico de escritura

 void AD7730_SetMode(unsigned short modeOperation, unsigned char    nputRange,  unsigned char channel)
  {unsigned short oldRegisterVal = 0x0;
  unsigned short newRegisterVal = 0x0;

oldRegisterVal = AD7730_GetRegisterValue(AD7730_COMM_ADDR(AD7730_REG_MODE),2);
newRegisterVal = oldRegisterVal & ~(AD7730_MODE_SEL(0x07) |AD7730_MODE_RANGE_SEL(0x03) |AD7730_MODE_CHANNEL_SEL(0x03) );
newRegisterVal = newRegisterVal |modeOperation |inputRange |channel;
AD7730_SetRegisterValue(AD7730_COMM_ADDR(AD7730_REG_MODE), newRegisterVal, 2);
}

// Devuelve el promedio de varias conversiones

 unsigned long AD7730_ContinuousReadAvg(unsigned char channel, unsigned char inputRange, unsigned char sampleNumber)
{
unsigned char registerWord[4] = {0};
unsigned long samplesAverage = 0;
unsigned char count = 0x00;

AD7730_SetMode(AD7730_MODE_SEL(AD7730_MODE_CONT_CONV), inputRange, channel);
registerWord[0] = 0x01;
registerWord[1] = AD7730_COMM_RW(AD7730_COMM_START_CONT_RD) | AD7730_COMM_ADDR(AD7730_REG_DATA);
spi_write(registerWord, 1);

for(count = 0; count < sampleNumber;count ++)
{
    registerWord[0] = 0x01;
    registerWord[1] = 0x0;
    registerWord[2] = 0x0;
    registerWord[3] = 0x0;
    AD7730_WaitReady();
    spi_read(registerWord, 3);
    samplesAverage += ((unsigned long)registerWord[0] << 16) + ((unsigned long)registerWord[1] << 8) + registerWord[2];
}
samplesAverage = samplesAverage / sampleNumber;
registerWord[0] = 0x01;
registerWord[1] = AD7730_COMM_RW(AD7730_COMM_STOP_CONT_RD) | AD7730_COMM_ADDR(AD7730_REG_COMM);
spi_write(registerWord, 1);

return(samplesAverage);
}

Jugando con el código leyendo las señales en un osciloscopio. Un problema que noté durante una sola lectura es que la salida lista no emite pulsos o señales de que los datos están listos para ser leídos. Seguiré publicando actualizaciones.

    

1 respuesta

1

1) AD7730_writeRegistry para datos de 2 bytes de longitud pone bytes en [2], [3]. Si no me equivoco, debería ser [1] y [2]

2) AD7730_writeRegistry (AD7730_DATA_REG, CR_START_CONT, 1); Esto no tiene sentido.

Primero, la lectura continua se establece al escribir 21 en el registro de comunicaciones, no en el registro de datos. Su función AD7730_writeRegistry siempre escribe CR_SINGLE_W (es decir, escritura única) en el registro de comunicaciones.

Segundo, tienes que decidir si usas lectura continua o única. En la lectura continua no puede hacer nada más que leer el mismo registro una y otra vez. Y no puede usar su AD7730_readRegistry para esto, porque intenta escribir en el registro de comunicaciones en cada llamada.

Tercero, la línea de espera para RDY debe ser antes de la lectura en el bucle, no después. De lo contrario, leerás datos no válidos.

Cuarto, no estoy seguro de que PORTD.OUTCLR sea suficiente para mantener la línea MOSI baja, como se recomienda para la operación de lectura continua. Sospecho que la próxima llamada a spi_read comenzará a marcar el último byte transmitido. Esperamos que sea el mismo comando "iniciar cont. Leer registro de datos", por lo que no debería reiniciar el AD7730.

    
respondido por el Maple

Lea otras preguntas en las etiquetas