2008-11-10 01:52 AM
I2C: Always 2 Databytes sent ?!
2011-05-17 03:50 AM
Hi,
it seems that there are always 2 bytes send, why is it not possible to send only one byte? Is it a bug? Init-Code: I2C_InitTypeDef I2C_InitStructure; I2C_DeInit(I2C1); /* I2C1 and I2C2 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); // Configure I2C1 pins: SCL and SDA GPIO_InitStructure.GPIO_Pin=TAS_SCL|TAS_SDA; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD; GPIO_Init(TASTPORT,&GPIO_InitStructure); // I2C-Init: I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; // I2C_Mode_SMBusHost ########## 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=I2C_Speed; // I2C Peripheral Enable I2C_Cmd(I2C1,ENABLE); // Apply I2C configuration after enabling it I2C_Init(I2C1,&I2C_InitStructure); Send-Code: /* While the bus is busy */ for(nn=CHECKEVENTCNT;(nn--)&&(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));); /* Send I2C1 START condition */ I2C_GenerateSTART(I2C1,ENABLE); /* Test on I2C1 EV5 and clear it */ for(nn=CHECKEVENTCNT;(nn--)&&(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));); /* While the bus is busy */ for(nn=CHECKEVENTCNT;(nn--)&&(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));); /* Send I2C1 START condition */ I2C_GenerateSTART(I2C1,ENABLE); /* Test on I2C1 EV5 and clear it */ for(nn=CHECKEVENTCNT;(nn--)&&(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));); /* Send Data */ I2C_SendData(I2C1,dat); /* Clear ADDR flag: read operation to I2C_SR1 register followed by a read operation to I2C_SR2 register */ /* Test on I2C1 EV8 and clear it */ for(nn=CHECKEVENTCNT;(nn--)&&(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));); -> Startbit sent o.k. -> Addressbyte sent o.k. -> I2C_SendData() sends two Bytes, why? I know that the DFF Bit in CR1 should set 1 byte or 2 byte but it is not applicable by the ST library?! The ackbit in the address is not cleared. There is no I2C slave - could this be the problem? Which mode is correct? Why are the bits in the Raisonance RIDE7 environment other than described in the ST reference manual? At Raisonance (debugger) there is no DFF-Bit in the I2C->CR1 register ?! Funny: Why can I not send a databyte in I2C_Mode_SMBusHost - mode? Only the addressbyte is sent here!? Best regards Edi [ This message was edited by: pt1 on 05-11-2008 11:00 ] [ This message was edited by: pt1 on 05-11-2008 11:38 ]2011-05-17 03:50 AM
Hi
I've solved my problem - because of the connected slave, now only 1 byte will be sent. Hope anybody helps this too. Best regards Edi [ This message was edited by: pt1 on 05-11-2008 18:40 ]2011-05-17 03:50 AM
I had the same effect: Since I assumed the connected slave caused problems in my I2C communication, I exchanged all event checkings in my code sequence for delays and sent an I2C message with a false address. (So the slave didn't answer.)
The transmit of the address byte was like expected, but not the transmit of the following data bytes: After the 9th (not acknowledged) clock the byte was transmitted once again immediately. After the 18th clock (also not acknowledged) the rest of the delay was following and then started the twice transmit of the next data byte. I assumed the reason was the absent acknowledge. So I changed the initialisation to: I2C_InitStructure.I2C_Ack = I2C_Ack_Disable; But this had no effect, the data bytes was transmitted 2 times too. Does anybody know what the setting I2C_Ack_Disable/I2C_Ack_Enable should effect? Thanks in advance, Norbert2011-05-17 03:50 AM
Sounds like the problem Lanchon pointed out. Search the forums for i2c and lanchon.
2011-05-17 03:50 AM
Thanks for your answer although it didn't really help me. But I lerned from the forum threads that I have to do still some research for making my I2C running. :( I hoped I could use a driver from a FWLib example without very exactly knowledge of the STM32 I2C macrocell's working.
Best regards, Norbert2011-05-17 03:50 AM
Hello,
I have not tested my code if it sends extra data, but it works with my I2C touch sensor:Code:
void touch_WR(unsigned char addr,unsigned char val) { /*----- First transmission Phase -----*/ /* 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 I2C2 slave Address for write */ I2C_Send7bitAddress(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 data */ I2C_SendData(I2C1, addr); /* Test on EV8 and clear it */ while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send I2C1 data */ I2C_SendData(I2C1, val); /* Send I2C1 STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); } The assigned I2C adress must be shifted 1 bit up to leave space for the R/W bit. This funktion first sends the Adress and then the data value. Maybe this can help you a litle? Kasper