Actualmente intento leer un registro de un sensor de aceleración (ADXL345). Intento simular el procedimiento SPI con software. Escribí una función readRegister
:
uint8_t readRegister(uint8_t reg) {
uint8_t i, k;
uint8_t res = 0;
GPIOD->ODR &= ~(1<<CS);
delay_ms(2);
// write register address
GPIOD->DDR |= (1<<SDIO); // SDIO as output
for(i=0; i<8; i++) {
GPIOD->ODR &= ~(1<<SCLK);
if(reg & (1<<7)) {
GPIOD->ODR |= (1<<SDIO);
} else {
GPIOD->ODR &= ~(1<<SDIO);
}
delay_ms(1);
GPIOD->ODR |= (1<<SCLK);
delay_ms(1);
reg <<= 1;
}
// read result
GPIOD->DDR &= ~(1<<SDIO); // set SDIO as input
for(k=0; k<8; k++) { // loop over data bits
res <<= 1;
GPIOD->ODR &= ~(1<<SCLK);
delay_ms(1);
GPIOD->ODR |= (1<<SCLK);
if(GPIOD->IDR & (1<<SDIO)) {
res |= 1;
}
delay_ms(1);
}
GPIOD->ODR |= (1<<CS);
return res;
}
La función devuelve 227
(así que 11100011
) en lugar de 119
( 01110111
) a pesar de que le escribí 119
con este código:
void enableADXL345(){
uint8_t write;
uint8_t addr;
uint8_t data;
uint8_t result;
uint16_t write_command;
uint8_t read_command;
addr = 0x31;
data = 0x04;
write_command = (write | addr) << 8 | data; //set SPI 3-wire
writeCommand(write_command);
addr = 0x27;
data = 0x77;
write_command = (write | addr) << 8 | data; //write something
writeCommand(write_command);
read_command = (0b10000000 | addr);
result = readRegister(read_command); //read something
}
Esta es mi función write
:
void writeCommand(uint16_t cmd){
uint16_t i;
GPIOD->ODR &= ~(1<<CS);
delay_ms(2);
GPIOD->DDR |= (1<<SDIO); //SDIO as output
for(i = 0; i < 16; i++){ //start to transfer the register we want to read
GPIOD->ODR &= ~(1<<SCLK);
if(cmd & (1<<7)){
GPIOD->ODR |= (1<<SDIO);
} else {
GPIOD->ODR &= ~(1<<SDIO);
}
GPIOD->ODR |= (1<<SCLK);
delay_ms(1);
cmd <<= 1;
}
GPIOD->ODR |= (1<<CS);
}
Este es el SPI-lectura / escritura como se describe en la hoja de datos: