STM32硬件I2C双机通信

STM32硬件I2C双机通信

I2C的接口模式可以选择4种

  • 主发送器模式
  • 主接收器模式
  • 从发送器模式
  • 从接收器模式

  在本次实验中需要用到两块STM32单片机,其中一块的I2C1做主机,另一块的I2C2做从机,分别进行I2C1写I2C2实验、I2C1读I2C2实验,两次实验I2C1均为主机。

1、主发送、从接收模式

  在I2C1写I2C2实验中,先检测总线占用情况,确定在总线空闲的情况下,由主机发送起始信号然后发送从机地址,选择写命令,从机接收到地址与自身匹配后回应ACK信号,主机接收到ACK信号后开始发送数据,从机收到数据后回应ACK,当主机发送到最后一个字节并且收到ACK后,主机发出停止信号结束本次通信并且释放总线,从机收到停止信号后也退出与主机的通信。

  注意:在从机I2C初始化的时候要设置从机地址,在主机发送从机地址的时候,一般最后一位是读写位,0写1读,假设从机地址为0x30,则发送0x30|0x00为写,0x30|0x01为读。
在这里插入图片描述

/**
  * @brief  主机I2C1写数据
  * @param  None
  * @retval None
  */
static void I2C1_Write_Byte(uint32_t ReadAddr)
{
	uint32_t i;
	uint32_t tbuf[10] = {0X01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};
	
	while(I2C1->SR2&((u16)0x1<<1));		//等待总线空闲
	I2C1->CR1|=(u16)0x1<<8;				//置位START,产生起始条件
	
	/*  SB = 1: EV5 */
	while(!(I2C1->SR1&(u16)0x1<<0));	//等待SB置位,当发送出起始条件时该位被置1	
	I2C1->SR1;							//读SR1
	I2C1->DR = ReadAddr;				//发送写指令,写DR寄存器清除SB事件
	
	/*  ADDR = 1: EV6 */
	while(!(I2C1->SR1&(u16)0x1<<1));	//等待从设备应答
	
	/*  TxE = 1: EV8-1 */
	while(!(I2C1->SR1&(u16)0x1<<7));	//等待TxE为1,数据寄存器空
	for(i=0;i<SIZE;i++)
	{
		/*  TxE = 1: EV8 */
		I2C1->DR = tbuf[i];
		
		/*  TxE = 1, BTF = 1: EV8-2 */
		while(!(I2C1->SR1&(u16)0x1<<2));//BTF为1,字节发送结束
	}	
	I2C1->CR1|=(u16)0x1<<9;				//产生停止条件
	while(!(I2C1->CR1&(u16)0x1<<9));
}

在这里插入图片描述

/**
  * @brief  从机I2C2 读数据
  * @param  None
  * @retval None
  */
static void I2C2_Read_Byte(void)
{
	uint32_t i;
	uint32_t rbuf[SIZE];
	
    while(!(I2C2->SR2&(u16)0x1<<1));	//1:BUSY忙
    while(I2C2->SR2&(u16)0x1);			//0:从模式
    /*  ADDR = 1: EV1 */
    while(!(I2C2->SR1&(u16)0x1<<1));	//接收到地址
    I2C2->SR1;
    I2C2->SR2;							//清除ADDR
    for(i=0; i<10; i++)
    {
        /*  RxNE = 1: EV2 */
        while(!(I2C2->SR1&(u16)0x1<<6));//接收到数据
        rbuf[i] = I2C2->DR;
    }
    /*  STOPF = 1: EV4 */
    while(!(I2C2->SR1&(u16)0x1<<4));	//等待STOPF为1
}
2、主接收、从发送模式

  在I2C1读I2C2实验中,先检测总线占用情况,确定在总线空闲的情况下,由主机发送起始信号然后发送从机地址,选择读命令,从机接收到地址与自身匹配后回应ACK信号,接着由从机开始发送数据,主机接收到数据后回应ACK信号,当主机完成所有数据接收后发送一个NACK信号,从机收到NACK后停止发送数据,主机发送完NACK后再发出停止信号,释放总线结束本次通信。
在这里插入图片描述

/**
  * @brief  主机I2C1读数据
  * @param  ReadAddr  :开始读数的地址
  * @retval None
  */
static void I2C1_Read_Byte(uint32_t ReadAddr)
{
	uint32_t i;
	uint32_t rbuf[SIZE];
	
	while(I2C1->SR2&((u16)0x1<<1));		//等待总线空闲
	I2C1->CR1|=(u16)0x1<<8;				//置位START,产生起始条件
	
	/*  SB = 1: EV5 */
	while(!(I2C1->SR1&(u16)0x1<<0));	//等待SB置位,当发送出起始条件时该位被置1	
	I2C1->SR1;							//读SR1
	I2C1->DR = ReadAddr|0x01;			//发送读指令,写DR寄存器清除SB事件
	
	/*  ADDR = 1: EV6 */
	while(!(I2C1->SR1&(u16)0x1<<1));	//等待从设备应答
	I2C1->SR1;
	I2C1->SR2;							//清除ADDR		
	
	for(i=0;i<SIZE;i++)
	{
		/*  RxNE = 1: EV7 */
		while(!(I2C1->SR1&(u16)0x1<<6));//等待RXNE=1,接收到数据	
		rbuf[i] = I2C1->DR;
	}
	
	/*  STOP = 1: EV7-1 */
	I2C1->CR1&=~((u16)0x1<<10);			//ACK=0
	I2C1->CR1|=(u16)0x1<<9;				//产生停止条件
}	

