打印
[STM32F3]

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

[复制链接]
372|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

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

代码和cube工程下载地址

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

一、创建测试工程I2C MASTER

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


使用特权

评论回复
沙发
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2024-2-1 00:04 编辑

I2C模式使能中断

使用特权

评论回复
板凳
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
I2C模式使能中断

使用特权

评论回复
地板
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2024-2-1 00:05 编辑

配置LL库

使用特权

评论回复
5
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
I2C模式使能中断

使用特权

评论回复
6
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2024-2-1 00:05 编辑

配置你使用的开发工具

使用特权

评论回复
7
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
I2C模式使能中断

使用特权

评论回复
8
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2024-2-1 00:06 编辑

生成代码

使用特权

评论回复
9
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
I2C模式使能中断

使用特权

评论回复
10
逢dududu必shu|  楼主 | 2024-1-31 23:59 | 只看该作者
本帖最后由 逢dududu必shu 于 2024-2-1 00:06 编辑

二、创建测试工程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****/

使用特权

评论回复
11
逢dududu必shu|  楼主 | 2024-2-1 00:00 | 只看该作者
I2C模式使能中断

使用特权

评论回复
12
逢dududu必shu|  楼主 | 2024-2-1 00:07 | 只看该作者
发送和读取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****/

使用特权

评论回复
13
逢dududu必shu|  楼主 | 2024-2-1 00:07 | 只看该作者
四、 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****/

使用特权

评论回复
14
逢dududu必shu|  楼主 | 2024-2-1 00:07 | 只看该作者
主函数里啥也没有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 */
}

使用特权

评论回复
15
逢dududu必shu|  楼主 | 2024-2-1 00:07 | 只看该作者
中断函数/* 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****/

使用特权

评论回复
16
逢dududu必shu|  楼主 | 2024-2-1 00:07 | 只看该作者
五、测试效果

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

58

主题

380

帖子

0

粉丝