cancel
Showing results for 
Search instead for 
Did you mean: 

hmc5611-01ba03 sensor with i2c _ stm32f407

mohamad_armoon
Associate III
Posted on April 25, 2014 at 10:58

hi every body.

i have ahmc5611-01ba03 barometric pressure sensor and i want to get temperature and pressure from it. i connected to my stm32f047 Discovery board through i2c. i implemented all of things that is mentioned in datasheet but it doesn't give me any data all data i received is 0 . what can i do for this problem . please help me, thanks a lot. here is my coed :

void
writeByte(uint8_t devAdd,uint8_t address,uint8_t value);
void
I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction);
void
I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx);
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx);
void
baro_reset();
void
baro_readPROM();
void
inti_RCC()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/******************************************************/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
}
void
init_I2C1(
void
){
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
// we are going to use PB6 and PB7
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; 
// set output to open drain --> the line has to be only pulled low, not driven high
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_Init(GPIOB, &GPIO_InitStruct); 
// Connect I2C1 pins to AF 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); 
// SCL
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); 
// SDA
// configure I2C1 
I2C_DeInit(I2C1);
I2C_InitStruct.I2C_ClockSpeed = 100000; 
// 100kHz
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; 
// I2C mode
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; 
// 50% duty cycle --> standard
I2C_InitStruct.I2C_OwnAddress1 = 0x00; 
// own address, not relevant in master mode
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; 
// disable acknowledge when reading (can be changed later on)
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
// set address length to 7 bit addresses
I2C_Init(I2C1, &I2C_InitStruct); 
I2C_Cmd(I2C1, ENABLE);
}
void
ms_5611_initialize()
{
baro_reset();
Delay(0xFFFFFF);
baro_readPROM();
}
int
main()
{
inti_RCC();
init_I2C1();
init_usart();
ms_5611_initialize();
startConversion(0x48);
Delay(0xFFF);
while
(1)
{
I2C_start(I2C1 , MS5611_DevAddr , I2C_Direction_Transmitter);
I2C_write(I2C1,0x00);
I2C_stop(I2C1);
I2C_start(I2C1,(MS5611_DevAddr)|1 , I2C_Direction_Receiver);
I2C_AcknowledgeConfig(I2C1, ENABLE);
baro_data[0] = I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, ENABLE);
baro_data[1] = I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, DISABLE);
baro_data[2] = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
USART_SendData(USART2,baro_data[0]);
Delay(0xffff);
USART_SendData(USART2,baro_data[1]);
Delay(0xffff);
USART_SendData(USART2,baro_data[2]);
Delay(0xffff);
}
}
void
writeByte(uint8_t devAdd,uint8_t address,uint8_t value)
{
I2C_start(I2C1, devAdd , I2C_Direction_Transmitter);
I2C_write(I2C1,address);
I2C_write(I2C1,value);
I2C_stop(I2C1);
}
void
I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction)
{
while
(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2Cx, ENABLE);
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2Cx, address, direction);
if
(direction == I2C_Direction_Transmitter){
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
GPIO_SetBits(GPIOD, GPIO_Pin_13);
}
else
if
(direction == I2C_Direction_Receiver){
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
}
}
void
I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
I2C_SendData(I2Cx, data);
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
void
I2C_stop(I2C_TypeDef* I2Cx)
{
I2C_GenerateSTOP(I2Cx, ENABLE);
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx)
{
I2C_AcknowledgeConfig(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
uint8_t data = I2C_ReceiveData(I2Cx);
return
data;
}
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
// enable acknowledge of recieved data
I2C_AcknowledgeConfig(I2Cx, ENABLE);
// wait until one byte has been received
while
( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
// read data from I2C data register and return data byte
uint8_t data = I2C_ReceiveData(I2Cx);
return
data;
}
void
baro_reset()
{
//writeByte(MS5611_DevAddr,MS561101BA_RESET,
I2C_start(I2C1, MS5611_DevAddr , I2C_Direction_Transmitter);
I2C_write(I2C1,0x1E);
I2C_stop(I2C1);
}
void
baro_readPROM()
{
uint8_t temp[6];
for
(
int
i=0;i<6;i++) {
I2C_start(I2C1, MS5611_DevAddr , I2C_Direction_Transmitter);
I2C_write(I2C1,0xA2 + (i * 2));
I2C_stop(I2C1);
I2C_start(I2C1, MS5611_DevAddr|1 , I2C_Direction_Receiver);
temp[i] = I2C_read_nack(I2C1); 
USART_SendData(USART2,temp[i]);
Delay(0xFFF);
}
}

5 REPLIES 5
Posted on April 25, 2014 at 13:38

There is a status bit for the USART to indicate the register is empty, use that, not random delays.

You are sending binary data via the USART, does the terminal understand this, or would sending hex or decimal ASCII work better?

MS5611_DevAddr

is not defined
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mohamad_armoon
Associate III
Posted on April 26, 2014 at 09:10

thank clive for answering to my problem.

i2c always was one of my problem . i solved it, problem was the order of sending a value to start the conversion of the sensor and other value which starts adc in ms5611. i will put the complete code here.

my terminal gets data as hex ans char and because i wrote that i can change it to every thing i want.

about that status bit you mentioned which can indicate empty register in usart  . i put delay because if i didn't ,all of my USART_SendData functions sometimes worked and sometimes some of them don't.

can you explain more about that status bit, because i solved my problem with interrupt and some time when i'm busy i just use this for example :

if(USART_GetITStatus(USART2, USART_IT_RXNE) == RESET)

      USART_SendData(USART2,baro_data[2]); 

about that variable, i defined it in my header and i forgot to write it in my code here .

thanks in advance.

Posted on April 26, 2014 at 14:18

  while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); // Spin until empty

  USART_SendData(USART2, ch);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lyonlui
Associate
Posted on June 28, 2014 at 15:36

hey,fellow

I am using stm32 103 and ms5611-01 make a altimeter。

and i also have some problem with I2C.

could you please send you successful soures code to me as reference?

thank you very much!!

lyonlui
Associate
Posted on June 28, 2014 at 15:47

hey,fellow

I am using stm32 103 and ms5611-01 make a altimeter。

and i also have some problem with I2C.

could you please send you successful soures code to me as reference?

thank you very much!!