STM32硬件IIC
1 /** 2 * @brief 写一个字节到I2C设备中 3 * @param 4 * @arg pBuffer:缓冲区指针 5 * @arg WriteAddr:写地址 6 * @retval 正常返回1,异常返回0 7 */ 8 uint8_t I2C_ByteWrite(u8 pBuffer, u8 WriteAddr) 9 { 10 /* Send STRAT condition */ 11 I2C_GenerateSTART(macI2Cx, ENABLE); 12 13 I2CTimeout = I2CT_FLAG_TIMEOUT; 14 15 16 /* Test on EV5 and clear it */ 17 //启动信号发出之后要等待状态寄存器SR1的位0(SB=1),状态寄存器SR2的位1(BUSY=1)和位0(MSL=1),此时表明主模式下,起始条件已发送,总线处于忙状态;确保IIC通讯正确 18 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT)) 19 { 20 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 21 } 22 23 /* Send slave address for write */ 24 I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Transmitter);//7bit slave address + read/write (0write,1 read) 25 26 I2CTimeout = I2CT_FLAG_TIMEOUT; 27 28 /* Test on EV6 and clear it */ 29 //从机地址发出之后,等待 BUSY, MSL, ADDR, TXE and TRA flags标志位 30 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 31 { 32 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 33 } 34 35 /* Send the slave's internal address to write to */ 36 I2C_SendData(macI2Cx, WriteAddr); 37 38 I2CTimeout = I2CT_FLAG_TIMEOUT; 39 /* Test on EV8 and clear it */ 40 /* TRA, BUSY, MSL, TXE and BTF flags */ 41 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 42 { 43 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 44 } 45 46 /* Send the byte to be written */ 47 I2C_SendData(macI2Cx, pBuffer); 48 49 I2CTimeout = I2CT_FLAG_TIMEOUT; 50 51 /* Test on EV8 and clear it */ 52 /* TRA, BUSY, MSL, TXE and BTF flags */ 53 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 54 { 55 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 56 } 57 58 /* Send STOP condition */ 59 I2C_GenerateSTOP(macI2Cx, ENABLE); 60 61 return 1; //正常返回1 62 }
IIC事件检测:498页。STM32的硬件IIC通信非常严格,每一步都要检测相应的标志位是否正确,确保通信不会出错。
1 /** 2 * @brief 从I2C设备里面读取一块数据 3 * @param 4 * @arg pBuffer:存放从slave读取的数据的缓冲区指针 5 * @arg WriteAddr:接收数据的从设备的地址 6 * @arg NumByteToWrite:要从从设备读取的字节数 7 * @retval 正常返回1,异常返回0 8 */ 9 uint8_t I2C_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) 10 { 11 I2CTimeout = I2CT_LONG_TIMEOUT; 12 13 while(I2C_GetFlagStatus(macI2Cx, I2C_FLAG_BUSY)) // Added by Najoua 27/08/2008 14 { 15 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 16 } 17 18 I2C_GenerateSTART(macI2Cx, ENABLE); 19 20 I2CTimeout = I2CT_FLAG_TIMEOUT; 21 22 /* Test on EV5 and clear it */ 23 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT)) 24 { 25 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 26 } 27 28 /* Send slave address for write */ 29 I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Transmitter); 30 31 I2CTimeout = I2CT_FLAG_TIMEOUT; 32 33 /* Test on EV6 and clear it */ 34 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 35 { 36 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 37 } 38 39 /* Clear EV6 by setting again the PE bit */ 40 I2C_Cmd(macI2Cx, ENABLE); 41 42 /* Send the slave's internal address to write to */ 43 I2C_SendData(macI2Cx, ReadAddr); 44 45 I2CTimeout = I2CT_FLAG_TIMEOUT; 46 47 /* Test on EV8 and clear it */ 48 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) 49 { 50 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 51 } 52 53 /* Send STRAT condition a second time */ 54 I2C_GenerateSTART(macI2Cx, ENABLE); 55 56 I2CTimeout = I2CT_FLAG_TIMEOUT; 57 /* Test on EV5 and clear it */ 58 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_MODE_SELECT)) 59 { 60 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 61 } 62 63 /* Send slave address for read */ 64 I2C_Send7bitAddress(macI2Cx, MPU6050_SLAVE_ADDRESS, I2C_Direction_Receiver); 65 66 I2CTimeout = I2CT_FLAG_TIMEOUT; 67 68 /* Test on EV6 and clear it */ 69 while(!I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) 70 { 71 if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(); 72 } 73 74 /* While there is data to be read */ 75 while(NumByteToRead) 76 { 77 if(NumByteToRead == 1) 78 { 79 /* Disable Acknowledgement */ 80 I2C_AcknowledgeConfig(macI2Cx, DISABLE); 81 82 /* Send STOP Condition */ 83 I2C_GenerateSTOP(macI2Cx, ENABLE); 84 } 85 86 /* Test on EV7 and clear it */ 87 if(I2C_CheckEvent(macI2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) 88 { 89 /* Read a byte from the slave */ 90 *pBuffer = I2C_ReceiveData(macI2Cx); 91 92 /* Point to the next location where the byte read will be saved */ 93 pBuffer++; 94 95 /* Decrement the read bytes counter */ 96 NumByteToRead--; 97 } 98 } 99 100 /* Enable Acknowledgement to be ready for another reception */ 101 I2C_AcknowledgeConfig(macI2Cx, ENABLE); 102 103 return 1; //正常,返回1 104 }