Stm32 I2c从HAL传输

Stm32 I2c从HAL传输,stm32,i2c,stm32f4discovery,hal,Stm32,I2c,Stm32f4discovery,Hal,我试图用STM32F446RE中的I2C作为从设备传输到主设备,但我无法实现 当MCU上没有代码运行时,我可以看到主机请求我在示波器上写入代码。但当我使用此代码时: if(HAL_I2C_Slave_Receive_IT(&I2CxHandle, (uint8_t*)&T2, 1)!= HAL_OK); while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY) { } while(H

我试图用STM32F446RE中的I2C作为从设备传输到主设备,但我无法实现

当MCU上没有代码运行时,我可以看到主机请求我在示波器上写入代码。但当我使用此代码时:

if(HAL_I2C_Slave_Receive_IT(&I2CxHandle, (uint8_t*)&T2, 1)!= HAL_OK);
  while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {    }
  while(HAL_I2C_Slave_Transmit_IT(&I2CxHandle, (uint8_t*)&T1, 1)!= HAL_OK);
  while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {    }
SDA变高,SCL变低

此外,当我删除接收线并在大约100MS结束时加上延迟时,主机只接收消息,但只在有限的时间内(不是固定的时间,有时是3-4s,有时几乎是秒),但是它不应该这样做,因为它不考虑来自主机的请求。 有什么想法吗?我没有检查任何旗帜,因为我不知道如何检查

完整代码:

/* Includes ------------------------------------------------------------------*/
#include "main.h"



#define I2C_ADDRESS        0x2E



I2C_HandleTypeDef I2CxHandle;
static GPIO_InitTypeDef  GPIO_InitStruct;


static void SystemClock_Config(void);
static void Error_Handler(void);



int main(void)
{
  HAL_Init();
  /* Configure the system clock to 180 MHz */
  SystemClock_Config();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

  /* Configure LED2 */
  BSP_LED_Init(LED2);

  /*##-1- Configure the I2C peripheral #######################################*/
  I2CxHandle.Instance             = I2Cx;
  I2CxHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
  I2CxHandle.Init.ClockSpeed      = 100000;
  I2CxHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  I2CxHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
  I2CxHandle.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
  I2CxHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
  I2CxHandle.Init.OwnAddress1     = I2C_ADDRESS;
  I2CxHandle.Init.OwnAddress2     = 0;

  if(HAL_I2C_Init(&I2CxHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }


HAL_Delay(100);

  while(1)
  {

    if(HAL_I2C_Slave_Receive_IT(&I2CxHandle, (uint8_t*)&T2, 1)!= HAL_OK);
      while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {   }
      while(HAL_I2C_Slave_Transmit_IT(&I2CxHandle, (uint8_t*)&T1, 1)!= HAL_OK);
      while ( HAL_I2C_GetState(&I2CxHandle) != HAL_I2C_STATE_READY)      {   }
      T1++;

      //HAL_Delay(100);
    }
  }

static void Error_Handler(void)
{
  /* Turn LED2 ON if error */
  //BSP_LED_On(LED2);

  while(1)
  {
  }
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follows: 
  *            System Clock source            = PLL (HSI)
  *            SYSCLK(Hz)                     = 180000000
  *            HCLK(Hz)                       = 180000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSI Frequency(Hz)              = 16000000
  *            PLL_M                          = 16
  *            PLL_N                          = 360
  *            PLL_P                          = 2
  *            PLL_Q                          = 7
  *            PLL_R                          = 6
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 5
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef ret = HAL_OK;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /* Enable HSI Oscillator and activate PLL with HSI as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 0x10;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  RCC_OscInitStruct.PLL.PLLR = 6;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

   /* Activate the OverDrive to reach the 180 MHz Frequency */  
  ret = HAL_PWREx_EnableOverDrive();
  if(ret != HAL_OK)
  {
    while(1) { ; }
  }
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }

}

/**
  * @brief  I2C error callbacks
  * @param  I2cHandle: I2C handle
  * @note   This example shows a simple way to report transfer error, and you can
  *         add your own implementation.
  * @retval None
  */
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
{
  /* Toggle LED2: error */

  while(1)
  {
   //     BSP_LED_On(LED2);
   // HAL_Delay(500);
    //BSP_LED_Off(LED2);
    //HAL_Delay(500);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

当您使用非阻塞、基于中断的HAL函数时,我将定义所有HAL_I2C_*()回调函数,以便能够对中断做出反应(您现在正在轮询状态,以查看操作何时完成)。并确保中断已启用。-然而,为了测试,使用HAL函数的阻塞、非中断变体(即HAL_I2C_Slave_Receive()/_Transmit())通常要容易得多。如果您需要更快的非阻塞操作,您可以将系统设置为稍后使用*\u IT()甚至*\u DMA()函数…连接了哪些管脚?它们在哪里/如何初始化?什么是
I2Cx
?有关@berendi答案的一些详细信息:同一个pin可以连接到多个外围设备,您可以通过GPIO配置对它们进行路由/多路传输。如果您使用的是HAL,则HAL_GPIO_Init()将用于此操作(另请参见数据表中的“备用函数映射”)STM32CubeMX在这里可以派上用场示例代码中的I2Cx代表程序使用的I2C外围设备的“实例”(内存映射寄存器),在SMT32F446x上有4个I2C外围设备->I2C1、I2C2、I2C3、I2C4…-您是否复制/粘贴了教程中的代码?我认为它需要调整……当您使用非阻塞、基于中断的HAL函数时,我会定义所有HAL_I2C_*()回调函数,以便能够对中断做出反应(您现在正在轮询状态,以查看操作何时完成)。并确保中断已启用。-然而,为了测试,使用HAL函数的阻塞、非中断变体(即HAL_I2C_Slave_Receive()/_Transmit())通常要容易得多。如果您需要更快的非阻塞操作,您可以将系统设置为稍后使用*\u IT()甚至*\u DMA()函数…连接了哪些管脚?它们在哪里/如何初始化?什么是
I2Cx
?有关@berendi答案的一些详细信息:同一个pin可以连接到多个外围设备,您可以通过GPIO配置对它们进行路由/多路传输。如果您使用的是HAL,则HAL_GPIO_Init()将用于此操作(另请参见数据表中的“备用函数映射”)STM32CubeMX在这里可以派上用场示例代码中的I2Cx代表程序使用的I2C外围设备的“实例”(内存映射寄存器),在SMT32F446x上有4个I2C外围设备->I2C1、I2C2、I2C3、I2C4…-您是否复制/粘贴了教程中的代码?我认为它需要调整。。。