Received data not get into the variable
Hi everybody!
I have an STM32F411RE Nucleoboard and an ADXL345-M accelerometer. I have 2 problems.
- I want to read 1 byte data from the accelerometer. In this case I want to get he device id (0xe5) and store it in a variable. In debug mode it seems that the device id gets into the data register, but when I want to store it in a variable nothing happens.
- When I debug my code and if I stay a bit more time on a line where I'm waiting e.g. for the ADDR=1 (while(!(I2C1->SR1 & I2C_SR1_ADDR)) {}), after click to "Step Over" it seems that it get's into an endless loop.
I attach my code and a picture about register values.
Thank you in advance for your help!
Best regards,
Martin
void I2C_Init(void) {
//I2C_1 SCL: PB8
//I2C_1 SDA: PB9
//Enable clock access to I2C
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
//Enable clock access to GPIOB
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
//Set alternate function mode AF04
GPIOB->MODER &= ~(0x3 <<16);
GPIOB->MODER |= (0x2<<16);
GPIOB->MODER &= ~(0x3 <<18);
GPIOB->MODER |= (0x2<<18);
GPIOB->AFR[1] &= ~(0xF<<0);
GPIOB->AFR[1] |= (0x4<<0);
GPIOB->AFR[1] &= ~(0xF<<4);
GPIOB->AFR[1] |= (0x4<<4);
//Set output open-drain
GPIOB->OTYPER |= GPIO_OTYPER_OT8;
GPIOB->OTYPER |= GPIO_OTYPER_OT9;
//Enable pull up resistor
GPIOB->PUPDR &= ~(0x3 <<16);
GPIOB->PUPDR |= (0x1<<16);
GPIOB->PUPDR &= ~(0x3 <<18);
GPIOB->PUPDR |= (0x1<<18);
//Enable peripheral
I2C1->CR1 |= I2C_CR1_PE;
//Enable acknowledge
I2C1->CR1 |= I2C_CR1_ACK;
//Set clock frequency (16 MHz)
I2C1->CR2 |= (1<<4);
//Set CCR
I2C1->CCR |= (0x50<<0);
//Set TRISE to 16+1
I2C1->TRISE = 17;
}
void I2C_read_1_byte(char slave_addr, char mem_addr, char* data) {
volatile int temp;
//Wait for bus
while(I2C1->SR2 & I2C_SR2_BUSY){}
//Send START
I2C1->CR1 |= I2C_CR1_START;
//Wait for SB
while(!(I2C1->SR1 & I2C_SR1_SB)) {}
//Write slave address to DR | 1
I2C1->DR = slave_addr << 1;
//Wait for ADDR
while(!(I2C1->SR1 & I2C_SR1_ADDR)) {}
//Clear ADDR
temp = I2C1->SR1;
temp = I2C1->SR2;
//Wait for TRxE
while(!(I2C1->SR1 & I2C_SR1_TXE)) {}
//Set register address
I2C1->DR = mem_addr;
//Wait for TRxE and BTF
while(!(I2C1->SR1 & I2C_SR1_TXE)) {}
//Generate restart
I2C1->CR1 |= I2C_CR1_START;
//Wait for SB
while(!(I2C1->SR1 & I2C_SR1_SB)) {}
//Write slave address to DR
I2C1->DR = slave_addr << 1 | 1;
//Wait for ADDR
while(!(I2C1->SR1 & I2C_SR1_ADDR)) {}
//Send NACK
I2C1->CR1 &= ~I2C_CR1_ACK;
//Clear ADDR
temp = I2C1->SR1;
temp = I2C1->SR2;
//Wait for RxNE
while(!(I2C1->SR1 & I2C_SR1_RXNE)) {}
//Send STOP
I2C1->CR1 |= I2C_CR1_STOP;
//Read data
*data = I2C1->DR;
}
int main(void)
{
uint8_t id[0];
I2C_Init();
while(1) {
I2C_read_1_byte(SLAVE_ADDR, DEV_ID, (char*) id);
}
}
