如题,最近在调试STM32的硬件IIC,从中发现了很多问题,经过网上查找资料总结和实际测试,总结出如下步骤来检测硬件IIC。
测试环境如下:
STM32F407开发板;
STM32Cube固件库F4 1.6.0
IIC设备 AT24C02
IIC配置如下:
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
1.检查STM32Cube时钟项配置是否正确(主要看所接入的时钟源是否与实际时钟源一致)
2.检查在完成IIC初始化后,SDA、SCL引脚是否为高电平,不是的话,要采用软件的方式实现,在IIC初始化代码增加如下步骤:
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB8 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
//增加代码部分Start
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
hi2c1.Instance->CR1=I2C_CR1_SWRST;
hi2c1.Instance->CR1=0;
//增加代码部分End
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
......
}
若此方式还是无法解决,就可能是硬件问题了;
3.验证硬件IIC单字节读取是否成功,测试代码如下:
#define ADDR_24LCxx_Write 0xA0
#define ADDR_24LCxx_Read 0xA1
uint8_t val=0;
HAL_I2C_Mem_Write(&hi2c1, ADDR_24LCxx_Write, 0, I2C_MEMADD_SIZE_8BIT,0x5A,1,0xff);
HAL_Delay(5);
HAL_I2C_Mem_Write(&hi2c1, ADDR_24LCxx_Read, 0, I2C_MEMADD_SIZE_8BIT,&val,1,0xff);
4..验证硬件IIC多字节字节读取是否成功,测试代码如下:
#define BufferSize 0x100
uint8_t WriteBuffer[BufferSize],ReadBuffer[BufferSize];
uint16_t i;
printf("\r\n***************I2C Example*******************************\r\n");
printf("WriteBuffer\r\n");
for(i=0; i<256; i++)
{
WriteBuffer[i]=256-i; /* WriteBuffer init */
printf("0x%02X ",WriteBuffer[i]);
}
/* wrinte date to EEPROM */
for(i=0;i { HAL_I2C_Mem_Write(&hi2c1, ADDR_24LCxx_Write, i, I2C_MEMADD_SIZE_8BIT,&WriteBuffer[i],1,0xff);//使用I2C块读,出错。因此采用此种方式,逐个单字节写入 HAL_Delay(5);//此处延时必加,与AT24C02写时序有关 } printf("\r\n EEPROM 24C02 Write Test OK \r\n"); HAL_I2C_Mem_Read(&hi2c1, ADDR_24LCxx_Read, 0, I2C_MEMADD_SIZE_8BIT,ReadBuffer,BufferSize,0xff); for(i=0; i<256; i++) printf("0x%02X ",ReadBuffer[i]); if(memcmp(WriteBuffer,ReadBuffer,BufferSize) == 0 ) /* check date */ printf("\r\n EEPROM 24C02 Read Test OK\r\n"); else printf("\r\n EEPROM 24C02 Read Test False\r\n"); AT24C02写时序如下: 至此,硬件IIC的使用完成;不管硬件IIC采用何种形式(DMA,IT),都要确保两次写入的间隔大于5ms;
其中twr为两次写入的时间间隔,其间隔最大为5ms;
上一篇:关于STM32的HAL库硬件I2C简单调试
下一篇:stm32 hal i2c 库读写sd3088时钟
推荐阅读最新更新时间:2024-03-16 16:04