STM32L031F6 LL库硬件I2C使用,中断模式

Posted シ゛甜虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32L031F6 LL库硬件I2C使用,中断模式相关的知识,希望对你有一定的参考价值。

最近用到了I2C,之前都是用软件模拟I2C,听说硬件I2C已经比之前好用了,这次决定尝试一下

代码和cube工程下载地址

stm32l053硬件i2c发送接收程序-C文档类资源-CSDN下载

一、创建测试工程I2C MASTER

配置上拉,串口用来查看调试信息

I2C模式使能中断

配置LL库

配置你使用的开发工具

 

生成代码

二、创建测试工程I2C SLAVE

配置上拉,串口用来查看调试信息,配置与MASTER相同即可,硬件I2C的2个IO口直连

三、 MASTER代码编写

master是主动请求,slave用中断处理所有操作,这里把主要代码贴出来

i2c.c

/**
  ******************************************************************************
  * @file    i2c.c
  * @brief   This file provides code for the configuration
  *          of the I2C instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

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

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* I2C1 init function */
void MX_I2C1_Init(void)


  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  LL_I2C_InitTypeDef I2C_InitStruct = 0;

  LL_GPIO_InitTypeDef GPIO_InitStruct = 0;

  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  /**I2C1 GPIO Configuration
  PA9   ------> I2C1_SCL
  PA10   ------> I2C1_SDA
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);

  /* I2C1 interrupt Init */
  NVIC_SetPriority(I2C1_IRQn, 0);
  NVIC_EnableIRQ(I2C1_IRQn);

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  /** I2C Initialization
  */
  LL_I2C_EnableAutoEndMode(I2C1);
  LL_I2C_DisableOwnAddress2(I2C1);
  LL_I2C_DisableGeneralCall(I2C1);
  LL_I2C_EnableClockStretching(I2C1);
  I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  I2C_InitStruct.Timing = 0x00000708;
  I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
  I2C_InitStruct.DigitalFilter = 0;
  I2C_InitStruct.OwnAddress1 = 0x01;
  I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  LL_I2C_Init(I2C1, &I2C_InitStruct);
  LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
  /* USER CODE BEGIN I2C1_Init 2 */
	LL_I2C_EnableSMBusAlert(I2C1);
	LL_I2C_EnableOwnAddress1(I2C1);	 //
  LL_I2C_Enable(I2C1);
	/* Listen IT */
//  LL_I2C_EnableIT_ADDR(I2C1);
//  LL_I2C_EnableIT_NACK(I2C1);
//  LL_I2C_EnableIT_ERR(I2C1);
//  LL_I2C_EnableIT_STOP(I2C1);
  /* USER CODE END I2C1_Init 2 */



/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

发送和读取i2c数据在主函数中,这里用的是软件停止位,同样可以使用自动停止位LL_I2C_MODE_AUTOEND,使用自动停止位不需要主动发送停止

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)

  /* USER CODE BEGIN 1 */
	uint16_t i = 0;
	int timeOut = 0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);

  /* System interrupt init*/
  /* SysTick_IRQn interrupt configuration */
  NVIC_SetPriority(SysTick_IRQn, 3);

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_LPUART1_UART_Init();
  /* USER CODE BEGIN 2 */
	LL_LPUART_Enable(LPUART1);
	printf("Init Ok!\\r\\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  
		LL_mDelay(5000);
		
		LL_I2C_HandleTransfer(I2C1, 0x10, LL_I2C_ADDRSLAVE_7BIT, 10, LL_I2C_MODE_SOFTEND, LL_I2C_GENERATE_START_WRITE);
		printf("I2C Send Data:\\t");
		for(i=0;i<10;i++)
		
			LL_mDelay(1);
			while(!LL_I2C_IsActiveFlag_TXIS(I2C1))
			
				LL_mDelay(1);
				timeOut++;
				if(timeOut>100)
				
					timeOut = 0;
					break;
				
			
			LL_I2C_TransmitData8(I2C1,(uint8_t)i);
			printf("%x\\t",(uint8_t)i);
	 
	  printf("\\r\\nI2C Recv Data:\\t");
	  LL_mDelay(10);
		LL_I2C_HandleTransfer(I2C1, 0x10, LL_I2C_ADDRSLAVE_7BIT, 0, LL_I2C_MODE_SOFTEND,LL_I2C_GENERATE_STOP);
		LL_mDelay(50);
		LL_I2C_HandleTransfer(I2C1, 0x10, LL_I2C_ADDRSLAVE_7BIT, 10, LL_I2C_MODE_SOFTEND,LL_I2C_GENERATE_START_READ);
		for(i=0;i<10;i++)
		
			LL_mDelay(1);
			while(!LL_I2C_IsActiveFlag_RXNE(I2C1))
					
				LL_mDelay(1);
				timeOut++;
				if(timeOut>100)
				
					timeOut = 0;
					break;
				
			
			printf("%x\\t",LL_I2C_ReceiveData8(I2C1));
		
		printf("\\r\\n");
		LL_mDelay(10);
		LL_I2C_HandleTransfer(I2C1, 0x10, LL_I2C_ADDRSLAVE_7BIT, 0, LL_I2C_MODE_SOFTEND,LL_I2C_GENERATE_STOP);
		
//		LL_I2C_HandleTransfer(I2C1, 0x00, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
//	
//		while(!LL_I2C_IsActiveFlag_TXIS(I2C1))
//     
//    	
//		LL_I2C_TransmitData8(I2C1,0x01);

//		while(!LL_I2C_IsActiveFlag_TXIS(I2C1))
//     
//    	
//		LL_I2C_TransmitData8(I2C1,0x1f);
//		
//	
//		LL_I2C_HandleTransfer(I2C1, 0x00, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_AUTOEND,LL_I2C_GENERATE_START_READ);
//		while(!LL_I2C_IsActiveFlag_RXNE(I2C1))
//				
//		
//		printf("%x\\r\\n",LL_I2C_ReceiveData8(I2C1));
//		LL_I2C_HandleTransfer(I2C1, 0x00, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_AUTOEND,LL_I2C_GENERATE_START_READ);
//		while(!LL_I2C_IsActiveFlag_RXNE(I2C1))
//				
//		
//		printf("%x\\r\\n",LL_I2C_ReceiveData8(I2C1));
		
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  
  /* USER CODE END 3 */


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)

  LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_0)
  
  
  LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
  LL_RCC_MSI_Enable();

   /* Wait till MSI is ready */
  while(LL_RCC_MSI_IsReady() != 1)
  

  
  LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5);
  LL_RCC_MSI_SetCalibTrimming(0);
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);

   /* Wait till System clock is ready */
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI)
  

  

  LL_Init1msTick(2097000);

  LL_SetSystemCoreClock(2097000);
  LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
  LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);


