STM32硬件I2C

以I2C2为例子

硬件I2C不需要我们手动去翻转电平

首先配置I2C:配置GPIO,配置复用功能I2C,配置复用开漏,使能I2C。

I2C起始条件函数

/* * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: ENABLE or DISABLE.
*/
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);

停止条件函数

/* * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: ENABLE or DISABLE.
*/
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

收一个字节后,是否给从机应答

/* * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  NewState: ENABLE or DISABLE.
*/
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

发数据函数,将数据写入dr寄存器中。

/* @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  Data: Byte to be transmitted.
*/
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);

接收数据函数,读取DR寄存器的数据,作为返回值,(移位寄存器传入数据寄存器)

/*  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @retval The value of the received data.
*/
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

发送7位地址函数,原理和发送数据相同,都是将数据写入到DR寄存器中,不同的是它给出了一位读写位

/*1:接收,0:传送*/
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

状态监控函数:用于确保某些操作是否完成

初始化:

/*初始化*/
    //开启时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    //配置GPIO
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    //配置I2C
    I2C_InitTypeDef I2C_InitStructure;
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//配置位i2c功能
    I2C_InitStructure.I2C_ClockSpeed = 50000;//时钟速率,随便给,不超过阈值即可,数值越大,传输越快,《=400kHz
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//时钟占空比,小于100khz,都是1:1
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//给应答
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//STM32作为从机的地址长度
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;//STM32作为从机的地址
    I2C_Init(I2C2, &I2C_InitStructure);
    //使能I2C
    I2C_Cmd(I2C2, ENABLE);

写一个数据

    void I2C_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
    uint32_t Timeout;
    Timeout = 10000;
    while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS)
    {
        Timeout --;
        if (Timeout == 0)
        {
            break;
        }
    }
}
void I3C_WriteReg(uint8_t RegAddress, uint8_t Data)
{
    I2C_GenerateSTART(I2C2, ENABLE);//生成起始条件
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);/*检测EV5事件发生
    EV5事件:发送起始条件完成,其余的event事件均是同理*/
    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//发送七位地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
    
    I2C_SendData(I2C2, RegAddress);//发送寄存器地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);
    
    I2C_SendData(I2C2, Data);//发送写入寄存器的数据
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
    
    I2C_GenerateSTOP(I2C2, ENABLE);//停止信号
}

读一个数据:

/*先写一个寄存器的地址,在读寄存器的数据 */
uint8_t I2C_ReadReg(uint8_t RegAddress)
{
    uint8_t Data;
    I2C_GenerateSTART(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);

    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);

    I2C_SendData(I2C2, RegAddress);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
    
    I2C_GenerateSTART(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);
    
    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
    
    I2C_AcknowledgeConfig(I2C2, DISABLE);
    I2C_GenerateSTOP(I2C2, ENABLE);
    
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);
    Data = I2C_ReceiveData(I2C2);
    
    I2C_AcknowledgeConfig(I2C2, ENABLE);
    
    return Data;
}

STM32是一系列由意法半导体(STMicroelectronics)开发的32位微控制器产品线。STM32系列提供了丰富的硬件外设,其中包括硬件I2C(Inter-Integrated Circuit)接口。 硬件I2C是一种用于在微控制器和其他外设之间进行通信的串行通信协议。它使用两根线路,即SDA(数据线)和SCL(时钟线),允许多个设备在同一总线上进行通信。 在STM32上使用硬件I2C,您需要首先配置和初始化相关的GPIO引脚,并设置I2C的时钟频率、地址等参数。然后,您可以使用STM32提供的I2C库函数来发送和接收数据。 以下是一个示例代码,用于在STM32上使用硬件I2C发送数据: ```c #include "stm32f4xx.h" void I2C_Init(void) { // 配置相关GPIO引脚为I2C功能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; 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_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置I2C时钟和地址 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_InitTypeDef I2C_InitStructure; 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; I2C_Init(I2C1, &I2C_InitStructure); // 使能I2C I2C_Cmd(I2C1, ENABLE); } void I2C_SendData(uint8_t data) { // 等待I2C准备就绪 while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // 设置要发送的数据 I2C_SendData(I2C1, data); // 等待数据发送完成 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } int main(void) { // 初始化I2C I2C_Init(); // 发送数据 uint8_t data = 0xAA; I2C_SendData(data); while (1) { // 保持程序运行 } } ``` 这只是一个简单的示例代码,具体的实现方式可能会因为所使用的STM32型号和开发工具不同而有所差异。在实际开发中,您可能还需要处理其他I2C事件、配置中断等。建议您查阅相关的STM32参考手册和开发文档,以获取更详细的信息和示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值