STM32 I2C通讯+MPU6050通讯演示

一.I2C通讯

1.I2C通讯简介

I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线;

两根通信线:SCL(Serial Clock)、SDA(Serial Data);

同步,半双工,带数据应答;

支持总线挂载多设备(一主多从、多主多从)

2.硬件电路

所有I2C设备的SCL连在一起,SDA连在一起;

设备的SCL和SDA均要配置成开漏输出模式;

SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

3.I2C时序基本单元

I2C总线处于空闲状态时,默认情况下SCL和SDA上拉电阻拉高高电平,SCL和SDA先均处于高电平状态;

起始条件:SCL高电平期间,SDA从高电平切换到低电平;

终止条件:SCL高电平期间,SDA从低电平切换到高电平

起始条件和终止条件都是由主机产生的;

发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节;

主机如果发送0,就拉低SDA到低电平;

主机如果发送1,就有上拉电阻拉高到高电平;

SCL高电平期间(如下图B7位置),从机读取SDA;

SCL低电平期间,主机把数据放在SDA线上;数据放完之后,主机再次放手SCL拉高电电平,从机读取SDA线上的数据,一次运行八次,读到一个字节的数据;

接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

接收与发送的区别:

发送:SCL低电平,主机将数据放在SDA线上,SCL高电平,从机读取SDA线上的数据;

接收:SCL低电平,从机将数据放在SDA线上,SCL高电平,主机读取SDA线上的数据;

发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

4.I2C外设简介

STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担

支持多主机模型

支持7/10位地址模式

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

支持DMA

STM32F103C8T6 硬件I2C资源:I2C1I2C2

5.I2C框图

二.I2C程序标准库(此程序以MPU6065模块演示)

1.软件I2C程序

MyI2C.c

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

void MyI2C_W_SCL(uint8_t BitValue)     //写SCL引脚反转     直接调用这个函数,传参给1或0就可释放或拉低SCL端口
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue); //bitactiion是一个枚举类型的变量,表示这个位是高电平还是低电平,  将uint8_t 强转BitValue(0或1)
	Delay_us(10);      //防止一些高性能单片机端口反转速度快,丛机速度跟不上  ,引脚延时10us
}

void MyI2C_W_SDA(uint8_t BitValue)     //写SDA引脚反转     直接调用这个函数,传参给1或0就可释放或拉低SDA端口
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);
	Delay_us(10);      //防止一些高性能单片机端口反转速度快,丛机速度跟不上  ,引脚延时10us
}

uint8_t MyI2C_R_SDA(void)     //读SDA引脚
{
	uint8_t BitValue;
	BitValue = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);    //读PB11引脚的状态
	Delay_us(10);
	return BitValue;    //将读到的参数返回 SDA线的电平
}


void MyI2C_Init(void)     //软件I2C不需要库函数,
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;     //软件I2C需要将端口配置开漏输出模式,开漏输出模式仍可以输入,输入时,端口输出1,再读取数据寄存器
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11);  //将PA12和PA13置位高电平,SCL和SDA高电平空闲状态
	
}

//配置I2C 6个时序基本单元
//1.起始条件
void MyI2C_Start(void)   //起始条件函数:先拉低SDA,再拉低SCL,就能触发起始条件
{
	MyI2C_W_SDA(1);      //先释放SDA引脚,输出1  ,高电平空闲
	MyI2C_W_SCL(1);      //释放SCL引脚,输出1  ,高电平空闲
	MyI2C_W_SDA(0);      //先拉低SDA引脚,输出0  ,低电平有效 
	MyI2C_W_SCL(0);      //再拉低SCL引脚,输出0  ,低电平有效 
}

//2.终止条件
void MyI2C_Stop(void)
{
	MyI2C_W_SDA(0);       //先拉低SDA引脚,输出0  ,低电平有效 
	MyI2C_W_SCL(1);       //然后释放SCL引脚,输出1  ,高电平空闲 
	MyI2C_W_SDA(1);       //再释放SDA引脚,输出1  ,高电平空闲
}

//3.发送一个字节
void MyI2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for(i = 0; i < 8; i++)      //循环八次, (0x80 &g
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胸有猛虎丶细嗅蔷薇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值