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文件文章来源:https://www.toymoban.com/news/detail-759586.html
#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模板网!