STM32——I2C硬件通信(标准库)_stm32 i2c标准库的使用

(6)支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)支持DMA

(7)同步,半双工

二丶读写过程

(1)发送过程

(2)接收数据

三丶库函数

(1)void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);

初始化I2C

(2)void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);

使能I2C

(3)void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
         void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);

配合DMA使用

(4)void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
         void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

起始条件和终止条件

(5)void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

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

(6)void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);

设置主机地址(STM32当从机使用时配置)

(7)void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
         uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

发送数据和接收数据

(8)void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

发送从机地址(当然I2C_SendData也可以发送)

(9)I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);

检查应答位

四丶代码部分及解析(使用了MPU6050观察实验现象)

(一)I2C及MPU6050初始化部分

#include "stm32f10x.h"                  // Device header
#include "MPU6050_Reg.h"

#define MPU6050_ADDRESS		0xD0



void MPU6050_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);    //开启GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //开启I2C时钟
	
	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);                  //初始化GPIO
	
	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;      //时钟占空比
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;             //主机是否设置应答
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  //主机地址位数  7位或10位
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;               //主机地址(当STM32位从机时)
	I2C_Init(I2C2, &I2C_InitStructure);
	
	I2C_Cmd(I2C2, ENABLE);
	
	MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);
	MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);
	MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);
	MPU6050_WriteReg(MPU6050_CONFIG, 0x06);
	MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);
	MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}



void MPU6050_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 MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
	I2C_GenerateSTART(I2C2, ENABLE);
	MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);        //检测EV5
	
	I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);   //发送从机地址
	MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);     //检测EV6(发送模式)
	
	I2C_SendData(I2C2, RegAddress);     //发送从机寄存器地址
	MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);             //检测EV8
	
	I2C_SendData(I2C2, Data);                                                //发送数据
	MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);              //检测EV8_2
	
	I2C_GenerateSTOP(I2C2, ENABLE);                                          //停止发送                     
}

uint8_t MPU6050_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);      //检测EV6(接收模式)
	
	I2C_AcknowledgeConfig(I2C2, DISABLE);                                  //主机给从机应答位A
	I2C_GenerateSTOP(I2C2, ENABLE);                                        //接收数据时需要提前发送终止位
	
	MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);               //检测EV7
	Data = I2C_ReceiveData(I2C2);
	
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	
	return Data;
}

uint8_t MPU6050_GetID(void)
{
	return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}

void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
	uint8_t DataH, DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
	*AccX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
	*AccY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
	*AccZ = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
	*GyroX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
	*GyroY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
	*GyroZ = (DataH << 8) | DataL;
}

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/e272e074e57b1cb5c2acebf8b14bdc1e.png)

![img](https://img-blog.csdnimg.cn/img_convert/e53ae89dd810c00458bcde1bb0289ea1.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/ffcb5cb0d1407ba748b76ee6a84bfe7a.png)

 **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

![img](https://img-blog.csdnimg.cn/img_convert/797b2153ab4974f9bbcb12e0bd259233.png)

![img](https://img-blog.csdnimg.cn/img_convert/1168dd71e478de72c5a83b06004af30e.png)

 

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**

<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**

<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

**[更多资料点击此处获qu!!](https://bbs.csdn.net/topics/618376385)**
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于STM32 HAL硬件I2C通信,我可以给你一些基本的信息和代码示例。 首先需要在CubeMX中配置I2C外设,并且生成HAL初始化代码。以下是一个示例代码,可以用于初始化I2C1外设: ``` /* I2C1 init function */ static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00707CBB; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } ``` 然后,就可以使用HAL提供的函数进行I2C通信了。以下是一个示例代码,可以用于向I2C设备发送数据: ``` uint8_t i2c_tx_buf[2]; i2c_tx_buf[0] = 0x00; // 选择寄存器地址 i2c_tx_buf[1] = 0x12; // 写入的数据 HAL_I2C_Master_Transmit(&hi2c1, I2C_DEVICE_ADDRESS, i2c_tx_buf, 2, HAL_MAX_DELAY); ``` 其中,`I2C_DEVICE_ADDRESS`是I2C设备的地址,可以在设备的数据手册中查找。 接下来是一个示例代码,可以用于从I2C设备读取数据: ``` uint8_t i2c_rx_buf[2]; i2c_rx_buf[0] = 0x00; // 选择寄存器地址 HAL_I2C_Master_Transmit(&hi2c1, I2C_DEVICE_ADDRESS, i2c_rx_buf, 1, HAL_MAX_DELAY); HAL_I2C_Master_Receive(&hi2c1, I2C_DEVICE_ADDRESS, i2c_rx_buf, 2, HAL_MAX_DELAY); ``` 其中,先使用`HAL_I2C_Master_Transmit`函数向I2C设备发送寄存器地址,然后使用`HAL_I2C_Master_Receive`函数从I2C设备接收数据。 以上是一个简单的硬件I2C通信的示例,希望可以帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值