STM32 IIC 通信 库函数实现
reading stucture | ||||||||||||||||
device address | read command | write address to board | device address | read data from board | ||||||||||||
start | 0xb0 | ack | 0x01 | ack | address high | ack | address low | ack | start | 0xb1 | ack | data high | ack | data low | nack | stop |
example to read address 0x1234 and result 0x789A | ||||||||||||||||
start | 0xb0 | ack | 0x01 | ack | 0x12 | ack | 0x34 | ack | start | 0xb1 | ack | 0x78 | ack | 0x9a | nack | stop |
writing stucture | ||||||||||||||||
device address | write command | write address to board | read data from board | |||||||||||||
start | 0xb0 | ack | 0x81 | ack | address high | ack | address low | ack | data high | ack | data low | ack | stop | |||
example to write address 0x5678 with data 0xcdef | ||||||||||||||||
start | 0xb0 | ack | 0x81 | ack | 0x56 | ack | 0x78 | ack | 0xcd | ack | 0xef | ack | stop | 0x9a |
|
Read Register
void Read_Reg(u8 *DataBuff,u8 ByteQuantity,uint16_t RegAddress,u8 SlaveAddress) { //这句去掉也正常 while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008 /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* 发送器件地址(写)*/ I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */ //这句去掉也正常 /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2C1, ENABLE); I2C_SendData(I2C1,01); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,RegAddress>>8); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,RegAddress); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* 发送器件地址(写)*/ I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Receiver); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */ while (ByteQuantity) { if(ByteQuantity==1) { I2C_AcknowledgeConfig(I2C1, DISABLE); //最后一位后要关闭应答的 I2C_GenerateSTOP(I2C1, ENABLE); //发送停止位 } while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */ *DataBuff = I2C_ReceiveData(I2C1); DataBuff++; /* Decrement the read bytes counter */ ByteQuantity--; } //再次允许应答模式 I2C_AcknowledgeConfig(I2C1, ENABLE); //errorflag=0; //break; }
Write Register
void Write_Reg(uint16_t WriteValue,uint16_t RegAddress,u8 SlaveAddress) { while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008 /* Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send EEPROM address for write */ I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1,0x81); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,RegAddress>>8); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,RegAddress); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,WriteValue>>8); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1,WriteValue); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send STOP condition */ I2C_GenerateSTOP(I2C1, ENABLE); }
I2C_Send7bitAddress
/** * @brief Transmits the address byte to select the slave device. * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. * @param Address: specifies the slave address which will be transmitted * @param I2C_Direction: specifies whether the I2C device will be a * Transmitter or a Receiver. This parameter can be one of the following values * @arg I2C_Direction_Transmitter: Transmitter mode * @arg I2C_Direction_Receiver: Receiver mode * @retval None. */ void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) { /* Check the parameters */ assert_param(IS_I2C_ALL_PERIPH(I2Cx)); assert_param(IS_I2C_DIRECTION(I2C_Direction)); /* Test on the direction to set/reset the read/write bit */ if (I2C_Direction != I2C_Direction_Transmitter) { /* Set the address bit0 for read */ Address |= OAR1_ADD0_Set; } else { /* Reset the address bit0 for write */ Address &= OAR1_ADD0_Reset; } /* Send the address */ I2Cx->DR = Address; } #define I2C_Direction_Transmitter ((uint8_t)0x00) #define I2C_Direction_Receiver ((uint8_t)0x01)
7位模式下,地址字节最低位若是0则说明主机要进入发送模式,若是1则是接收模式