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 }
原文地址:https://www.cnblogs.com/prayer521/p/6023289.html