/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
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 */


#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 CODE BEGIN 6 */
  /* 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) */
  /* USER CODE END 6 */

#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

四、 SLAVE代码编写

配置代码

/**
  ******************************************************************************
  * @file    i2c.c
  * @brief   This file provides code for the configuration
  *          of the I2C instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

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

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* I2C1 init function */
void MX_I2C1_Init(void)


  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  LL_I2C_InitTypeDef I2C_InitStruct = 0;

  LL_GPIO_InitTypeDef GPIO_InitStruct = 0;

  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  /**I2C1 GPIO Configuration
  PA9   ------> I2C1_SCL
  PA10   ------> I2C1_SDA
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);

  /* I2C1 interrupt Init */
  NVIC_SetPriority(I2C1_IRQn, 0);
  NVIC_EnableIRQ(I2C1_IRQn);

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  /** I2C Initialization
  */
  LL_I2C_EnableAutoEndMode(I2C1);
  LL_I2C_DisableOwnAddress2(I2C1);
  LL_I2C_DisableGeneralCall(I2C1);
  LL_I2C_EnableClockStretching(I2C1);
  I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  I2C_InitStruct.Timing = 0x00000708;
  I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
  I2C_InitStruct.DigitalFilter = 0;
  I2C_InitStruct.OwnAddress1 = 0x10;
  I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  LL_I2C_Init(I2C1, &I2C_InitStruct);
  LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
  /* USER CODE BEGIN I2C1_Init 2 */
	LL_I2C_EnableSMBusAlert(I2C1);
	LL_I2C_EnableOwnAddress1(I2C1);	 //
  LL_I2C_Enable(I2C1);
	/* Listen IT */
  LL_I2C_EnableIT_ADDR(I2C1);
  LL_I2C_EnableIT_NACK(I2C1);
  LL_I2C_EnableIT_ERR(I2C1);
  LL_I2C_EnableIT_STOP(I2C1);
  /* USER CODE END I2C1_Init 2 */



/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

主函数里啥也没有

int main(void)

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);

  /* System interrupt init*/
  /* SysTick_IRQn interrupt configuration */
  NVIC_SetPriority(SysTick_IRQn, 3);

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_LPUART1_UART_Init();
  /* USER CODE BEGIN 2 */
	LL_LPUART_Enable(LPUART1);
	printf("Init Ok!\\r\\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  
		LL_mDelay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  
  /* USER CODE END 3 */

中断函数

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32l0xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l0xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/

/* USER CODE BEGIN EV */
int ubReceiveIndex=0;
int ubSendIndex=0;
uint8_t aReceiveBuffer[256];
void Slave_Reception_Callback(void)

	uint8_t recvData = LL_I2C_ReceiveData8(I2C1);
	printf("ubReceiveIndex:%x,LL_I2C_ReceiveData8:%x\\r\\n",ubReceiveIndex,recvData);
  /* Read character in Receive Data register. RXNE flag is cleared by reading data in RXDR register */
  aReceiveBuffer[ubReceiveIndex++] = recvData;


void Error_Callback()

	uint8_t i=0;
	uint8_t data =0;
	printf("Error_Callback:");
	/* Clear NACKF Flag */
	LL_I2C_ClearFlag_NACK(I2C1);        
	/* Clear STOP Flag */
	LL_I2C_ClearFlag_STOP(I2C1);        
	/* Clear Configuration Register 2, */
	I2C1->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN));
