STM32 I2C(hal库)

I2C:

I2C和串口不同,只有一条线可以用来传递数据(SDA),另一条用于提供同步时钟脉冲的时钟线(SCL),并且为"半双工"通信,同一时刻只能进行一个方向的通信,因此采用主从模式:一台为主机,另一台(多台)为从机:

IC2读取OLED屏幕数据:

具体原理可以看我的标准库中的I2C,接下来我们就直接配置CubeMX:

先到Connectivity点击I2C,然后选择I2C模式,参数配置默认就好,然后就可以看到右边PB6和PB7配置为I2C_SLC和I2C_SDA

随后按照这个参数进行配置I2C,不过初始化配置默认就是这个,所以也不用改

这是OLED屏幕指令:

0x00 是命令流

0x8d,0x14 使能电荷泵

0xaf 打开屏幕的开关

0xa5 使屏幕全亮

先从机也就是OLED屏幕发送这些指令就能开启对应的操作

这是I2C的发送数据和读写数据的函数

最后是配置函数:

c 复制代码
	uint8_t Commands[]={0x00,0x8d,0x14,0xaf,0xa5};

  HAL_I2C_Master_Transmit(&hi2c1,0x78,Commands,sizeof(Commands),HAL_MAX_DELAY);

  uint8_t DataOled;
  HAL_I2C_Master_Receive(&hi2c1,0x78,&DataOled,1,HAL_MAX_DELAY);
  
  if((DataOled&(0x01<<6))==0)
  {
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
  }else{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
  }

I2C中断模式和DMA模式&简单状态机:

其实I2C中断模式和DMA模式与串口中断模式和DMA模式本质是一样的,所以不做过多赘述,直接开始CubeMX配置:

首先打开NVIC中断向量,一个是I2C事件中断,一个是I2C错误中断,本节主要讲事件中断

随后就是发送和接收函数:

c 复制代码
  HAL_I2C_Master_Transmit_IT(&hi2c1,0x78,Commands,sizeof(Commands));
  
  HAL_I2C_Master_Receive_IT(&hi2c1,0x78,&DataOled,1);

从串口小节我们就了解到,这个中断和DMA模式是非阻塞模式,所以这些操作一瞬间就完成了,不需要等待,所以就不需要等待时间参数

c 复制代码
  HAL_I2C_Master_Transmit_IT(&hi2c1,0x78,Commands,sizeof(Commands));

  uint8_t DataOled;
  HAL_I2C_Master_Receive_IT(&hi2c1,0x78,&DataOled,1);
  if((DataOled&(0x01<<6))==0)
  {
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
  }else{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
  }

因为这个中断和DMA模式是非阻塞模式 ,它们将任务交给外设后就会接着向下执行,并不会等到数据的接收和发送完成,整个通信流程都交给外设和中断控制,通信完成后再通过中断来通知我们,所以上面的发送和接受函数只是CPU通知外设进行发起和接受,它们并没有完成,CUO就会跳到处理判断函数这里,这时我们就需要一个简单的状态机来,不同的状态下做不同的事

这是我们的状态机,现在我们就开始配置代码吧

main主函数:

c 复制代码
    if(OLED_State==0)
    {
      OLED_Start();
      OLED_State=1;
    }
    else if(OLED_State==2)
    {
      OLED_ReceiveData();
      OLED_State=3;
    }
    else if(OLED_State==4)
    {
      LED_Open();
    }

OLED.C函数:

c 复制代码
#include "main.h"
#include "i2c.h"

void OLED_Start(void)
{
	static	uint8_t Commands[]={0x00,0x8d,0x14,0xaf,0xae};

	HAL_I2C_Master_Transmit_IT(&hi2c1,0x78,Commands,sizeof(Commands));	
}
uint8_t DataOled;
volatile uint8_t OLED_State=0;  // 0=空闲, 1=发送中, 2=发送完成, 3=接收中, 4=接收完成,volatile
void OLED_ReceiveData(void)
{
	HAL_I2C_Master_Receive_IT(&hi2c1,0x78,&DataOled,1);	
}

void LED_Open(void)
{
	if((DataOled&(0x01<<6))==0)
	{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
	}else{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
	}
}

//I2C主机发送完成回调函数
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
	if(hi2c==&hi2c1)
	{
		OLED_State=2;
	}
}

//I2C主机接收完成回调函数
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
	if(hi2c==&hi2c1)
	{
		OLED_State=4;
	}
}

**这里注意:**要在OLED.h中加入extern volatile uint8_t OLED_State; 定义为全局变量

最后是DMA模式,其实就是在原代码基础上将IT改成DMA就ok了,回调函数用的也是同一个,这里就不多写了

最后总结I2C的相关函数:

c 复制代码
/* 普通I2C接收函数
 * 第一个参数是I2C句柄
 * 第二个参数是从机地址,8位地址,最后一位为0,函数内部会自动处理最后一位
 * 第三个参数是要发送的数据的指针
 * 第四个参数是要发送的字节数
 * 第五个参数是超时时间
 */
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 
/*参数同上*/
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

//I2C中断模式发送函数
HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
 
//I2C中断模式接收函数
HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
 
//I2C主机发送完成回调函数
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
 
//I2C主机接收完成回调函数
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
相关推荐
深圳市宝华视联4 小时前
Python 读取 IP 视频流简单 Demo
python·嵌入式硬件·opencv·网络协议·tcp/ip·实时音视频·嵌入式实时数据库
恒锐丰科技韩生4 小时前
RB6005A|晶准 单节锂电池内置 MOS 保护芯片 DFN2×3‑8
嵌入式硬件·硬件工程
youshi66684 小时前
stm32-PWR、低功耗模式
stm32·单片机·嵌入式硬件
ACP广源盛139246256734 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 Serdes 长距离视频传输芯片 GSV5800 在私有化 AI 服务中的价值与应用场景
大数据·数据库·人工智能·嵌入式硬件·矩阵·开源·音视频
Funing75 小时前
STM32 电机动态 PI 控制:从编码器反馈、增量式 PI 到 Matlab 参数拟合与 PWM 输出
stm32·嵌入式硬件·matlab·pi控制算法
云泽8085 小时前
深入浅出 STM32(十八):时钟树、总线与寄存器的底层联动机制
stm32·单片机·嵌入式硬件
米饭不加菜6 小时前
C51 语言参考手册
经验分享·笔记·单片机·嵌入式硬件
深圳市宝华视联6 小时前
院感约束下,手术室音视频布线与设备摆放实施注意事项
嵌入式硬件·音视频·实时音视频·视频编解码·嵌入式实时数据库
科芯创展6 小时前
2.7VIN,5VOUT,360KHz,电荷泵升压芯片,XZ3120
单片机
dozenyaoyida6 小时前
LittleFS 嵌入式文件系统机制拆解与某 RISC-V MCU 实测配置
单片机·嵌入式·文件系统·risc-v·littlefs·flash存储