May 26, 2024, 05:34:53 AM

I2C temperature sensor TCN75A

Started by melajmi, August 10, 2014, 08:20:35 PM

Previous topic - Next topic



I am a new user STM32F207.
I use Kit Eval Olimex STM32-P207.
I would like send data to TCN75A. I can't have SDA and SCL.
SDA and SCL are low.
There is my code
Thanks for your help
Best regards

/* Includes ------------------------------------------------------------------*/
#include "stm32f2xx.h"
#include "stm32f2xx_conf.h"
#include "stm32f2xx_i2c.h"
#include "delay.h"
#include "gpio.h"
#include <stdio.h>

#define I2C_SPEED 100000
#define I2C_DUTYCYCLE I2C_DutyCycle_2

/* Function declaration -------------------------------------------------------------*/
void I2C1_init(void);
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_ack(I2C_TypeDef* I2Cx);
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx);
void I2C_stop(I2C_TypeDef* I2Cx);

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

#define SLAVE_ADDRESS 0x4B

   void I2C1_init(void)

      GPIO_InitTypeDef GPIO_InitStruct;
      I2C_InitTypeDef I2C_InitStruct;

      // enable APB1 peripheral clock for I2C1
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
      // enable clock for SCL and SDA pins
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
      RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, DISABLE);
      RCC_AHB3PeriphResetCmd(RCC_AHB3Periph_FSMC, DISABLE);

// Connect I2C1 pins to AF
GPIO_PinAFConfig(GPIOG, GPIO_PinSource10, GPIO_AF_I2C1);   // SCL
      GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_I2C1); // SDA
      /* setup SCL and SDA pins
       * You can connect the I2C1 functions to two different
       * pins:
        * 1. SCL on PG10
        * 2. SDA on PG12
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12; // we are going to use PG10 and PG12
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;   // set pins to alternate function
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;   // set GPIO speed
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;   // set output to open drain
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;   // enable pull up resistors
      GPIO_Init(GPIOG, &GPIO_InitStruct);   // init GPIOG

      /* Configure I2C1 ***********************************************************/   
      I2C_DeInit(I2C1);   /* I2C DeInit */
// configure 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;   // Enable acknowledge when reading     
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length
I2C_Init(I2C1, &I2C_InitStruct);   // init I2C1

      // enable I2C1
      I2C_Cmd(I2C1, ENABLE);

   /* This function issues a start condition and
   * transmits the slave address + R/W bit
   * Parameters:
   * I2Cx --> the I2C peripheral e.g. I2C1
   * address --> the 7 bit slave address
   * direction --> the transmission direction can be:
   * I2C_Direction_Tranmitter for Master transmitter mode
   * I2C_Direction_Receiver for Master receiver
   void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction)
      // wait until I2C1 is not busy any more
      while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
      // Send I2C1 START condition : SDA =0, SCL=0
      I2C_GenerateSTART(I2Cx, ENABLE);

      // wait for I2C1 EV5 --> Slave has acknowledged start condition
      while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

      // Send slave Address for write
      I2C_Send7bitAddress(I2Cx, address, direction);

      /* wait for I2Cx EV6, check if
       * either Slave has acknowledged Master transmitter or
       * Master receiver mode, depending on the transmission
       * direction
      if(direction == I2C_Direction_Transmitter)
            while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
      else if(direction == I2C_Direction_Receiver)
            while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

   /* This function transmits one byte to the slave device
    * Parameters:
    * I2Cx --> the I2C peripheral e.g. I2C1
    * data --> the data byte to be transmitted
   void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
      // wait for I2C1 EV8 --> last byte is still being transmitted (last byte in SR, buffer empty), next byte can already be written
      while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
      I2C_SendData(I2Cx, data);

   /* This function reads one byte from the slave device
    * and acknowledges the byte (requests another byte)
   uint8_t I2C_read_ack(I2C_TypeDef* I2Cx)
      uint8_t data;
      // enable acknowledge of received data
      I2C_AcknowledgeConfig(I2Cx, ENABLE);
      // wait until one byte has been received : EV7
      while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
      // read data from I2C data register and return data byte
      data = I2C_ReceiveData(I2Cx);
      return data;

   /* This function reads one byte from the slave device
    * and doesn't acknowledge the received data
    * after that a STOP condition is transmitted
   uint8_t I2C_read_nack(I2C_TypeDef* I2Cx)
      uint8_t data;
      // disable acknowledge of received data
      // nack also generates stop condition after last byte received
      // see reference manual for more info
      I2C_AcknowledgeConfig(I2Cx, DISABLE);
      I2C_GenerateSTOP(I2Cx, ENABLE);
      // wait until one byte has been received : EV7
      while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
      // read data from I2C data register and return data byte
      data = I2C_ReceiveData(I2Cx);
      return data;

   /* This function issues a stop condition and therefore
    * releases the bus
   void I2C_stop(I2C_TypeDef* I2Cx)

      // Send I2C1 STOP Condition after last byte has been transmitted
      I2C_GenerateSTOP(I2Cx, ENABLE);
      // wait for I2C1 EV8_2 --> byte has been transmitted
      while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

   int main(void)
uint8_t received_data;

/*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f2xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f2xx.c file
   /* Configuration du Systick à 1 ms (1000) */
   SysTick_Config(SystemCoreClock / 1000);
   I2C1_init(); // initialize I2C peripheral

   I2C_start(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter); // start a transmission in Master transmitter mode
   I2C_write(I2C1, 0x00); // write one byte to the slave
   I2C_stop(I2C1); // stop the transmission

   I2C_start(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver); // start a transmission in Master receiver mode
   received_data = I2C_read_nack(I2C1); // read one byte and don't request another byte, stop transmission



Hello Melajmi,

The GPIO pins used for TCN75A also go to pins 5 and 6 of the UEXT connector. Are you sure there isn't something attached to the UEXT keeping them low?

Unfortunately, the board lacked free hardware SDA/SCL pins and we had to go with GPIO pins, naming them SOFT_SDA and SOFT_SCL so people would know what to expect (e.g. that they would need to implement software I2C on PG9 and PG11 processor pins).

Best regards,
Technical support and documentation manager at Olimex


who i can connect PG9 and PG11 in I2C by software