STM32CubeMX与HAL库开发教程七(IIC通信)

目录

前言

1、IIC总线结构

2、IIC总线通信协议

3、IIC的HAL库驱动程序

4、STM32CubeMX配置


前言

        IIC接口是一种串行数字总线接口,IIC接口只有两根信号线,总线上可以连接多个设备,硬件实现简单,可扩展性强,IIC通信协议可以用普通的GPIO口进行软件模拟,IIC接口主要用于通信速率不强,以及多个器件之间通信的应用场景

1、IIC总线结构

        一个器件的IIC接口只有两根数据线,即双向串行数据线SDA和时钟信号SCL,IIC较为常用的器件有OLED显示屏,E2PROM的24C02,MPU6050陀螺仪,所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。I2C总线上的每一个设备都对应一个唯一的地址。

        IIC总线有以下的特点

1、IIC总线只有两根信号线,SDA是双向串行数据线,SCL是时钟信号线,用于数据的收发同步

2、IIC总线可以挂载多个设备,一般有一个主设备、多个从设备,MCU一般作为主设备,外围器件作为从设备,在IIC通信协议中,主动发起通信的就是主设备,被动相应的就是从设备

3、IIC总线上每个器件有7位或10位的地址,主设备发起通信时,会首先发送目标设备地址,只有地址对应的从设备才会做出相应

4、IIC总线的两根信号线有上拉电阻,当IIC器件空闲时,其输出口是高阻态,当所有设备都空闲时,IIC总线是高电平

5、IIC通信有标准模式和快速模式,标准模式传输率为100kbit/s,快速模式传输率为400kbit/s

2、IIC总线通信协议

        IIC总线通信总是由主机启动,每个通信过程由起始信号开始,由停止信号结束,一个数据包有八位,每个数据包后有一个应答位和非应答位,例如下面的时序图

起始位:当SCL是高电平时,SDA的下降沿就是起始位,是启动一次IIC通信的起始信号

停止位:当SCL是高电平时,SDA的上升沿就是停止位,是停止一次IIC通信的结束信号

数据位:在SCL的一个时钟周期内传输一个数据位,当SCL为低电平时,发送设备更新SDA的电平,当SCL为高电平时,接收设备读取SDA的电平就是有效的一位数据

数据包:IIC数据通信一个数据包总是8位,也就是1字节的数据

应答信号:在发送完8位数据包时,发送设备在第九个SCL时钟周期采集接收设备的应答信号,若在SCL的第九个周期采集SDA信号为低电平,就是应答ACK,如果采集SDA信号为高电平就是非应答信号NACK

3、IIC的HAL库驱动程序

        IIC的HAL驱动程序头文件是stm32f1xx_hal_i2c.hstm32f1xx_hal_i2c.ex.h

 IIC的HAL库驱动程序包含宏定义,结构体定义,宏函数和功能函数,IIC的数据传输方式有阻塞式,中断方式和DMA方式

对IIC接口进行初始化配置的函数是HAL_I2C_Init() 以下为函数原型

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);   其中hi2c是IIC接口的对象指针,是I2C_HandleTypeDef的结构体类型指针,在CubeMX自动生成的文件I2C.c中,会为启动的IIC接口定义外设对象变量 例如 I2C_HandleTypeDef hi2c1;

在IIC中的三种发送形式的函数用处差不多,只是接收和发送的形式变了,参数和功能没变,这里我们只介绍几个常用的函数

 HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

功能:IIC写数据
参数:

*hi2c 设置使用的是那个IIC 例:&hi2c2

DevAddress 写入的地址 设置写入数据的地址 例 0xA0

*pData 需要写入的数据

Size 要发送的字节数

Timeout 最大传输时间,超过传输时间将自动退出传输函数

HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

功能:IIC读一个字节

参数:

*hi2c 设置使用的是那个IIC 例:&hi2c2

DevAddress 写入的地址 设置写入数据的地址 例 0xA0

*pData 需要写入的数据

Size 要发送的字节数

Timeout 最大传输时间,超过传输时间将自动退出传输函数

举例 :发送两个字节

HAL_I2C_Master_Transmit(&hi2c1,0xA1,(uint8_t*)TxData,2,1000) ;;

IIC写数据函数


HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
/* 第1个参数为I2C操作句柄
   第2个参数为从机设备地址
   第3个参数为从机寄存器地址
   第4个参数为从机寄存器地址长度
   第5个参数为发送的数据的起始地址
   第6个参数为传输数据的大小
   第7个参数为操作超时时间   */

功能: IIC写多个数据 该函数适用于IIC外设里面还有子地址寄存器的设备,比方说E2PROM,除了设备地址,每个存储字节都有其对应的地址

参数:

*hi2c: I2C设备号指针,设置使用的是那个IIC 例:&hi2c2

DevAddress: 从设备地址 从设备的IIC地址 例E2PROM的设备地址 0xA0

MemAddress: 从机寄存器地址 ,每写入一个字节数据,地址就会自动+1

MemAddSize: 从机寄存器地址字节长度 8位或16位

