2020-02-15 06:47 AM
I'm trying to read temperature data in realtime , here is my code
#include "stm32f10x.h"
#include "LCD.h"
#include "MPU_6050.h"
void I2C_init(void);
void I2C_write(uint8_t devAddress, uint8_t regAddress, uint8_t data);
void I2C_read(uint8_t devAddress, uint8_t regAddress, uint8_t *data);
int main()
{
RCC->APB2ENR |= PORTB;
initPin(GPIOC, PIN14);
initTimers();
initLCD();
I2C_init();
uint8_t tempH = 0;
uint8_t tempL = 0;
int16_t temp = 0;
while(1)
{
I2C_read(MPU6050_W, MPU6050_RA_TEMP_OUT_H, &tempH);
waitMs(2);
I2C_read(MPU6050_W, MPU6050_RA_TEMP_OUT_L, &tempL);
waitMs(2);
temp = (tempH<<8)|tempL;
temp /= 340;
temp += 36;
printNumber(temp);
}
}
void I2C_init(void)
{
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
I2C1->CR2 |= 36;
I2C1->CCR |= 180;
I2C1->TRISE |= 37;
// enable ACK
I2C1->CR1 |= I2C_CR1_ACK;
// set PORTB PB6, PB7 alternate function
GPIOB->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_MODE6;
GPIOB->CRL |= GPIO_CRL_CNF7 | GPIO_CRL_MODE7;
// enable peripheral
I2C1->CR1 |= I2C_CR1_PE;
// MPU6050_RA_PWR_MGMT_1 = 0x6B
I2C_write (MPU6050_W, MPU6050_RA_PWR_MGMT_1, 0b00000000);
}
void I2C_write(uint8_t devAddress, uint8_t regAddress, uint8_t data)
{
while((I2C1->SR2 & I2C_SR2_BUSY) == I2C_SR2_BUSY);
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
(void) I2C1->SR1;
// by writing DR clear SB flag and send address
I2C1->DR = devAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
// clear ADDR flag
(void)I2C1->SR1;
(void)I2C1->SR2;
// send slave register address
I2C1->DR = regAddress;
while(!(I2C1->SR1 & I2C_SR1_TXE));
// send data and clear TXE flag
I2C1->DR = data;
while(!(I2C1->SR1 & I2C_SR1_BTF));
// send stop
I2C1->CR1 |= I2C_CR1_STOP;
while((I2C1->SR2 & I2C_SR2_BUSY) == I2C_SR2_BUSY);
}
void I2C_read(uint8_t devAddress, uint8_t regAddress, uint8_t *data)
{
I2C1->CR1 |= I2C_CR1_ACK;
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
(void)I2C1->SR1;
// send DEV ADDRESS
I2C1->DR = devAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
(void)I2C1->SR1;
(void)I2C1->SR2;
// send register address
I2C1->DR = regAddress;
while(!(I2C1->SR1 & I2C_SR1_TXE));
I2C1->CR1 |= I2C_CR1_STOP;
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
(void)I2C1->SR1;
// send DEVADDRESS in read mode
I2C1->DR = MPU6050_R;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
(void)I2C1->SR1;
(void)I2C1->SR2;
// read DATA + NACK
I2C1->CR1 &= ~I2C_CR1_ACK;
while(!(I2C1->SR1 & I2C_SR1_RXNE));
*data = I2C1->DR;
// send STOP
I2C1->CR1 |= I2C_CR1_STOP;
}
it prints temperature ONLY once i.e reads TEMP_H and TEMP_L, BUT
then when it trying to read TEMP_H again, it stucks inside of I2C_read's start flag loop.
while(!(I2C1->SR1 & I2C_SR1_SB));
What I'm doing wrong? why it's not reading temperature second times?
2020-02-15 07:35 AM
maybe I have wrong frequencies?