2个stm32设备之间的c-i2c通信失败



我目前使用2台stm32设备通过i2c进行通信。

沟通目前不起作用,我不知道为什么。

这是我的主初始化代码,由stm32cubemx生成,并修改了一点

static void MX_I2C2_Init(void)
{
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x00303D5B;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c2);
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
/*Configure GPIO pins : PB7 PB6 */
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PA2 PA3 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
if (HAL_I2C_Init(&hi2c2) != HAL_OK) {     cpu_ErrHandler();   }
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE)
!= HAL_OK) {
cpu_ErrHandler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
cpu_ErrHandler();
}
//HAL_I2C_Slave_Receive_IT(&hi2c2,  ( uint8_t * ) &i2c_data,1);
}
void cpu_ErrHandler(void)
{
/* USER CODE BEGIN cpu_ErrHandler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END cpu_ErrHandler_Debug */
}
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}

这是我的从属代码

static void MX_I2C2_Init(void)
{
/* USER CODE BEGIN I2C2_Init 0 */
/* USER CODE END I2C2_Init 0 */
/* USER CODE BEGIN I2C2_Init 1 */
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x00303D5B;
hi2c2.Init.OwnAddress1 = 96;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c2);
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
//__HAL_RCC_I2C2_CLK_ENABLE();
/*Configure GPIO pins : PB7 PB6 */
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PA2 PA3 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
if (HAL_I2C_Init(&hi2c2) != HAL_OK) {     cpu_ErrHandler();   }
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE)
!= HAL_OK) {
cpu_ErrHandler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
cpu_ErrHandler();
}
//HAL_I2C_Slave_Receive_IT(&hi2c2,  ( uint8_t * ) &i2c_data,1);
}
void cpu_ErrHandler(void)
{
/* USER CODE BEGIN cpu_ErrHandler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END cpu_ErrHandler_Debug */
}
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}

根据我的设备更改了pin号

这是我的从属接收代码

void user_main(void)
{
HAL_StatusTypeDef ret;
ret = HAL_I2C_Slave_Receive(&hi2c2,  ( uint8_t * ) UartRxMemory01, sizeof(UartRxMemory01), 100);
cpu_delay_ms(100);
if(ret != HAL_OK){
char i2c_fail[]="fail";
DCPU_TX_EN(); // get sensor value
#if 1
if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) i2c_fail,strlen( i2c_fail ),100 ) == HAL_OK) {
DCPU_RX_EN();
HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
}
#endif
}
else {
if(strstr((const char*)UartRxMemory01, "OK") != NULL){
char i2c[]="i2c succeed";
DCPU_TX_EN(); // get sensor value
#if 1
if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) i2c,strlen( i2c ),100 ) == HAL_OK) {
DCPU_RX_EN();
HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
}
#endif
} else {
char got_smth[]="received something";
DCPU_TX_EN(); // get sensor value
#if 1
if(HAL_UART_Transmit(&rcpu_huart2,( uint8_t * ) got_smth,strlen( got_smth ),100 ) == HAL_OK) {
DCPU_RX_EN();
HAL_UART_Receive(&rcpu_huart2, ( uint8_t * ) RxIntBuffer,sizeof(RxIntBuffer),100 );
}
#endif
}
}
}

这是我的主传输码

void user_main(void)
{
char i2c_ok[5];
i2c_ok[0]=0x0a;
strcat(i2c_ok, "OK");
i2c_ok[4] = 0x0d;
HAL_StatusTypeDef ret;
ret = HAL_I2C_Master_Transmit(&hi2c2, 0x20 << 1, (uint8_t*)i2c_ok, sizeof(i2c_ok),100);
if(ret != HAL_OK){
cpu_delay_ms(100);
}
else{
cpu_delay_ms(1000);
}
}

当我开始通信时,主机发送地址和写入位,并得到NACK作为返回,通信通过

i2c_波形

我真的不确定出了什么问题,有人能帮我吗?

这很可能是外围设备或硬件配置的问题。使用示波器检查时钟频率是否符合预期(100kHz是I2C的典型频率(。

当你在那里的时候,检查信号是否也有很好的快速边缘。忘记添加外部上拉电阻器是导致此问题的常见原因。2k2电阻器通常是好的。

你可能会发现你从电子堆栈交换中得到了更多的响应。

最新更新