stm32之IIC通讯(详细图解附代码)

这篇具有很好参考价值的文章主要介绍了stm32之IIC通讯(详细图解附代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

I2C硬件实现协议:

硬件I2C:

引脚选择:PB6 --SCL ;PB7 --SDA

I2C 初始化结构体:

I2C配置代码:

I2C作为主设备发送数据:

 I2C发送(写)数据代码:

I2C软件模拟协议:

I2C软件通信:

1、空闲状态:

2、开始信号:

3、停止信号:

4、应答信号:

5、数据的有效性:

各个信号产生的时间间隔:

 起始信号:

停止信号:

应答信号ACK:

等待应答:

I2C写字节:


I2C硬件实现协议:

由STM32的IIC片上外设专门负责实现IIC通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理IIC协议的方式减轻了CPU的工作,且使软件设计更加简单。     STM32的IIC外设可用作通讯的主机及从机,支持100Kbit/s和400Kbits/s的速率,支持7位、10位设备地址,支持DMA数据传输,并具有数据校验功能。

硬件I2C:

引脚选择:PB6 --SCL ;PB7 --SDA

stm32 iic,stm32,单片机,物联网

I2C 初始化结构体:

stm32 iic,stm32,单片机,物联网

I2C配置代码:

void I2C_init(void)
{

    I2C_InitTypeDef   I2C_InitStructure;
    GPIO_InitTypeDef   GPIO_InitStructure;
	
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,  ENABLE);
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );
	
	//PB6 --SCL ;PB7 --SDA
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;    //复用开漏
	GPIO_InitStructure.GPIO_Pin   =  GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Ack  =  I2C_Ack_Enable; //应答使能
	I2C_InitStructure.I2C_AcknowledgedAddress =  I2C_AcknowledgedAddress_7bit; //地址长 
    度,选择7位(可为7或10)
	I2C_InitStructure.I2C_ClockSpeed = 400000 ; 
	//时钟占空比,可选low/high=2:0或16:9,这里我们选择2:0
	I2C_InitStructure.I2C_DutyCycle  = I2C_DutyCycle_2 ;  
	I2C_InitStructure.I2C_Mode =  I2C_Mode_I2C;
	I2C_InitStructure.I2C_OwnAddress1 = 0X30 ;  //自身IIC设备地址
	I2C_Init(I2C1,&I2C_InitStructure );
    I2C_Cmd(I2C1,ENABLE);
}

注意:I2C_OwnAddress1是STM32设备本身的地址,一般STM32作为主设备,可以不用关心这个地址设置,随意设置个数就行,但是如果STM32作为从设备使用时,必须进行配置。
I2C_Send7bitAddress(I2Cx, address, direction)这个address指的是外设器件从设备地址,比如挂载EEPROM时,通常是0xA0.这个地址不能和 I2C_OwnAddress1混淆。

I2C作为主设备发送数据:

主发送器通讯过程,即作为 I2C 通讯的主机端时,向外发送数据时的过程。

stm32 iic,stm32,单片机,物联网

