Leer / escribir un sensor de aceleración (ADXL345) con STM8

0

Compré una pequeña tabla con un sensor de aceleración (ADXL345) y ahora trato de escribir mis funciones para comunicarme con el IC. Yo uso un STM8S103F3P6 como controlador y ST Visual Develop como IDE. Así que al principio eché un vistazo al "esquema del borde ascendente / descendente":

Asíquealprincipioquieroescribirlafunción"writeCommand", se ve así, actualmente:

void writeCommand(uint16_t cmd){
    uint8_t i,k;
    GPIOD->ODR |= (1<<SDIO); //turn SDIO HIGH to turn it LOW later

    GPIOD->ODR &= ~(1<<CS); //turn CS LOW
    delay_ms(2);
    GPIOD->ODR &= ~(1<<SCLK); //turn SCLK LOW

    for(k = 0; k < 2; k++){ //proceed with toggling R/W and multiple-byte bit
        GPIOD->ODR ^= (1<<SDIO);
        delay_ms(1);
        GPIOD->ODR |= (1<<SCLK);
        delay_ms(1);
        GPIOD->ODR &= ~(1<<SCLK);
    }

    for(i = 0; i < 15; i++){ //start writing data
        if(cmd & 128){
            GPIOD->ODR |= (1<<SDIO);
        } else {
            GPIOD->ODR &= ~(1<<SDIO);
        }
        GPIOD->ODR |= (1<<SCLK);
        cmd << 1;
        GPIOD->ODR &= ~(1<<SCLK);
    }
    delay_ms(1);
    GPIOD->ODR |= (1<<CS);
}

Me pregunto por qué solo hay 6 (A5 ... A0) bits de dirección. No estoy seguro de cómo concatenar el registro en el que quiero escribir y los datos.

¿Sería esta la manera correcta de llamar a mi función?

writeCommand(0x2C << 8 | 0x09); //write 1001 to 0x2C register

Sé que probablemente sea posible hacerlo con hardware SPI, pero quiero aprender a hacerlo mediante software. Quizás algunas preguntas suenen con retraso, pero espero que todavía las contestes :)

    
pregunta binaryBigInt

1 respuesta

0

¿Miraste la hoja de datos? Ninguna de las direcciones de registro excede los 6 bits, por lo que no debe preocuparse por no tener 8. Además, los 2 bits adicionales se utilizan para indicar el acceso de lectura / no escritura y multibyte.

Su comando de escritura coincide con su función (16 bits a la vez), pero realmente no hay manera de que pueda hacer el acceso multibyte con él. Tal vez sería útil una función más genérica (una que pueda llevar un puntero a un búfer como argumento, junto con la longitud de transferencia).

Si desea escribir 0x09 para registrar 0x2C, el comando debería estar bien. Sin embargo, aún sugeriría usar los controladores SPI del SDK en lugar de escribir los suyos propios.

Para combinar varios campos, deberá hacer algo como esto:

#define WRITE (0 << 7)
#define READ  (1 << 7)
#define MB    (1 << 6)

Luego, para formar los 16 bits que harías:

uint16_t read_message = ((READ | addr) << 8) | garbage;
uint16_t write_message = ((WRITE | addr) << 8) | data;

Si desea emitir un mensaje de lectura multibyte, su primer byte se convertirá en:

uint8_t read_multibyte = READ | MB | addr;

Para expandir mi comentario anterior sobre una función más genérica, y una que te permitiría usar comandos multibyte, podrías hacer algo como esto:

void sendCommand(uint8_t * buffer, uint8_t length)
{
   for (int i = 0; i < length; i++)
   {
      sendByte(buffer[i]);
   }
}

void sendByte(uint8_t byteToSend)
{
   // Put an 8-bit of your SPI function here
}

Entonces los datos que envíes pueden convertirse en:

buffer[0] = READ | MB | addr;
// The rest of the buffer doesn't matter since we are reading
sendCommand(buffer, 4); // Will receive 3 bytes

También es posible que desee utilizar corchetes para facilitar la lectura de sus comandos y eliminar cualquier posible error debido al orden de las operaciones.

    
respondido por el Catsunami

Lea otras preguntas en las etiquetas