HI,
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
Elajmi
/* 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;
I2C_DeInit(I2C1);
// 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
while(1);
}
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,
Lub/OLIMEX
who i can connect PG9 and PG11 in I2C by software
thanks