cancel
Showing results for 
Search instead for 
Did you mean: 

Received data not get into the variable

MSzal.1
Associate II

Hi everybody!

I have an STM32F411RE Nucleoboard and an ADXL345-M accelerometer. I have 2 problems.

  1. 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.
  2. 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);
	}
}

0693W00000Hp97aQAB.png0693W00000Hp97VQAR.png

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> uint8_t id[0];

"id" is defined as array of length 0. Probably not going to be able to put anything in there. Technically array of constant length 0 aren't allowed, but GCC didn't throw any warnings for me on it with default settings.

I2C protocol requires you to react to certain events quickly enough such that single stepping in the debugger is likely to cause problems. I would suggest finding another method to debug, perhaps through a UART stream or ITM.

The value that you store in "id" is also never used anywhere, so the compiler is free to optimize that out.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

2 REPLIES 2
TDK
Guru

> uint8_t id[0];

"id" is defined as array of length 0. Probably not going to be able to put anything in there. Technically array of constant length 0 aren't allowed, but GCC didn't throw any warnings for me on it with default settings.

I2C protocol requires you to react to certain events quickly enough such that single stepping in the debugger is likely to cause problems. I would suggest finding another method to debug, perhaps through a UART stream or ITM.

The value that you store in "id" is also never used anywhere, so the compiler is free to optimize that out.

If you feel a post has answered your question, please click "Accept as Solution".
MSzal.1
Associate II

Thank you for the answer!:folded_hands:

Indeed the 0 array length was the problem...This is the case when can't see the forest for the trees.=)

All the best!

Martin