//	for(i=0;i<200;i++)
//	
//		data = LL_I2C_ReceiveData8(I2C1);
//		printf("%x\\t",data);
//		if(data == 0x00)
//		
//			break;
//		
//	
	printf("\\r\\n");


void Slave_Complete_Callback()

	uint16_t i=0;
	printf("I2C Slave Recv Data\\r\\n");
	for(i=0;i<ubReceiveIndex;i++)
	
		printf("%x\\t",aReceiveBuffer[i]);
	
	printf("\\r\\n");

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M0+ Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable Interrupt.
  */
void NMI_Handler(void)

  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  
  
  /* USER CODE END NonMaskableInt_IRQn 1 */


/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)

  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  


/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)

  /* USER CODE BEGIN SVC_IRQn 0 */

  /* USER CODE END SVC_IRQn 0 */
  /* USER CODE BEGIN SVC_IRQn 1 */

  /* USER CODE END SVC_IRQn 1 */


/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)

  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */


/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)

  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */

  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */


/******************************************************************************/
/* STM32L0xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32l0xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles I2C1 event global interrupt / I2C1 wake-up interrupt through EXTI line 23.
  */
void I2C1_IRQHandler(void)

  /* USER CODE BEGIN I2C1_IRQn 0 */
  if(LL_I2C_IsActiveFlag_ADDR(I2C1))
  
    /* Verify the Address Match with the OWN Slave address */
    if(LL_I2C_GetAddressMatchCode(I2C1) == 0x10)
    
      /* Verify the transfer direction, a write direction, Slave enters receiver mode */
      if(LL_I2C_GetTransferDirection(I2C1) == LL_I2C_DIRECTION_WRITE)
      
        /* Clear ADDR flag value in ISR register */
        LL_I2C_ClearFlag_ADDR(I2C1);
        /* Enable Receive Interrupt */
        LL_I2C_EnableIT_RX(I2C1);
      
      else
      
        /* Clear ADDR flag value in ISR register */
        LL_I2C_ClearFlag_ADDR(I2C1);
				LL_I2C_ClearFlag_TXE(I2C1); 
				LL_I2C_EnableIT_TX(I2C1);
      
    
    else
    
      /* Clear ADDR flag value in ISR register */
      LL_I2C_ClearFlag_ADDR(I2C1);
        
      /* Call Error function */
      Error_Callback();
    
  
  /* Check RXNE flag value in ISR register */
  else if(LL_I2C_IsActiveFlag_TXIS(I2C1))
  
		LL_I2C_TransmitData8(I2C1, aReceiveBuffer[ubSendIndex++]);
		//printf("%x\\t%x\\r\\n",aReceiveBuffer[0],aReceiveBuffer[1]);
  	
  else if(LL_I2C_IsActiveFlag_RXNE(I2C1))
  
    /* Call function Slave Reception Callback */
    Slave_Reception_Callback();
  
  /* Check STOP flag value in ISR register */
  else if(LL_I2C_IsActiveFlag_STOP(I2C1))
  
    /* End of Transfer */
    LL_I2C_ClearFlag_STOP(I2C1);
    
    /* Call function Slave Complete Callback */
    Slave_Complete_Callback();
		
		ubReceiveIndex =0; 
		ubSendIndex = 0;
  
  else
  
    /* Call Error function */
    Error_Callback();
  
  /* USER CODE END I2C1_IRQn 0 */

  /* USER CODE BEGIN I2C1_IRQn 1 */

  /* USER CODE END I2C1_IRQn 1 */


/* USER CODE BEGIN 1 */

/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

五、测试效果

以上是关于STM32L031F6 LL库硬件I2C使用,中断模式的主要内容,如果未能解决你的问题,请参考以下文章

STM32L031 LL库读写内部EEPROM

STM32L031写Flash不使用HAL库

STM32Cube STM32L053闹钟唤醒LL库和HAL库

STM32Cube STM32L053配置RTC WAKEUP中断唤醒

STM32Cube STM32L053配置RTC WAKEUP中断唤醒

STM32L151 LL库串口发送丢数据解决办法