2011-08-17 06:57 AM
Hi,
I have been trying now for longer than i care to admit at getting my development board ( STM32F103R ) to talk to a sensor ( HMC5843 ) via I2C. I have gone through the STM32 code examples but they were frankly kind of useless.
I have put in the following code which i pasted together from pages of this forum and what little understanding of this peripheral i have.:
♯♯♯♯♯♯♯♯♯&sharpSTART CODE♯♯♯♯♯♯♯♯♯♯♯♯
&sharpinclude ''stm32f10x.h''
&sharpinclude ''Libs.h''
u16 loop1 = 0,loop2 = 0,loop3 = 0, Loop_Delay = 0; //loops for 1ms interrupts
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
&sharpdefine I2C1_SLAVE_ADDRESS7 0x1E // EEPROM I2C Address
&sharpdefine ClockSpeed 50000 // 50 KHz
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 i2c_var = 123;
/* Private function prototypes -----------------------------------------------*/
void Delay(u16);
void I2C_Setup(void);
void Transmit (void);
void Recieve(void);
int main(void)
{
Setup ();
//ADCconfig();
//PWMinit();
USART_Setup();
I2C_Setup();
while(1)
{
if (loop1>=100)
{
Transmit();
SendData(1,i2c_var);
loop1=0;
GPIOB->BSRR |= GPIO_Pin_8 | GPIO_Pin_9 ; // switch of LED's
Recieve();
}
}
}//end main
void Transmit (void)
{
/* Send I2C1 START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on I2C1 EV5 and clear it */
// while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send EEPROM slave Address for write */
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
/* Test on I2C1 EV6 and clear it */
// while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* Send I2C1 EEPROM internal address */
I2C_SendData(I2C1, 0x02); // 0x02 is config register
/* Test on I2C1 EV8 and clear it */
// while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send I2C1 EEPROM data */
I2C_SendData(I2C1, 0x00);//puts config register into continious measurement mode.
/* Test on I2C1 EV8 and clear it */
// while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send I2C1 STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
void I2C_Setup(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* GPIOB Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* I2C1 and I2C2 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Configure I2C1 pins: SCL and SDA ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open Drain, I2C bus pulled high externally
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable I2C1 -------------------------------------------------------------*/
I2C_Cmd(I2C1, ENABLE);
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
}
void Recieve(void)
{
/* Send I2C1 START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on I2C1 EV5 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send EEPROM slave Address for write */
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Receiver);
i2c_var = I2C_ReceiveData(I2C1);//puts config register into continious measurement mode.
/* Send I2C1 STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
//Increment function called by Systick every 1ms
inline void Increment (void)
{
loop1++;
loop2++;
loop3++;
Loop_Delay++;
}
void Delay(u16 count)
{
Loop_Delay=0;
while (Loop_Delay <= count)
{
asm(''nop'');
}
}//end Delay
♯♯♯♯♯♯♯♯&sharpEND CODE♯♯♯♯♯♯♯♯♯♯
The Libs.h file just contains some setup functions for setting up the USART and GPIOS. i made sure i called the I2C setup after my setups just incase it was setting some ports incorrectly.
All i am trying to do is read data from the sensors registers , any of them!
if i uncomment the while check events then it hangs on all of them. if i comment them all out and then run the code it just returns ''31'' to serial , which is the number i am putting into the DR register in the first place. so im figuring that whatever im putting into the register is just sitting there and not being sent anywhere.
any help in pointing out my stupidity would be appreciated :\
Thanks in advance.
#stm32 #i2c #i2c #i2c2011-09-16 05:06 AM
Marcos,
The description of the function is given within the library itself ''stm32f10x_i2c.c''. Id suggest reading through the library but it basically says the two arguments are as follows: @arg I2C_NACKPosition_Next: indicates that the next byte will be the last received byte. @arg I2C_NACKPosition_Current: indicates that current byte is the last received byte.Hope this helps,Darren.2013-10-17 12:54 PM
Hi Darren. This is a couple years since your post on I2C, but hopefully you'll understand my question ...
In your init_sens() routine, shouldn't the first I2C_SendData() call be rather I2C_Send7bitAddress() instead?Thanks for your post. I've been frustrated as well with the poor sample code for implementing I2C with STM32. I'd prefer interrupt driven, but right now I'll work with anything that does the job. I'll try your code and hope that it works for me, too!Jon