STM32F407系列硬件I2C笔记

这篇具有很好参考价值的文章主要介绍了STM32F407系列硬件I2C笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32F407系列有3个硬件I2C:

I2C1:该接口位于GPIOB引脚上,包括PB6(I2C1_SCL)和PB7(I2C1_SDA)。

I2C2:该接口位于GPIOB引脚上,包括PB10(I2C2_SCL)和PB11(I2C2_SDA)。

I2C3:该接口位于GPIOA和GPIOC引脚上,包括PA8(I2C3_SCL)和PC9(I2C3_SDA)。
 

硬件I2C的速度比软件I2C更快,硬件I2C通常可以达到几百kHz甚至更高的速度,软件I2C几十kHz

I2C1.C文件

#include "I2C1.h"


// I2C1初始化函数
void I2C1_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;
    
    // 使能GPIOB和I2C1时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    
    // 配置GPIOB的引脚为复用模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // 配置引脚复用映射
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);  // SCL
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);  // SDA
    
    // 配置I2C1
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;  // 设置自身设备地址
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;  // 设置通信速度,这里为100kHz
    
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
}




void I2C1_Start(void)
{
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
}

void I2C1_Stop(void)
{
    I2C_GenerateSTOP(I2C1, ENABLE);
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
}

void I2C1_SendData(uint8_t slaveAddr, uint8_t* data, uint8_t len)
{
    I2C1_Start();
    I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    for (uint8_t i = 0; i < len; i++)
    {
        I2C_SendData(I2C1, data[i]);
        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    }

    I2C1_Stop();
}

void I2C1_ReceiveData(uint8_t slaveAddr, uint8_t* data, uint8_t len)
{
    I2C1_Start();
    I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    for (uint8_t i = 0; i < len; i++)
    {
        if (i == len - 1)
            I2C_AcknowledgeConfig(I2C1, DISABLE);

        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
        data[i] = I2C_ReceiveData(I2C1);
    }

    I2C1_Stop();
}


I2C1.H文件

#ifndef __I2C1_H
#define __I2C1_H
#include "sys.h" 


void I2C1_Init(void);// I2C1初始化函数
void I2C1_Start(void);
void I2C1_Stop(void);
void I2C1_SendData(uint8_t slaveAddr, uint8_t* data, uint8_t len);
void I2C1_ReceiveData(uint8_t slaveAddr, uint8_t* data, uint8_t len);


#endif



I2C2.C文件

#include "I2C2.h"



// I2C2初始化函数
void I2C2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    // 打开I2C2和GPIOB的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    // 配置GPIOB的引脚为I2C2功能
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置GPIO引脚复用功能
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);

    // I2C2配置
    I2C_InitStructure.I2C_ClockSpeed = 100000;  // 设置时钟速度为100kHz
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C2, &I2C_InitStructure);

    // 使能I2C2
    I2C_Cmd(I2C2, ENABLE);
}

// I2C2发送数据函数
void I2C2_WriteData(uint8_t address, uint8_t reg, uint8_t data)
{
    // 等待I2C2处于空闲状态
    while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))
        ;

    // 发送START信号
    I2C_GenerateSTART(I2C2, ENABLE);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和写指令
    I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;

    // 发送寄存器地址
    I2C_SendData(I2C2, reg);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 发送数据
    I2C_SendData(I2C2, data);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 发送STOP信号
    I2C_GenerateSTOP(I2C2, ENABLE);
}

// I2C2接收数据函数
uint8_t I2C2_ReadData(uint8_t address, uint8_t reg)
{
    uint8_t data;

    // 等待I2C2处于空闲状态
    while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))
        ;

    // 发送START信号
    I2C_GenerateSTART(I2C2, ENABLE);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和写指令
    I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;

    // 发送寄存器地址
    I2C_SendData(I2C2, reg);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 重新发送START信号,切换到接收模式
    I2C_GenerateSTART(I2C2, ENABLE);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和读指令
    I2C_Send7bitAddress(I2C2, address, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;

    // 开启ACK
    I2C_AcknowledgeConfig(I2C2, ENABLE);

    // 接收数据
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    data = I2C_ReceiveData(I2C2);

    // 发送STOP信号
    I2C_GenerateSTOP(I2C2, ENABLE);

    return data;
}




