STM32F1x HAL库学习笔记(9)硬件 I2C(IIC)主从机的配置

本文开发环境:

  • MCU型号:STM32F103ZET6
  • IDE环境: MDK 5.27
  • 代码生成工具:STM32CubeMx 5.4.0
  • HAL库版本:STM32Cube_FW_F1_V1.8.0

本文内容:

  1. STM32CubeMx 配置主从I2C(IIC)
  2. 示例工程

一、简介

I2C 是一种双线协议,由一根时钟线和一根数据线组成,由于时序简单,应用广泛,ST 硬件 I2C 网传不够稳定,通常也用软件来模拟,不过由于软件模拟需要占用CPU的资源,所以在一些情况下,硬件I2C是更好的选择。本文示例了 I2C 的主从通信,由于 STM32F103ZE 拥有2个硬件I2C,所以只需要一个单片机即可模拟双机的通信。

二、使用 STM32CubeMx 配置 I2C

使用 STM32CubeMx(以下简称 Mx) 可以非常方便的配置硬件I2C,一般有以下几个步骤:

  • 选择目标单片机
  • 选择系统时钟源,配置系统时钟树
  • 打开调试 IO 口
  • 配置 I2C:选择速度,配置地址等
  • 生成指定 IDE 的工程

三、硬件I2C的配置

  1. 创建一个新的工程:
    在这里插入图片描述
  2. 选择目标单片机(STM32F103ZET6):
    在这里插入图片描述
  3. 选址时钟源:
    在这里插入图片描述

一般单片机的最小系统板,都有外部晶振,这里可根据实际需求来配置。

  1. 配置系统时钟树:
    在这里插入图片描述

  2. 打开调试:
    在这里插入图片描述

  3. 配置 I2C 主机:
    在这里插入图片描述

由于本文目的是把 I2C 配置为主机,所以其实只有2个选项需要配置,这里保持默认,即使用 标准模式,频率100KHz。

  1. 配置 I2C 从机:
    1. 基本配置:
      在这里插入图片描述2.打开中断:在这里插入图片描述

从机需要配置作为从机时的地址,I2C需要地址,这样就可以实现一对多的通信。地址有2种,7位和10位,本文选择默认的7位。另外,从机需要打开中断,以便使用中断来接收数据。

  1. 配置工程的基本信息
    在这里插入图片描述
  2. 生成工程
    至此已经完成了所有工程的配置,点击 GENERATE CODE 即可生成工程:
    在这里插入图片描述

三、外部上拉

需要注意的是,I2C标准中定义了IO口为开漏模式,所以需要上拉电阻,在进行编程测试之前,请保证 I2C 有外部上拉是电阻,本文上拉电阻为 4.7K:
在这里插入图片描述

四、编程

1. 准备

环境已经准备完成以后,就可以编程来测试代码,Mx 默认是使用 HAL 库来初始化外设,所以可以调用 HAL 的 API 函数来测试 I2C 的通信功能。

本文示例选用以下 2个数组和3 个函数来测试:

//接收和发送数组
static uint8_t I2C_recvBuf[10] = {0};
static uint8_t I2C_sendBuf[10] = {0,1,2,3,4,5,6,7,8,9};
//HAL 接口函数
HAL_I2C_Master_Transmit();             //主机堵塞发送
HAL_I2C_Slave_Receive_IT();            //从机中断接收
HAL_I2C_SlaveRxCpltCallback();         //接收完成回调函数

2. 程序实现

具体程序如下所示:

// #1.定义数组
static uint8_t I2C_recvBuf[10] = {0};
static uint8_t I2C_sendBuf[10] = {0,1,2,3,4,5,6,7,8,9};
int main(void)
{
  ......
  // #2.使能从机中断接收
  HAL_I2C_Slave_Receive_IT(&hi2c2/*接收的I2C*/,I2C_recvBuf/*存放数据的地址*/,sizeof(I2C_recvBuf)/*接收数据的个数*/);
  while (1)
  {
     ......
     // #3.主机发送数据
     HAL_I2C_Master_Transmit(&hi2c1/*发送的I2C*/, (20<<1)|0x00/*地址*/, I2C_sendBuf/*发送数据的地址*/, sizeof(I2C_sendBuf/*发送的字节*/), 1000/*等待的时间*/); 
  }
}

