STM32设置为I2C从机模式

这篇具有很好参考价值的文章主要介绍了STM32设置为I2C从机模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32设置为I2C从机模式

前言

STM32的I2C作为主机的情况相信很多同学都用过,网上也有很多教程,但是作为从设备使用的例子应该不多,本文通过硬件和软件的层面,介绍如何把STM32设置为一个I2C从机。

1 硬件连接

测试芯片:STM32F103ZET6
测试方法:用一个USB转I2C的工具接到STM32的I2C引脚上,通过上位机工具进行读写操作。如果没有这个工具,也可以用另外一个stm32或者其他设备测试通讯,同时也可以借助示波器或者逻辑分析仪来辅助调试。
硬件连接:
STM32这边使用硬件I2C1(PB6、PB7),并外接上拉电阻。
STM32设置为I2C从机模式
STM32设置为I2C从机模式

2 软件编程

根据STM32数据参考手册,I2C作为从设备时发送和接收的流程如下:
STM32设置为I2C从机模式
STM32设置为I2C从机模式

测试例程:定义一个256字节的buffer用来存放I2C从机的数据,默认赋初值0-255,然后通过中断的方式实现I2C数据读写。
示例代码如下:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_i2c.h"
#include "misc.h"

#define I2CSLAVE_ADDR           0x40 << 1  // address is 0x40

#define I2C1_CLOCK_FRQ          100000     // I2C-Frq in Hz (100 kHz)
#define I2C1_RAM_SIZE           256        // RAM Size in Byte

#define I2C1_MODE_WAITING       0          // Waiting for commands
#define I2C1_MODE_SLAVE_ADR_WR  1          // Received slave address (writing)
#define I2C1_MODE_ADR_BYTE      2          // Received ADR byte
#define I2C1_MODE_DATA_BYTE_WR  3          // Data byte (writing)
#define I2C1_MODE_SLAVE_ADR_RD  4          // Received slave address (to read)
#define I2C1_MODE_DATA_BYTE_RD  5          // Data byte (to read)

uint8_t i2c1_mode = I2C1_MODE_WAITING;
uint8_t i2c1_ram_adr = 0;
uint8_t i2c1_ram[I2C1_RAM_SIZE];

uint8_t Get_I2C1_Ram(uint8_t adr) 
{
    return i2c1_ram[adr];
}

void Set_I2C1_Ram(uint8_t adr, uint8_t val) 
{
    i2c1_ram[adr] = val;
    return;
}

void I2C1_Ram_Init(void) 
{
    uint16_t i;
    for (i = 0; i < 256; i++)
    {
        Set_I2C1_Ram(i, i);
    }
}

void I2C1_Slave_Init(void) 
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    I2C_InitTypeDef  I2C_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* Configure I2C_EE pins: SCL and SDA */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Configure the I2C event priority */
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Configure I2C error interrupt to have the higher priority */
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
    NVIC_Init(&NVIC_InitStructure);

    /* I2C configuration */
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = I2CSLAVE_ADDR;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = I2C1_CLOCK_FRQ;

    /* I2C Peripheral Enable */
    I2C_Cmd(I2C1, ENABLE);

    /* Apply I2C configuration after enabling it */
    I2C_Init(I2C1, &I2C_InitStructure);

    I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); //Part of the STM32 I2C driver
    I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
    I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); //Part of the STM32 I2C driver

    I2C1_Ram_Init();
}

void I2C1_ClearFlag(void) 
{
    /* ADDR Flag clear */
    while((I2C1->SR1 & I2C_SR1_ADDR) == I2C_SR1_ADDR) 
    {
        I2C1->SR1;
        I2C1->SR2;
    }

    /* STOPF Flag clear */
    while((I2C1->SR1&I2C_SR1_STOPF) == I2C_SR1_STOPF) 
    {
        I2C1->SR1;
        I2C1->CR1 |= 0x1;
    }
}

void I2C1_EV_IRQHandler(void) 
{
    uint8_t wert;
    uint32_t event;

    /* Reading last event */
    event = I2C_GetLastEvent(I2C1);

    /* Event handle */
    if(event == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) 
    {
        // Master has sent the slave address to send data to the slave
        i2c1_mode = I2C1_MODE_SLAVE_ADR_WR;
    }
    else if(event == I2C_EVENT_SLAVE_BYTE_RECEIVED) 
    {
        // Master has sent a byte to the slave
        wert = I2C_ReceiveData(I2C1);
        // Check address
        if(i2c1_mode == I2C1_MODE_SLAVE_ADR_WR) 
        {
            i2c1_mode = I2C1_MODE_ADR_BYTE;
            // Set current ram address
            i2c1_ram_adr = wert;
        }
        else 
        {
            i2c1_mode = I2C1_MODE_DATA_BYTE_WR;
            // Store data in RAM
            Set_I2C1_Ram(i2c1_ram_adr, wert);
            // Next ram adress
            i2c1_ram_adr++;
        }
    }
    else if(event == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) 
    {
        // Master has sent the slave address to read data from the slave
        i2c1_mode = I2C1_MODE_SLAVE_ADR_RD;
        // Read data from RAM
        wert = Get_I2C1_Ram(i2c1_ram_adr);
        // Send data to the master
        I2C_SendData(I2C1, wert);
        // Next ram adress
        i2c1_ram_adr++;
    }
    else if(event == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) 
    {
        // Master wants to read another byte of data from the slave
        i2c1_mode = I2C1_MODE_DATA_BYTE_RD;
        // Read data from RAM
        wert = Get_I2C1_Ram(i2c1_ram_adr);
        // Send data to the master
        I2C_SendData(I2C1, wert);
        // Next ram adress
        i2c1_ram_adr++;
    }
    else if(event == I2C_EVENT_SLAVE_STOP_DETECTED) 
    {
        // Master has STOP sent
        I2C1_ClearFlag();
        i2c1_mode = I2C1_MODE_WAITING;
    }
}