主发送器发送流程及事件说明如下:
(1) 控制产生起始信号 (S),当发生起始信号后,它产生事件“EV5”,并会对 SR1 寄存器的“SB”
位置 1,表示起始信号已经发送;
(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”及“EV8”,这时
SR1 寄存器的“ADDR”位及“TXE”位被置 1,ADDR 为 1 表示地址已经发送,TXE 为 1 表示
数据寄存器为空;
(3) 以上步骤正常执行并对 ADDR 位清零后,我们往 I2C 的“数据寄存器 DR”写入要发送的数
据,这时 TXE 位会被重置 0,表示数据寄存器非空,I2C 外设通过 SDA 信号线一位位把数据发送
出去后,又会产生“EV8”事件,即 TXE 位被置 1,重复这个过程,就可以发送多个字节数据了;
(4) 当我们发送数据完成后,控制 I2C 设备产生一个停止信号 (P),这个时候会产生 EV8_2 事件,
SR1 的 TXE 位及 BTF 位都被置 1,表示通讯结束。

 I2C发送(写)数据代码:

代码逻辑就是根据I2C主设备发送数据的时序来编写的。

void I2C_WriteByte(uint8_t addr,uint8_t data)
{
     //FlagStatus bitstatus = RESET
    while (I2C_GetFlagStatus(I2C1,  I2C_FLAG_BUSY));  //检查I2C总线是否繁忙	
    I2C_GenerateSTART(I2C1,  ENABLE); //打开I2C1 
    //ErrorStatus status = ERROR,   ERROR是个枚举类型,值为0        
    while( !I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_MODE_SELECT)); //EV5,主模式	
	 I2C_Send7bitAddress(I2C1,OLED_ADDRESS, I2C_Direction_Transmitter); //配置STM32的IIC设备自己的地址,每个连接到IIC总线上的设备都有一个自己的地址,作为主机也不例外。
	 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));   //EV6
	 I2C_SendData(I2C1,  addr);   //寄存器地址
     while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_BYTE_TRANSMITTING));  //EV8,等待发送数据 
     完成
	I2C_SendData(I2C1,  data);   //发送数据
	 while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_BYTE_TRANSMITTING)); //判断是否发送完成, 
     EV8,等待发送数据完成
    I2C_GenerateSTOP( I2C1,  ENABLE); //关闭I2C总线
}

I2C软件模拟协议:使用CPU直接控制通讯引脚的电平,产生出符合通讯协议标准的逻辑。

I2C软件通信:

1、空闲状态:

IIC总线的SDA和SCL两条信号线同时处于高电平时,规定位总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

I2C时序图:

2、开始信号:当SCL为高电平期间,SDA有高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。

3、停止信号:当SCL为高电平期间,SDA由低到高的跳变;停止信号也是一种高电平跳变时序信号,而不是一个电平信号( 起始信号和停止信号一般由主机产生)

4、应答信号:   发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

stm32 iic,stm32,单片机,物联网

5、数据的有效性:   IIC总线进行数据传输时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。SDA数据线在SCL的每个时钟周期传输一位数据。(数据在SCL的上升沿到来之前就需准备好。并在下降沿到来之前必须稳定  )

stm32 iic,stm32,单片机,物联网

各个信号产生的时间间隔:

stm32 iic,stm32,单片机,物联网

 起始信号:

void I2C_Start(void)
{
    I2C_SDA_H;//把数据线拉高
    I2C_SCL_H;//把时钟线拉高
    delay_us(5);//延时5微秒,要求大于4.7微秒
    I2C_SDA_L; //拉低,产生下降沿
    delay_us(5);//这个过程大于4.7微秒
}

停止信号:

void I2C_Stop(void)
{
   I2C_SCL_L;
   I2C_SDA_L;
   I2C_SCL_H;
   delay_us(5);
   I2C_SDA_H;
   delay_us(5);
}

应答信号ACK:低电平0表示应答,1表示非应答

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 函数名:SendAck
 * 参数:
 * 返回:
 * 描述:应答
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define IIC_DELAY_TIME	 10
static void SendAck(u8 _type){
    IIC_SCL_LOW();
    DelayUs(IIC_DELAY_TIME); 	    
    if(_type == 0)
        IIC_SDA_LOW();
    else
        IIC_SDA_HIGH();
    DelayUs(IIC_DELAY_TIME);
    IIC_SCL_HIGH();
    DelayUs(IIC_DELAY_TIME);
    IIC_SCL_LOW();
    DelayUs(IIC_DELAY_TIME); 
}

等待应答:

static unsigned char IIC_Wait_Ack(void)
{
	unsigned char ack;
	OLED_SCLK_CLr();	//时钟线置低
	 delay_us(1);
	OLED_SDIN_Set();	//信号线置高
	 delay_us(1);
	OLED_SCLK_Set();	//时钟线置高
	delay_us(1);

	if(OLED_READ_SDIN())	//读取SDA的电平
		ack = IIC_NO_ACK;	//如果为1,则从机没有应答
	else
		ack = IIC_ACK;		//如果为0,则从机应答

	OLED_SCLK_CLr();//时钟线置低
	 delay_us(1);
	return ack;	//返回读取到的应答信息
}

I2C写字节:

