马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目次
一、AT24C02硬件IIC-标准库
1、I2C_InitTypeDef
2、GPIO
3、数据写入
4、数据读取
二、AT24C02硬件IIC-HAL库
1、I2C_HandleTypeDef与I2C_InitTypeDef
2、GPIO
3、数据写入
4、数据读取
一、AT24C02硬件IIC-标准库
1、I2C_InitTypeDef
硬件IIC就要和I2C的代码打交道了。I2C_InitTypeDef在stm32f10x_i2c.h中,重要设置I2C通信速率,I2C模式,SCL时钟线占空比,自身IIC地址,I2C相应使能,I2C寻址模式长度等。
- typedef struct
- {
- uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz */
- uint16_t I2C_Mode; /*!< Specifies the I2C mode.
- This parameter can be a value of @ref I2C_mode */
- uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
- uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address.
- This parameter can be a 7-bit or 10-bit address. */
- uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement.
- This parameter can be a value of @ref I2C_acknowledgement */
- uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
- This parameter can be a value of @ref I2C_acknowledged_address */
- }I2C_InitTypeDef;
复制代码 2、GPIO
保持为复用开漏输出。
- /* I2C_SCL、I2C_SDA*/
- GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
- GPIO_Init(EEPROM_I2C_SCL_PORT, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
- GPIO_Init(EEPROM_I2C_SDA_PORT, &GPIO_InitStructure);
复制代码 3、数据写入
可以看到硬件IIC的时序就是必要不断的判定I2C的各类寄存器,例如EV6、EV8等,而非模拟IIC直接判定IO是否拉高、拉低即可。
- uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
- {
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
- }
-
- /* Send START condition */
- I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV5 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
- }
-
- /* Send EEPROM address for write */
- I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV6 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
- }
-
- /* Send the EEPROM's internal address to write to */
- I2C_SendData(EEPROM_I2Cx, WriteAddr);
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV8 and clear it */
- while(! I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7);
- }
- /* While there is data to be written */
- while(NumByteToWrite--)
- {
- /* Send the current byte */
- I2C_SendData(EEPROM_I2Cx, *pBuffer);
- /* Point to the next byte to be written */
- pBuffer++;
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV8 and clear it */
- while (!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
- }
- }
- /* Send STOP condition */
- I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
-
- return 1;
- }
复制代码 4、数据读取
- uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
- {
-
- I2CTimeout = I2CT_LONG_TIMEOUT;
-
- //*((u8 *)0x4001080c) |=0x80;
- while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(9);
- }
-
- /* Send START condition */
- I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
- //*((u8 *)0x4001080c) &=~0x80;
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV5 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(10);
- }
-
- /* Send EEPROM address for write */
- I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV6 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(11);
- }
-
- /* Clear EV6 by setting again the PE bit */
- I2C_Cmd(EEPROM_I2Cx, ENABLE);
- /* Send the EEPROM's internal address to write to */
- I2C_SendData(EEPROM_I2Cx, ReadAddr);
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV8 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(12);
- }
-
- /* Send STRAT condition a second time */
- I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV5 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(13);
- }
-
- /* Send EEPROM address for read */
- I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Receiver);
-
- I2CTimeout = I2CT_FLAG_TIMEOUT;
- /* Test on EV6 and clear it */
- while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(14);
- }
-
- /* While there is data to be read */
- while(NumByteToRead)
- {
- if(NumByteToRead == 1)
- {
- /* Disable Acknowledgement */
- I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE);
-
- /* Send STOP Condition */
- I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
- }
- /* Test on EV7 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
-
- while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0)
- {
- if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
- }
- {
- /* Read a byte from the EEPROM */
- *pBuffer = I2C_ReceiveData(EEPROM_I2Cx);
- /* Point to the next location where the byte read will be saved */
- pBuffer++;
-
- /* Decrement the read bytes counter */
- NumByteToRead--;
- }
- }
- /* Enable Acknowledgement to be ready for another reception */
- I2C_AcknowledgeConfig(EEPROM_I2Cx, ENABLE);
-
- return 1;
- }
复制代码
二、AT24C02硬件IIC-HAL库
1、I2C_HandleTypeDef与I2C_InitTypeDef
硬件IIC就要和I2C的代码打交道了。I2C_HandleTypeDef在stm32f1xx_hal_i2c.h中,重要设置I2C通信速率,I2C模式,SCL时钟线占空比,自身IIC地址,I2C相应使能,I2C寻址模式长度等。
- typedef struct
- #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
- {
- I2C_TypeDef *Instance; /*!< I2C registers base address */
- I2C_InitTypeDef Init; /*!< I2C communication parameters */
- uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
- uint16_t XferSize; /*!< I2C transfer size */
- __IO uint16_t XferCount; /*!< I2C transfer counter */
- __IO uint32_t XferOptions; /*!< I2C transfer options */
- __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
- context for internal usage */
- DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
- DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
- HAL_LockTypeDef Lock; /*!< I2C locking object */
- __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
- __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
- __IO uint32_t ErrorCode; /*!< I2C Error code */
- __IO uint32_t Devaddress; /*!< I2C Target device address */
- __IO uint32_t Memaddress; /*!< I2C Target memory address */
- __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
- __IO uint32_t EventCount; /*!< I2C Event counter */
- } I2C_HandleTypeDef;
- typedef struct
- {
- uint32_t ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz */
- uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
- uint32_t OwnAddress1; /*!< Specifies the first device own address.
- This parameter can be a 7-bit or 10-bit address. */
- uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
- This parameter can be a value of @ref I2C_addressing_mode */
- uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
- This parameter can be a value of @ref I2C_dual_addressing_mode */
- uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
- This parameter can be a 7-bit address. */
- uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
- This parameter can be a value of @ref I2C_general_call_addressing_mode */
- uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
- This parameter can be a value of @ref I2C_nostretch_mode */
- } I2C_InitTypeDef;
复制代码 2、GPIO
保持为复用开漏输出。
- GPIO_InitStruct.Pin = I2Cx_SCL_PIN;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-
- HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
-
- /* I2C RX GPIO pin configuration */
- GPIO_InitStruct.Pin = I2Cx_SDA_PIN;
- HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
复制代码 3、数据写入
可以看到硬件IIC的时序就是必要不断的判定I2C的各类寄存器,例如EV6、EV8等,而非模拟IIC直接判定IO是否拉高、拉低即可。
- uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Write EEPROM_PAGESIZE */
- status=HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS,WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);
- while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
- {
-
- }
- /* Check if the EEPROM is ready for a new operation */
- while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);
- /* Wait for the end of the transfer */
- while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
- {
-
- }
- return status;
- }
复制代码 4、数据读取
- uint32_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- status=HAL_I2C_Mem_Read(&I2C_Handle,EEPROM_ADDRESS,ReadAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)pBuffer, NumByteToRead,1000);
- return status;
- }
复制代码 可以看到HAL库下会方便一点,做了底层的深度封装,但是这么写,太受制于人了,和时序完全不打交道了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |