cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 and I2C issue - No ACK from slave

gianlucasuzzi
Associate II
Posted on February 22, 2013 at 14:56

Hi everyone, first of all i've to tell you that i'm new with I2C bus.

I'm using I2C1 on STM32F103 ARM to communicate with an I2C eeprom (24LC256). I can see both SCL and SDA on my scope but it seems there is a problem with the ACK at the ninth clock. I've made the same test with a lux sensor MAX44009 and i can't be able to see any ACK at all. The testing function i use is:

void
STM32_I2C_test(
void
)
{
uint8_t I2C_address;
uint32_t I2C_speed;
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
I2C_address = 0xA0; 
//
//address = 0x94; //
I2C_speed = 1000; 
// 1000Hz
/*enable I2C*/
I2C_Cmd(I2C1,ENABLE);
/* I2C1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* I2C1 SDA and SCL configuration */
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;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//SCL is pin06 and SDA is pin 07 for I2C1
/* I2C1 configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_speed ;
I2C_Init(I2C1, &I2C_InitStructure);
//
/* check start bit flag */
while
(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* initiate start sequence */
I2C_GenerateSTART(I2C1,ENABLE);
while
(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));
/*send write command to chip*/
I2C_SendData(I2C1,I2C_address);
//I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/*mode register address*/
I2C_SendData(I2C1, 0x02);
/*wait for byte send to complete*/
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/*clear bits*/
I2C_SendData(I2C1, 0x00);
/*wait for byte send to complete*/
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/*generate stop*/
I2C_GenerateSTOP(I2C1, ENABLE);
/*stop bit flag*/
while
(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
}

I've attached also the signals from my scope. I've pulled up both SCL and SDA with 10k resistors (but i've tried also with 4k7 with no effect). 0690X00000604QZQAY.png Can you halping me understand where i'm wrong? Thank's and sorry for my english. #i2c-ack-issue
9 REPLIES 9
emalund
Associate III
Posted on February 22, 2013 at 16:02

have you read the errata?

gianlucasuzzi
Associate II
Posted on February 22, 2013 at 17:57

Yes, i've tried also to use DMA but with no effect. Anyway in errata they doesn't speak about ACK issue.

Posted on February 22, 2013 at 18:55

Number one reason a slave doesn't ACK, is that it doesn't recognize the address supplied. Got to watch the 7-bit representation and shift on different chipsets.

What are you doing with the A0,A1,A2 chip select bits in your design?

You honestly want SMBus mode for this application?

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
gianlucasuzzi
Associate II
Posted on February 25, 2013 at 08:48

I've short circuited A0,A1,A2 to GND. In this manner the address is A0.

Instead of shifting the address i put the address already shifted...it could be the same, right?

So i put A0 in the address without shifting. I've tried also to shift the address..but in that case i dont's see activity at all. If i use the address without shifting i see the waveform showed in figure.

I've to use I2C. I've tried many times with different code, so i've tried also to use it in SMbus..but the behaviour is the same. I've forgotten to replace I2C in the code attacched here.

What i don't understand is the shape of the signal on the ninth clock (as you can see from the image attached). It seems the slave is trying to answer.

roelie
Associate
Posted on October 30, 2014 at 08:44

Did you manage to get the I2C resolved? I'm also trying to use I2C currently on the STM32F103RBT6 microcontroller without any luck so far. I would just like to know why you didn't get the ACK back and what did you do to resolve it?

Thanks

selcukozb
Associate III
Posted on October 30, 2014 at 12:20

Hi,

Before Suzzi responses to your inquiry, I suggest you pay attention to following points:

1) I2C Library functions do not ''left shift'' adress when placing read/write bit to LSB of the start command byte, that means if your address is 0x27, you should assign 0x4E as 7 bit address parameter.

2) In case of Suzzi's problem, SMBUS protocol was selected, whereas I2C should be the right selection, as Clive warned.

3) If another IC pin is sharing SDA line, be careful, it might be attempting  to pull that line to Vdd during ACK.  (That is a low probability since it should be an output that shorts the pull up resistor. And that might result a burn out on I/O s. And why that chip should attempt to do that right on the moment of ACK)

BR

jvankuilenburg
Associate II
Posted on October 31, 2014 at 07:37

Hi,

I've also problems with the I2C-bus. I tested with the original dirvers of ST on the mcbstm32f400 eval kit of Keil. Also tried it on our pcb with a stm32f427 micro. We see the seem problem. At the 9de bit after the address, eeprom has to give an ack. But we get an ''half'' signal. The ST micro tried to pull-up and the eeprom to pull-down. When I tested it with ''handclocking'' in the code, it's okay. That means that the bus and address is correct. When i put an strange address for the eeprom, you see that the ack is 100% high. Thats okay, becauce there is no ic with that address. It looks like that the micro don't expect an ack. But bit 10 of CR1 is high, the reg-settings:

I2C startup REG CR1 0x0401 CR2 0x002a CCR 0x01a4 TRISE 0x002b OAR1 0x4001 ** ST1 0x0000 ST2 0x0000

0690X00000602vKQAQ.jpg

The blue line is the SCL and the cyan the SDA. You see at the 9de clockpuls a ''half'' SDA signal.

Have somebody an idea, what I can do?

Thanks, Jan.

John F.
Senior
Posted on October 31, 2014 at 09:17

The microcontroller I2C pins SDA and SCL must be configured as open-drain. Your oscillogram looks like SDA is configured as push-pull (or your pull up resistor value is much too low - typically between 2k2 and 10k).

jvankuilenburg
Associate II
Posted on October 31, 2014 at 09:52

-The pull-up resistor is 2k2

-I set the portmode to 2 (alternate mode)

-outputtype to 1 (opendrain)

-pullup/pulldown to 2 and also tried 0 (2==pulldown // 0==no_pp)

-set AFR to 4 (I2C1)