static void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;  //定义变量
	for(i=0;i<8;i++) //for循环8次
	{
		OLED_SCLK_CLr();	//时钟线置低,为传输数据做准备
		 delay_us(1);

		if(IIC_Byte & 0x80)	//读取最高位
		  	OLED_SDIN_Set();//最高位为1
		else
			OLED_SDIN_CLr();	//最高位为0

		IIC_Byte <<= 1;  //数据左移1位
		 delay_us(1);
		OLED_SCLK_Set(); //时钟线置高,产生上升沿,把数据发送出去
		 delay_us(1);
	}
	OLED_SCLK_CLr();	//时钟线置低
		 delay_us(1);

	while(IIC_Wait_Ack());	//从机应答
}

有需要可以加QQ:2404513972文章来源地址https://www.toymoban.com/news/detail-792904.html

到了这里,关于stm32之IIC通讯(详细图解附代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机双机IIC通信

    通过IIC协议进行两个51单片机之间的信息传输,主机按下按键发送不同的指令,控制从机对应LED灯进行点亮。 1、发送部分 (1)开始信号 起始条件:SCL高电平期间,SDA从高电平切换到低电平 (2)结束信号 终止条件:SCL高电平期间,SDA从低电平切换到高电平 (3)发送一个字

    2024年02月13日
    浏览(42)
  • 51单片机(IIC协议OLED屏)

    1.1、概述:IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双 工同步通信方式 1.2、特点:简单性和有效性。 由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和

    2024年01月22日
    浏览(38)
  • 【51单片机】EEPROM-IIC实验(按键控制数码管)

    目录   🎁I2C总线 ​编辑 🎁代码 🏳️‍🌈main.c 🏳️‍🌈i2.c 🎆代码分析   I2C总线是Philips公司在八十年代初推出的一种串行、半双工的总线,主要用于近距离、低速的芯片之间的通信;I2C总线有两根双向的信号线,一根 数据线SDA 用于收发数据,一根 时钟线SCL 用于通信

    2024年02月11日
    浏览(41)
  • 基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)

    当前文章介绍基于51单片机和SHT30传感器设计的环境温度与湿度检测设备。设备采用IIC模拟时序通信协议,能够实时监测环境的温度和湿度,并将数据通过LCD显示屏显示出来;可以广泛应用于室内环境监测、气象观测、农业温室监测等领域。 在本项目中,使用了51单片机作为主

    2024年02月13日
    浏览(38)
  • stm32 IIC通信

    IIC总线是一种通用数据总线,有两根通信线(SCL(串行时钟总线),SDA(串行数据总线))。 特点:同步,半双工,带数据应答,支持总线挂载多设备 所有IIC设备的SCL连在一起,SDA连在一起。 SCL与SDA均配置成开漏输出模式 SCL与SDA各添加一个上拉电阻,阻值一般为4.7千欧左右。

    2024年02月15日
    浏览(47)
  • STM32之IIC

    IIC全称Inter-Integrated Circuit (集成电路总线),由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。 IIC属于半双工同步通信方式。 IIC串行总线有两根信号线,一根是双向的 数据线SDA ,另一根是 时钟线SCL。 两条线都接上拉电阻,以确保 总线空闲时刻为

    2024年02月13日
    浏览(28)
  • STM32--IIC

    IIC:Inter Integrated Circuit,集成电路总线,是一种同步串行半双工通信总线。 IIC总线结构图 由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空闲状态为高电平 总线支持多设备连接,允许多主机存在,每个设备都有一个唯一的地址 IIC协议时序 起始信号(S):当SCL为高

    2024年02月09日
    浏览(25)
  • stm32硬件实现IIC

    2024年01月17日
    浏览(41)
  • STM32硬件IIC使用

    虽然STM32的硬件IIC据说有设计缺陷,但是经过我的实践,至少STM32F103的硬件IIC是没问题的。这里给出STM32的硬件IIC的使用以及编程思路。 在这里给出STM32F103的硬件IIC引脚,方便查阅使用 STM32的硬件IIC我认为是非常具有借鉴意义的,它使用了事件组的一个流程。以stm32为主设备,

    2024年03月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包