写入数据的字节类型 8位还是16位
I2C_MEMADD_SIZE_8BIT
I2C_MEMADD_SIZE_16BIT
在stm32f1xx_hal_i2c.h中有定义

        使用HAL_I2C_Mem_Write等于先使用HAL_I2C_Master_Transmit传输第一个寄存器地址,再用HAL_I2C_Master_Transmit传输写入第一个寄存器的数据。可以传输多个数据

void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
{
    uint8_t TxData[2] = {REG_Address,REG_data};
    while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)
    {
        if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
                {
                  Error_Handler();
                }
    }
}

在传输过程,寄存器地址和源数据地址是会自加的。

至于读函数也是如此,因此用HAL_I2C_Mem_Write和HAL_I2C_Mem_Read,来写读指定设备的指定寄存器数据是十分方便的,让设计过程省了好多步骤。

举例:8位  16位

HAL_I2C_Mem_Write(&hi2c2, ADDR, i, I2C_MEMADD_SIZE_8BIT,&(I2C_Buffer_Write[i]),8, 1000);

HAL_I2C_Mem_Read(&hi2c2, ADDR, i, I2C_MEMADD_SIZE_8BIT,&(I2C_Buffer_Write[i]),8, 1000);
// 8 位

HAL_I2C_Mem_Write(&hi2c2, ADDR, i, I2C_MEMADD_SIZE_16BIT,&(I2C_Buffer_Write[i]),8, 1000);

HAL_I2C_Mem_Read(&hi2c2, ADDR, i, I2C_MEMADD_SIZE_16BIT,&(I2C_Buffer_Write[i]),8, 1000);
// 16 位

如果只往某个外设中写数据,则用Master_Transmit。 如果是外设里面还有子地址,例如我们的E2PROM,有设备地址,还有每个数据的寄存器存储地址。则用Mem_Write。
Mem_Write是2个地址,Master_Transmit只有从机地址

4、STM32CubeMX配置

点击I2C1 设置为I2C 因为我们的硬件IIC 芯片一般都是主设备,也就是一般情况设置主模式即可

I2C1是参数设置分为两组

Master features  主模式特性

I2C Speed Mode: IIC模式设置 快速模式和标准模式。实际上也就是速率的选择。

I2C Clock Speed:I2C传输速率,默认为100KHz,快速模式可以最高400KHZ

Slave  features  从模式特性

Clock No Stretch Mode:禁止时钟延长,设置Disabled表示允许时钟延长

IIC时钟拉伸(Clock stretching)
clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretching是可选的,实际上大多数从设备不包括SCL驱动,所以它们不能stretch时钟.
Primary Address Length selection: 从设备地址长度 设置从设备的地址是7bit还是10bit 大部分为7bit
-Dual Address Acknowledged: 双地址确认

Primary slave address:  从设备初始地址

这里我们保持默认即可

其实在初学者学到这里已经可以简单进行IIC的使用了,在我们配置完成后,常用的外设例如MPU6050和OLED显示屏都有自己的函数库,我们学会寻找和调用这些别人封装好的函数就可以,下面举一个OLED显示屏函数库使用IIC的例子

/**
  * @brief  OLED写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void OLED_WriteCommand(uint8_t Command)
{
	 uint8_t *pData;
	 pData = &Command;
	 HAL_I2C_Mem_Write(&Hardware_IIC_No,0x78,0x00,I2C_MEMADD_SIZE_8BIT,pData,1,100);
}

/**
  * @brief  OLED写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void OLED_WriteData(uint8_t Data)
{
	 uint8_t *pData;
	 pData = &Data;
	HAL_I2C_Mem_Write(&Hardware_IIC_No,0x78,0x40,I2C_MEMADD_SIZE_8BIT,pData,1,100);

}

  • 23
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
嵌入式系统设计是指将计算机系统集成到其他设备或系统中,以实现特定功能。而基于STM32CubeMXHAL库的嵌入式系统设计是指利用ST公司的STM32系列微控制器,结合STM32CubeMX工具和HAL库(Hardware Abstraction Layer),进行软硬件设计和开发的过程。 STM32CubeMX是ST公司推出的一款嵌入式系统设计工具,它提供了图形化的界面,可以帮助开发者快速配置STM32微控制器的引脚、时钟、外设等参数,生成初始化代码和项目文件,使整个开发过程更加简化和快捷。 HAL库STM32系列微控制器的硬件抽象层库,提供了一组封装了底层硬件操作的API接口,使开发者能够更加方便地进行外设控制和数据处理等操作。开发者可以根据具体的需求,选择需要的API接口,编写相应的代码,完成对硬件的控制和操作。 在使用STM32CubeMXHAL库进行嵌入式系统设计时,可以通过STM32CubeMX工具进行硬件的初始化和配置,生成相应的代码和项目文件。然后,在IDE(集成开发环境)中使用HAL库提供的API接口,编写代码进行软件的开发和应用程序的编写。通过这种方式,开发者可以在短时间内快速完成嵌入式系统设计,提高开发效率和产品质量。 总而言之,基于STM32CubeMXHAL库的嵌入式系统设计提供了一种快速、简化的嵌入式软硬件开发方法,使开发者能够更加高效地进行嵌入式应用的设计与开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值