cancel
Showing results for 
Search instead for 
Did you mean: 

STM8L DISCOVERY I2C

juankrygarcia
Associate II
Posted on March 19, 2013 at 20:55

Hello all STM comunity,

First of all my apologies for my English, my language level is rather basic yet. That said, I will proceed to explain te reasons as I am writing this post.

I am a Spanish estudent and I am developing a proyect with the demo board stm8l discovery. For this proyect I need to comunicate the MCU with an external ADC, becouse I need a 18-bit resolution.

So I am trying to comunicate STM8L DISCOVERY (master) with MCP3424 (Slave).

Folowing I2C protocol, at first I check that the I2C bus is not busy anymore and next, I send the start condition. The problem is that after I send the start condition, SDA goes low (that its correct) but SCL goes lo too and no clock signal is generated, SCL is low level constantly.

I have tried to change the I2C bus frecuency, the pull up resistor are correct, and the chip is not borken. The start condition function that I´m using as follows:

 /* 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 tranmission 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 anymore

while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

// Send I2C1 START condition

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 I2C1 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));

}

}

The function is waiting ack after send the slave adrees, is obvious, beouse it is not clock. (I have measured whit an oscilloscope).

I would be ver grateful if someone trying to help me.

Greetings from Spain,

Juan Cristóbal
1 REPLY 1
allantommathew
Associate II
Posted on November 07, 2016 at 08:25

Hi Juan,

     This reply comes after years and thus this may not serve your purpose. I started working on STM8L recently and came across some problems with I2C and that is what led me to this page. This may serve some others working in similar lines.

     Coming to the problem that you are facing, in order to use the function ''I2C_Send7bitAddress'' properly we should left shift the address by one bit. I don't know if it is a bug in the library function or they expect us to do the shifting our self. Anyway a left shift is required before calling this function.

     Solution in one line:

I2C_Send7bitAddress( I2Cx, address << 1, direction );

     Second is that, we should specify a read or write request  along with the 7 bit address. If the LSB is '0', it specifies a write request to the slave device. If the LSB is '1', it specifies a read request to the slave device.

     Thus solution in one line:

I2C_Send7bitAddress( I2Cx, address << 1 & 0xFE, direction ); // for write request

I2C_Send7bitAddress( I2Cx, address << 1 | 0x01, direction ); // for read request

     Happy to be part of this huge community.