I2C2.h文件

#ifndef __I2C2_H
#define __I2C2_H
#include "sys.h" 


// I2C2初始化函数
void I2C2_Init(void);

// I2C2发送数据函数
// 参数:
//   address: 目标设备地址
//   reg: 寄存器地址
//   data: 要发送的数据
void I2C2_WriteData(uint8_t address, uint8_t reg, uint8_t data);

// I2C2接收数据函数
// 参数:
//   address: 目标设备地址
//   reg: 寄存器地址
// 返回值:
//   读取到的数据
uint8_t I2C2_ReadData(uint8_t address, uint8_t reg);




#endif


I2C3.C文件

#include "I2C3.h"

// I2C3初始化函数
void I2C3_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    // 打开I2C3和GPIOA的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // 配置GPIOA的引脚为I2C3功能
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置GPIO引脚复用功能
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_I2C3);

    // I2C3配置
    I2C_InitStructure.I2C_ClockSpeed = 100000;  // 设置时钟速度为100kHz
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C3, &I2C_InitStructure);

    // 使能I2C3
    I2C_Cmd(I2C3, ENABLE);
}

// I2C3发送数据函数
void I2C3_WriteData(uint8_t address, uint8_t reg, uint8_t data)
{
    // 等待I2C3处于空闲状态
    while (I2C_GetFlagStatus(I2C3, I2C_FLAG_BUSY))
        ;

    // 发送START信号
    I2C_GenerateSTART(I2C3, ENABLE);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和写指令
    I2C_Send7bitAddress(I2C3, address, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;

    // 发送寄存器地址
    I2C_SendData(I2C3, reg);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 发送数据
    I2C_SendData(I2C3, data);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 发送STOP信号
    I2C_GenerateSTOP(I2C3, ENABLE);
}

// I2C3接收数据函数
uint8_t I2C3_ReadData(uint8_t address, uint8_t reg)
{
    uint8_t data;

    // 等待I2C3处于空闲状态
    while (I2C_GetFlagStatus(I2C3, I2C_FLAG_BUSY))
        ;

    // 发送START信号
    I2C_GenerateSTART(I2C3, ENABLE);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和写指令
    I2C_Send7bitAddress(I2C3, address, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;

    // 发送寄存器地址
    I2C_SendData(I2C3, reg);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;

    // 重新发送START信号,切换到接收模式
    I2C_GenerateSTART(I2C3, ENABLE);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
        ;

    // 发送目标设备地址和读指令
    I2C_Send7bitAddress(I2C3, address, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;

    // 开启ACK
    I2C_AcknowledgeConfig(I2C3, ENABLE);

    // 接收数据
    while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    data = I2C_ReceiveData(I2C3);

    // 发送STOP信号
    I2C_GenerateSTOP(I2C3, ENABLE);

    return data;
}

I2C3.h文件文章来源地址https://www.toymoban.com/news/detail-759586.html

#ifndef __I2C3_H
#define __I2C3_H
#include "sys.h" 


// I2C3初始化函数
void I2C3_Init(void);

// I2C3发送数据函数
// 参数:
//   address: 目标设备地址
//   reg: 寄存器地址
//   data: 要发送的数据
void I2C3_WriteData(uint8_t address, uint8_t reg, uint8_t data);

// I2C3接收数据函数
// 参数:
//   address: 目标设备地址
//   reg: 寄存器地址
// 返回值:
//   读取到的数据
uint8_t I2C3_ReadData(uint8_t address, uint8_t reg);



#endif

到了这里,关于STM32F407系列硬件I2C笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】入门(七):I2C硬件控制方式

    之所以叫“I2C硬件控制方式”是与“软件控制方式”相对。I2C软件控制,就是写程序直接操作两个GPIO引脚,分别作为时钟线SCL和数据线SDA,按照I2C协议的时序要求,操作GPIO输入、输出、高电平、低电平。 听着就很复杂,好在STM32中有I2C的硬件实现,即通过简单的操作寄存器

    2023年04月08日
    浏览(19)
  • STM32 HAL FreeRTOS 硬件I2C 使用

    因为某个项目想要颜色识别,去识别球的颜色,但是又不想多来个摄像头,所以想尝试一下颜色传感器的方案。但是经过尝试,HAL库生成的 FreeRTOS 硬件 I2C 读写一直在报错。 刚好手头上有九轴陀螺仪的例程代码。最后用FreeRTOS 硬件 I2C 读取数据。 这里提到了阻塞式 HAL 函数(

    2024年02月20日
    浏览(19)
  • STM32 SHT40驱动源码(使用硬件I2C)

    目录 简介: SHT40.c: SHT40.h 测试结果:         SHT40是瑞士Sensirion公司推出的第四代温湿度传感器,内部集成加热器用于去除表面微小液滴。集成I2C接口,典型的相对湿度精度1.8%RH,典型温度精度0.2℃,运行在0-100%RH和-40-125℃的环境中。 主控:STM32H7B0VBT6 平台:STM32CubeIDE SHT4

    2024年03月19日
    浏览(36)
  • 【STM32学习】——STM32-I2C外设&硬件读写MPU6050&软硬件读写波形对比

    目录 前言 一、I2C外设 二、硬件I2C操作流程 1.主机发送时序 3.其他时序

    2024年02月10日
    浏览(13)
  • STM32 硬件IIC 控制OLED I2C卡死问题

    #更新通知:2023-09-06 STM32L151 固件库 使用I2C 太难了,又宕机了,建议不要在固件库版本上尝试硬件IIC 了,一般人真用不了,直接使用软件模拟的,或者不要使用固件库了,用HAL 库吧,据说HAL 库没这么多问题,不死心的我还是死心了,等有空再研究吧 3.1 I2C模式,我这里选的

    2024年02月09日
    浏览(19)
  • S32K3系列 --- 硬件I2C Mcal配置

    网上看到很多I2C的教程,基本都是模拟I2C,现在S32K3的芯片支持硬件I2C,我想着就配一个硬件的出来吧,这边记录一下,供大家学习。 这里主要教大家如何去配置,去使用。 原理的话可以参考这篇文章: 一文搞懂I2C通信总线_i2c通信的详细讲解-CSDN博客 I2C时序 这里我们用I2C与

    2024年01月18日
    浏览(17)
  • STM32配合cubeMX硬件I2C驱动0.96寸OLED

    目录 一、简单介绍 1.1   OLED 1.2   I2C协议 二、实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三、驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐标函数 3.4 显示字符函数 3.5 显示字符串函数 3.6 显示图片函数 附录 驱动代码文件 oled.c oled.h f6x8.h 有机发光二极管 (英语:Organic

    2024年02月08日
    浏览(18)
  • 01_STM32软件+硬件I2C读取MPU6050(HAL库)

    目录 1、I2C简介 2、I2C时序单元 2.1 起始条件 2.2 终止条件 2.3 发送一个字节 2.4 接收一个字节 2.5 发送应答 2.6 接收应答 3、I2C完整时序 3.1 指定地址写一个字节 3.2 当前地址读一个字节 3.2 指定地址读一个字节 4、简单软件I2C代码(HAL) 4.1 软件I2C 4.2 软件I2C读MPU6050寄存器 5、ST

    2024年04月17日
    浏览(18)
  • RT-Thread在STM32硬件I2C的踩坑记录

    参考文章: 1.将硬件I2C巧妙地将“嫁接”到RTT原生的模拟I2C驱动框架 2.基于STM32F4平台的硬件I2C驱动实现笔记 3.《rt-thread驱动框架分析》- i2c驱动   最近打算用RT-Thread做一个小demo玩玩,其中需要用I2C通信驱动一个oled屏幕,但是找了一圈也没找到RTT中对硬件I2C的支持方式以及

    2024年02月11日
    浏览(22)
  • STM32学习笔记(十)丨I2C通信(使用I2C实现MPU6050和STM32之间通信)

    ​  本次课程采用单片机型号为STM32F103C8T6。(鉴于笔者实验时身边只有STM32F103ZET6,故本次实验使基于ZET6进行的) ​  课程链接:江协科技 STM32入门教程   往期笔记链接:   STM32学习笔记(一)丨建立工程丨GPIO 通用输入输出   STM32学习笔记(二)丨STM32程序调试

    2024年01月19日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包