void I2C1_ER_IRQHandler(void) 
{
    if (I2C_GetITStatus(I2C1, I2C_IT_AF)) 
    {
        I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
    }
}

3 运行测试

3.1 I2C连续写入

通过上位机工具写入:
STM32设置为I2C从机模式

通过逻辑分析仪抓取波形:
STM32设置为I2C从机模式

3.2 I2C连续读取

通过上位机工具连续读取256字节:
STM32设置为I2C从机模式

通过逻辑分析仪抓取波形:
STM32设置为I2C从机模式

STM32设置为I2C从机模式

3.3 I2C单次读写测试

通过上位机工具读取原值,再写入新值,最后再读取新值:
STM32设置为I2C从机模式

通过逻辑分析仪抓取波形:
STM32设置为I2C从机模式

4 总结

通过上位机工具的测试以及逻辑分析仪的解析,STM32的硬件I2C从机通信正常且稳定,读写速度测试了100k和400k,没有发现问题,至此测试完成。
好了,关于STM32如何设置从机模式就介绍到这里,如果你们有什么问题,欢迎评论区留言。

需要完整源码工程的同学可以自行下载:源码下载地址
另外还有一篇HAL库版本的博客:STM32设置为I2C从机模式(HAL库版本)

如果这篇文章能够帮到你,就…懂的。
STM32设置为I2C从机模式文章来源地址https://www.toymoban.com/news/detail-502236.html

到了这里,关于STM32设置为I2C从机模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【STM32 CubeMX】I2C层次结构、I2C协议

    在STM32 CubeMX环境中,I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,广泛应用于连接各种外设和传感器。理解I2C的层次结构、协议和硬件结构对于STM32微控制器的开发至关重要。通过STM32 CubeMX提供的图形化配置工具,我们能够更轻松地理解和配置I2C通信,同时深入了解

    2024年02月22日
    浏览(66)
  • STM32 I2C

    目录 I2C通信  软件I2C读写MPU6050 I2C通信外设 硬件I2C读写MPU6050 I2C通信 R/W:0写1读 十轴:3轴加速度,3轴角速度,3轴磁场强度和一个气压强度  软件I2C读写MPU6050 MyI2C.c MPU6050.c MPU6050_Reg.h(寄存器) main.c I2C通信外设 GPIO口需要配置为复用开漏输出模式。复用:就是GPIO的状态是交由

    2024年02月19日
    浏览(40)
  • STM32---I2C

    目录                                       一.I2C协议 1.什么是I2C协议?  2.物理层特性                                     二.协议层 1.I2C读写过程 2.I2C外设 3.I2C外设通讯过程              三.I2C库函数                       四.EEPROM 写操作: 读操作:      

    2024年02月16日
    浏览(34)
  • STM32学习笔记(十)丨I2C通信(使用I2C实现MPU6050和STM32之间通信)

    ​  本次课程采用单片机型号为STM32F103C8T6。(鉴于笔者实验时身边只有STM32F103ZET6,故本次实验使基于ZET6进行的) ​  课程链接:江协科技 STM32入门教程   往期笔记链接:   STM32学习笔记(一)丨建立工程丨GPIO 通用输入输出   STM32学习笔记(二)丨STM32程序调试

    2024年01月19日
    浏览(50)
  • STM32——I2C通信

            I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线,它是两线式串行总线,它具有两根通信线: SCL(Serial Clock)、SDA(Serial Data) ,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。I2C是同步半双

    2024年01月25日
    浏览(42)
  • STM32 I2C详解

    I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线 两根通信线: SCL(Serial Clock)串行时钟线,使用同步的时序,降低对硬件的依赖,同时同步的时序稳定性也比异步的时序更高。 SDA(Serial Data)串行数据线,半双工,一根线兼具发送和接收,最大化利用资源。 同步,半

    2024年02月05日
    浏览(44)
  • STM32-I2C通讯

    I2C( Inter-Integrated Circuit )是一种通用的总线协议。它是由Philips(飞利浦)公司,现NXP(恩智浦)半导体开发的一种 简单的双向两线制 总线协议标准。 I2C有两根双向的信号线,一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步。 支持同步,半双工,带数据应答,

    2024年03月14日
    浏览(37)
  • stm32中的i2c协议

    协议通讯图 I2C上一个总线能挂载多个设备共用信号线,可以连接多个从机 只用了两个总线,一条双向串行数据线(SDA),一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。 每个连接到总线的设备都有独立的地址,主机可以通过该地址进行访问 I2C空闲

    2024年01月22日
    浏览(46)
  • 【【STM32----I2C通信协议】】

    我们会发现I2C有两根通信线: SCL和SDA 同步 半双工 带数据应答 支持总线挂载多设备(一主多从,多主多从) 硬件电路 所有I2C设备的SCL连在一起,SDA连在一起 设备的SCL和SDA均要配置成开漏输出模式 SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右 左边的CPU就是主机,他的权

    2024年02月12日
    浏览(42)
  • 10:STM32------I2C通信

    目录 一:I2C通信协议 1:I2C简历 2:硬件电路 3:I2C时序基本单元 A : 开/ 终条件 2:发送一个字节 3:接收一个字节 4:应答机制  4:I2C时序  1:指定地址写 2:当前地址读 3: 指定地址读 二:MPU6050 1:简历 2:参数 3:硬件电路 4:框图 5:寄存器地址 三:案例 A:软件I2C读写 MPU6050 1:连接图 2:代码 B:硬

    2024年02月20日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包