在这里插入图片描述

/**
  * @brief  从机I2C2 写数据
  * @param  None
  * @retval None
  */
static void I2C2_Write_Byte(void)
{
	uint32_t i;
	uint32_t tbuf[10] = {0X01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};
	
    while(!(I2C2->SR2&(u16)0x1<<1));	//1:BUSY忙
    while(I2C2->SR2&(u16)0x1);			//0:从模式
    /*  ADDR = 1: EV1 */
    while(!(I2C2->SR1&(u16)0x1<<1));	//接收到地址
    I2C2->SR1;
    I2C2->SR2;
    /*  TxE = 1: EV3-1 */
    while(!(I2C2->SR1&(u16)0x1<<7));	//1:TXE 数据寄存器空
    for(i=0; i<10; i++)
    {
        /*  TxE = 1: EV3 */
        I2C2->DR = tbuf[i];
        while(!(I2C2->SR2&(u16)0x1<<2));//1:TRA 数据已发送
        while(!(I2C2->SR1&(u16)0x1<<2));//1:BTF 字节发送结束
    }
    /*  AF = 1: EV3-2 */
    while(!(I2C2->SR1&(u16)0x1<<10));	//1:AF 应答失败,发送结束
}
  • 7
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: STM32是一款非常强大的微控制器系列,它在硬件上具有丰富的外设资源,包括SPI(串行外设接口)。SPI是一种常用的通信协议,可以用于多种应用,包括双机通信。 SPI通信可以在STM32的不同引脚之间建立起一个主从关系。主设备(通常是STM32)控制整个通信过程,而从设备则根据主设备的指令进行数据传输。通过配置SPI相关寄存器,可以设置数据传输的速率、数据位数和时钟极性等参数,以满足特定通信需求。 在双机通信中,可以使用两个STM32微控制器作为主设备和从设备,通过SPI接口进行通信。主设备可以发送指令或数据给从设备,从设备则可以将数据发送回主设备。这种通信方式可以实现高速的数据传输和双向通信,可广泛应用于许多应用场景。 在使用SPI进行双机通信时,需要注意以下几点: 1. 确保主从设备的SPI接口设置一致,包括传输速率、时钟极性和相位等参数。 2. 设计合适的通信协议,包括数据帧结构和数据解析规则,以确保数据的可靠传输。 3. 考虑通信的实时性和可靠性,可以使用中断或DMA方式进行数据传输,以减少处理器的负载。 综上所述,STM32可以使用SPI进行双机通信,通过配置合适的SPI参数和设计合理的通信协议,可以实现高效可靠的数据传输。 ### 回答2: STM32是一款广泛应用于嵌入式系统开发的微控制器系列,它内置了丰富的外设接口,包括SPI(串行外设接口)。SPI通信是一种基于主从模式的串行通信协议,用于在多个设备间进行双向通信。 因此,STM32完全支持使用SPI接口进行双机通信。通过配置STM32的SPI外设作为主设备和从设备,可以实现多个STM32之间的通信。主设备负责控制通信的时序和传输数据,从设备负责接收和发送数据。 在SPI通信中,主设备通过发送时钟信号(SCLK)、主设备输出数据(MOSI)和接收从设备数据(MISO)的方式与从设备进行通信。通过在SPI配置中设置一些参数(如时钟频率、数据位数等),可以实现数据的高效传输和同步。 当然,为了确保双机通信的稳定性和可靠性,还需要在硬件电路、软件驱动等方面进行适当的设计和配置。例如,需要确保主设备和从设备的时钟信号、数据线的连接正确可靠;还需要编写相应的软件驱动程序,实现SPI通信的初始化、数据发送和接收等功能。 总之,STM32可以完全使用SPI进行双机通信,通过合适的硬件和软件配置,可以实现多个STM32之间的高效数据传输和通信。 ### 回答3: STM32可以使用SPI进行双机通信。 SPI(Serial Peripheral Interface)是一种同步串行通信协议,适用于短距离高速数据传输。STM32微控制器内部集成了多个SPI接口,可以用于与其他硬件设备进行通信。 要实现双机通信,至少需要两个STM32微控制器。其中一个控制器设为主设备(master),另一个设为从设备(slave)。主设备负责调度通信的时序并发起通信操作,从设备则按照主设备的时序进行响应。通过SPI接口连接两个设备,可以实现双机之间的通信。 在SPI通信中,主设备和从设备之间可以交换数据,主设备将待发送的数据放入发送缓冲区,然后通过时钟信号将数据发送给从设备。从设备收到数据后,将其放入接收缓冲区,供主设备读取。通信完成后,两个设备可以交换角色,实现双向通信。 通过SPI接口进行双机通信的好处是,通信速率高、传输可靠、占用的引脚少等。但也需要注意SPI的时序设置、数据格式等方面的配置,确保两个设备之间的通信正常进行。 总之,STM32可以使用SPI接口进行双机通信,适用于短距离高速数据传输的应用场景。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值