/* 从机接收回调函数 */
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    /* 再次打开 I2C 中断接收 */
	HAL_I2C_Slave_Receive_IT(&hi2c2,I2C_recvBuf,sizeof(I2C_recvBuf));
}

需要注意,在I2C2完成一次接收一次,会关闭中断,并调用回调函数HAL_I2C_SlaveRxCpltCallback() 所以,可以在回调函数中写入数据处理的语句,但是需要运行HAL_I2C_Slave_Receive_IT()来开启接收中断。

3. 验证

将 I2C1 和 I2C2 连接起来,也就是连接主机和从机:

  • PB6 --> PB10
  • PB7 --> PB11

该程序有多种验证的方法:

  1. 在回调函数中,打印 I2C_recvBuf 的值,查看是否和发送的一致。这需要额外添加打印的代码
  2. 使用硬件仿真,通过变量观察窗口查看 I2C_recvBuf 的值,这需要ST-LINK或J-Link调试器
  3. 使用 逻辑分析仪/示波器 直接进行时序的分析,这需要一个逻辑分析仪示波器

本文使用 硬件仿真 的方式:

  1. 运行程序仿真后,将I2C_recvBuf 添加到 Watch1 观察串口中:
    在这里插入图片描述

2 . 观察Watch1中,I2C_recvBuf [] 的值:
在这里插入图片描述

五、注意事项

  • I2C 总线必须外部上拉
  • HAL 库在完成一个中断接收后,会关闭中断,所以需要在回调函数中再次打开
  • 一些 MCU 在调用主机发送时,可能会一直返回数值2,即对于错误:HAL_BUSY,若排除上拉电路问题,可能是遇到 I2C 死锁现象,在官方勘误文件已经做出了应对的方法,详见: 【InterFace】STM32 I2C 死锁问题

六、附件

百度云连接
STM32F103ZE HW_I2C MDK_Project
提取码:5ugn

STM32F1系列是意法半导体(STMicroelectronics)推出的一款32位MCU系列产品,具有丰富的外设和强大的性能。其中,I2C总线是一种常见的串行通信总线,用于连接微控制器和其他设备进行数据传输。 在STM32F1HAL中,提供了I2C的例程,以方便开发者快速使用I2C总线进行数据通信。下面简要介绍一下STM32F1 HALI2C例程的主要功能和使用方法: 1. 初始化I2C总线 (HAL_I2C_Init函数):通过配置I2C的时钟速度、地址模式等参数,初始化I2C总线。在初始化过程中,需要指定I2C的外设号以及总线的时钟源。 2. 写入数据到I2C总线 (HAL_I2C_Master_Transmit函数):通过指定I2C的外设号、目标设备地址、发送的数据缓冲区和数据长度,可以将数据写入到I2C总线。在写入数据之前,需要确保目标设备已经准备好接收数据。 3. 读取I2C总线上的数据 (HAL_I2C_Master_Receive函数):通过指定I2C的外设号、目标设备地址、接收数据的缓冲区和数据长度,可以从I2C总线上读取数据。在读取数据之前,需要确保目标设备已经准备好发送数据。 4. 发送和接收数据(HAL_I2C_Master_Transmit_Receive函数):通过指定I2C的外设号、目标设备地址、发送的数据缓冲区、发送数据的长度、接收数据的缓冲区和接收数据的长度,可以在一次函数调用中同时发送和接收数据。 以上是STM32F1 HALI2C例程的基本功能和使用方法。开发者可以根据具体需求,使用这些例程来实现自己的应用。注意,在使用I2C例程之前,需要在CubeMX工具中正确配置I2C外设的引脚映射和时钟源。 总而言之,STM32F1 HAL提供了丰富的I2C例程,方便开发者在STM32F1系列MCU上使用I2C总线进行数据通信。通过合理使用这些例程,可以快速开发出各种I2C设备的应用。
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值