STM8S - Conéctese al sensor de aceleración ADXL345 a través de SPI de hardware

1

Después de que el software SPI no funcionó, ahora intento conectarme al sensor de aceleración ADXL345 a través del hardware SPI del STM8S103F3. Pero, por supuesto, los problemas aparecieron de nuevo, ¿por qué no? Este es mi código de inicio SPI:

void initSPIMaster(){
    GPIOC->DDR = (1<<MOSI) | (1<<SCK) | (0<<MISO); //MOSI & SCK output, MISO input
    GPIOC->CR1 = (1<<MOSI) | (1<<SCK); //MOSI& SCK push-pull

    GPIOA->DDR |= (1<<CS); //set CS as output
    GPIOA->CR1 |= (1<<CS); //set CS as push-pull
    GPIOA->ODR |= (1<<CS); //turn CS high

    SPI->CR2 = 0b00000000; //2-line unidirectional, Hardware-Slave  management
    SPI->CR1 = 0b01111111; //Enable CPHA, CPOL, MASTER; Baudrate: f/256, SPI Enable
}

Esta es mi función SPI-Transmit para escribir datos en DR -Register:

void SPITransmit(uint8_t data){
    while(!(SPI->SR & (1<<1))){
        nop(); //wait until transmit buffer is empty
    }
    SPI->DR = data;
    while((SPI->SR & (1<<7))){
        nop(); //wait until not busy
    }
}

Esta es mi función SPIReceive para leer datos de DR -Register:

uint8_t SPIReceive(){
    uint8_t registerValue;
    while((SPI->SR & (1<<7))){
        nop(); //wait until not busy
    }
    while(!(SPI->SR & (1<<0))){
        nop(); //wait until receive buffer is not empty
    }
    registerValue = (SPI->DR);
    nop();
    return registerValue;
}

Como prueba inicial, intenté leer el registro DEVID del ADXL345 ( 0x00 ), debería devolver 229 como valor decimal. Y, de hecho, lo hizo, esta es mi función para leer un registro:

void getValueFromRegister(uint8_t reg, uint8_t *val){
    uint8_t transmitValue = (0x80 | reg);
    uint8_t receivedValue = 0;

    GPIOA->ODR &= ~(1<<CS); //CS low
    SPITransmit(transmitValue); //write 'read' command
    delay_ms(10);
    receivedValue = SPIReceive();
    GPIOA->ODR |= (1<<CS); //CS high

    delay_ms(10);
    *val = receivedValue;
}

También habilité el ADXL345 con este código:

void initADXL345(){
    //enable measurements
    GPIOA->ODR &= ~(1<<CS); //turn CS low
    SPITransmit(0x2D);
    SPITransmit(0x08);
    GPIOA->ODR |= (1<<CS); //turn CS high
    delay_ms(5);

    //set FULL_RES & 16g-Range
    GPIOA->ODR &= ~(1<<CS); //turn CS low
    SPITransmit(0x31);
    SPITransmit(0b00001011);
    GPIOA->ODR |= (1<<CS); //turn CS high
}

El siguiente paso lógico sería leer los datos de los registros de datos ( 0x32 - 0x37 ), así que lo hice ( x , y , z son valores globales de tipo int16_t ):

void getXYZValues(){
    uint8_t x0,x1,y0,y1,z0,z1;
    getValueFromRegister(0x32, &x0);
    delay_ms(10);
    getValueFromRegister(0x33, &x1);
    delay_ms(10);
    getValueFromRegister(0x34, &y0);
    delay_ms(10);
    getValueFromRegister(0x35, &y1);
    delay_ms(10);
    getValueFromRegister(0x36, &z0);
    delay_ms(10);
    getValueFromRegister(0x37, &z1);

    x = ((x1<<8) | x0);
    y = ((y1<<8) | y0);
    z = ((z1<<8) | z0);
}

El problema ahora es:

¡Siempre obtengo el valor -6683 (decimal) para cada eje! ¡Y este valor ni siquiera cambia si muevo el sensor!

Por el amor de Dios, ¿por qué es tan horrible trabajar con este sensor?

Pensé en que tal vez el problema es CPOL o CPHA pero de acuerdo con la hoja de datos, ambos deberían estar habilitados (como lo hice).

¿Alguna idea, por qué esto no funciona? Estoy realmente frustrado y trato de hacer que funcione durante semanas (si agrego los días desde mi primer intento con el software SPI).

    
pregunta binaryBigInt

0 respuestas

Lea otras preguntas en las etiquetas