STM32F407系列有3個(gè)硬件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通??梢赃_(dá)到幾百kHz甚至更高的速度,軟件I2C幾十kHz
I2C1.C文件
#include "I2C1.h"
// I2C1初始化函數(shù)
void I2C1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 使能GPIOB和I2C1時(shí)鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// 配置GPIOB的引腳為復(fù)用模式
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);
// 配置引腳復(fù)用映射
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; // 設(shè)置自身設(shè)備地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000; // 設(shè)置通信速度,這里為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初始化函數(shù)
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初始化函數(shù)
void I2C2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 打開(kāi)I2C2和GPIOB的時(shí)鐘
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引腳復(fù)用功能
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);
// I2C2配置
I2C_InitStructure.I2C_ClockSpeed = 100000; // 設(shè)置時(shí)鐘速度為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發(fā)送數(shù)據(jù)函數(shù)
void I2C2_WriteData(uint8_t address, uint8_t reg, uint8_t data)
{
// 等待I2C2處于空閑狀態(tài)
while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))
;
// 發(fā)送START信號(hào)
I2C_GenerateSTART(I2C2, ENABLE);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和寫(xiě)指令
I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
// 發(fā)送寄存器地址
I2C_SendData(I2C2, reg);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 發(fā)送數(shù)據(jù)
I2C_SendData(I2C2, data);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 發(fā)送STOP信號(hào)
I2C_GenerateSTOP(I2C2, ENABLE);
}
// I2C2接收數(shù)據(jù)函數(shù)
uint8_t I2C2_ReadData(uint8_t address, uint8_t reg)
{
uint8_t data;
// 等待I2C2處于空閑狀態(tài)
while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))
;
// 發(fā)送START信號(hào)
I2C_GenerateSTART(I2C2, ENABLE);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和寫(xiě)指令
I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
// 發(fā)送寄存器地址
I2C_SendData(I2C2, reg);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 重新發(fā)送START信號(hào),切換到接收模式
I2C_GenerateSTART(I2C2, ENABLE);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和讀指令
I2C_Send7bitAddress(I2C2, address, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
;
// 開(kāi)啟ACK
I2C_AcknowledgeConfig(I2C2, ENABLE);
// 接收數(shù)據(jù)
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
;
data = I2C_ReceiveData(I2C2);
// 發(fā)送STOP信號(hào)
I2C_GenerateSTOP(I2C2, ENABLE);
return data;
}
I2C2.h文件
#ifndef __I2C2_H
#define __I2C2_H
#include "sys.h"
// I2C2初始化函數(shù)
void I2C2_Init(void);
// I2C2發(fā)送數(shù)據(jù)函數(shù)
// 參數(shù):
// address: 目標(biāo)設(shè)備地址
// reg: 寄存器地址
// data: 要發(fā)送的數(shù)據(jù)
void I2C2_WriteData(uint8_t address, uint8_t reg, uint8_t data);
// I2C2接收數(shù)據(jù)函數(shù)
// 參數(shù):
// address: 目標(biāo)設(shè)備地址
// reg: 寄存器地址
// 返回值:
// 讀取到的數(shù)據(jù)
uint8_t I2C2_ReadData(uint8_t address, uint8_t reg);
#endif
I2C3.C文件文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-759586.html
#include "I2C3.h"
// I2C3初始化函數(shù)
void I2C3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 打開(kāi)I2C3和GPIOA的時(shí)鐘
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引腳復(fù)用功能
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_I2C3);
// I2C3配置
I2C_InitStructure.I2C_ClockSpeed = 100000; // 設(shè)置時(shí)鐘速度為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發(fā)送數(shù)據(jù)函數(shù)
void I2C3_WriteData(uint8_t address, uint8_t reg, uint8_t data)
{
// 等待I2C3處于空閑狀態(tài)
while (I2C_GetFlagStatus(I2C3, I2C_FLAG_BUSY))
;
// 發(fā)送START信號(hào)
I2C_GenerateSTART(I2C3, ENABLE);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和寫(xiě)指令
I2C_Send7bitAddress(I2C3, address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
// 發(fā)送寄存器地址
I2C_SendData(I2C3, reg);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 發(fā)送數(shù)據(jù)
I2C_SendData(I2C3, data);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 發(fā)送STOP信號(hào)
I2C_GenerateSTOP(I2C3, ENABLE);
}
// I2C3接收數(shù)據(jù)函數(shù)
uint8_t I2C3_ReadData(uint8_t address, uint8_t reg)
{
uint8_t data;
// 等待I2C3處于空閑狀態(tài)
while (I2C_GetFlagStatus(I2C3, I2C_FLAG_BUSY))
;
// 發(fā)送START信號(hào)
I2C_GenerateSTART(I2C3, ENABLE);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和寫(xiě)指令
I2C_Send7bitAddress(I2C3, address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
// 發(fā)送寄存器地址
I2C_SendData(I2C3, reg);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
// 重新發(fā)送START信號(hào),切換到接收模式
I2C_GenerateSTART(I2C3, ENABLE);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_MODE_SELECT))
;
// 發(fā)送目標(biāo)設(shè)備地址和讀指令
I2C_Send7bitAddress(I2C3, address, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
;
// 開(kāi)啟ACK
I2C_AcknowledgeConfig(I2C3, ENABLE);
// 接收數(shù)據(jù)
while (!I2C_CheckEvent(I2C3, I2C_EVENT_MASTER_BYTE_RECEIVED))
;
data = I2C_ReceiveData(I2C3);
// 發(fā)送STOP信號(hào)
I2C_GenerateSTOP(I2C3, ENABLE);
return data;
}
I2C3.h文件文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-759586.html
#ifndef __I2C3_H
#define __I2C3_H
#include "sys.h"
// I2C3初始化函數(shù)
void I2C3_Init(void);
// I2C3發(fā)送數(shù)據(jù)函數(shù)
// 參數(shù):
// address: 目標(biāo)設(shè)備地址
// reg: 寄存器地址
// data: 要發(fā)送的數(shù)據(jù)
void I2C3_WriteData(uint8_t address, uint8_t reg, uint8_t data);
// I2C3接收數(shù)據(jù)函數(shù)
// 參數(shù):
// address: 目標(biāo)設(shè)備地址
// reg: 寄存器地址
// 返回值:
// 讀取到的數(shù)據(jù)
uint8_t I2C3_ReadData(uint8_t address, uint8_t reg);
#endif
到了這里,關(guān)于STM32F407系列硬件I2C筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!