【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

这篇具有很好参考价值的文章主要介绍了【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
I2C总线是一个真正的多主机总线,如果两个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据破坏,每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。数据传输和地址设定由软件设定,非常灵活。总线上的器件增加和删除不影响其他器件正常工作。
I2C有3种总线速率——标速(100kHz)、快速(400kHz)和高速(3.4MHz),但GD32F103C8T6只支持标速和快速两种速率

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

通信流程

开始信号和停止信号

I2C的通信由一个起始信号开始,传输结束后由一个停止信号结束。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

开始信号为SDA线由高电平拉低,接着SCL线开始输出同步时钟信号;传输结束后SCL线停止同步时钟输出,接着SDA线也由低拉高,发出结束信号。

数据有效性

I2C是一个同步传输协议,因此数据的更新需根据同步时钟线来决定。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

I2C规定,时钟信号的高电平期间SDA线上的数据必须稳定。只有在时钟信号SCL变低的时候数据线SDA的电平才能跳变

仲裁

上面说过,I2C是一个多主机总线协议,因此当多个主机同时申请总线的控制权时,则需要对其进行仲裁,以决定哪一个主机获得总线的控制权。
I2C的仲裁比较特别,跟之前介绍的DMA的仲裁不同,DMA的仲裁是通过检查优先级的方式来进行的,而I2C的仲裁是通过比较实际输出电平的方式进行的。
在每一位数据的发送期间,当SCL为高时,每个主机都检查SDA电平是否和自己发送的相同。理论上讲,如果两个主机所传输的内容完全相同,那么他们能够成功传输而不出现错误。如果一个主机发送高电平但检测到SDA电平为低,则认为自己仲裁失败并关闭自己的SDA输出驱动,而另一个主机则继续完成自己的传输。

从设备地址与确认应答

I2C总线上可以连接多个从设备,每个从设备都共享一条SDA和SCL线。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

所以当主机想要给总线上的某一个从设备通信就需要有一个机制来寻找对应的从设备,这个机制就是从设备地址。
每个从设备都有一个自己的地址可以是7位的,也可以是10位的,地址的值的范围具体由厂商来决定。
主机在向总线发送开始信号并成功获得总线控制权后,将会向总线发送对应从机的地址,这个地址所有的从机都会接收,然后从机将收到的地址与自己的地址比较,若地址一致则该从机将会向总线发送ACK信号,也就是确认应答,表示可以开始通信;而其他的从机将会忽略总线上的信号,直到下一个开始信号来临。
主机与从机每传输一组数据,从机接收后都必须发送ACK信号,表示接收成功。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

软件控制流程

I2C具有4种运行状态——主机发送方、主机接收方、从机发送方、从机接收方。对于这4种不同的运行状态都有不同的软件控制流程。
这一部分所有的流程图都是基于10位地址I2C通信的,因此如果各位使用的是7位地址的I2C通信,那么把地址头发送的那一部分忽略即可。

主机发送方

简要流程:

  1. 使能I2C外设时钟,配置时钟相关寄存器来确保正确的I2C时序;
  2. 软件将START位置1,在I2C总线上产生一个START起始位,SBSEND置1,进入主机模式;
  3. 写一个7位地址位或带有地址头的10位地址位到数据寄存器,SBSEND置0,若是10位地址,那么先写入高地址ADD10SEND置1,发送后再写入低地址ADD10SEND置0;
  4. I2C开始发送地址或者地址头到总线上,ADDSEND置1,软件将ADDSEND置0;
  5. I2C进入数据发送状态,软件写第一个字节数据到数据寄存器,此时,写入数据寄存器的字节被立即移入内部移位寄存器,TBE置1;
  6. 移位寄存器非空,I2C开始发送数据到总线;
  7. 在第一个字节的发送过程中,软件可以写第二个字节到数据寄存器,TBE置0;
  8. 任何时候TBE被置1,软件都可以向数据寄存器写入一个字节,只要还有数据待发送。
  9. 在倒数第二个字节发送过程中,软件写入最后一个字节数据到数据寄存器来清除TBE标志
    位;
  10. 最后一个字节发送结束后,I2C主机将BTC位置1,因为移位寄存器和数据寄存器此时都为空;
  11. 软件将STOP位置1来发送一个STOP结束位,此后TBE和BTC状态位都将被置0。

说明:
SBSEND全称Start Bit Send,“起始位发送”标志位。
ADDSEND全称Address Send,“地址发送”标志位,同样ADD10SEND就是“10位地址发送”标志位
TBE全称Transfer Buffer Empty,“发送缓冲区空”标志位。
BTC全称Byte Transfer Complete,“字节传输完成”标志位。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

主机接收方

方案1(需软件对中断快速响应)

简要流程:

  1. 使能I2C外设时钟,配置时钟相关寄存器来确保正确的I2C时序,等待START起始位;
  2. 软件将START位置1,从而在I2C在总线上产生一个START起始位,SBSEND置1,进入主机模式;
  3. 写一个7位地址位或带有地址头的10位地址位到数据寄存器,SBSEND置0,若是10位地址,那么先写入高地址,发送后ADD10SEND置1,再写入低地址ADD10SEND置0;
  4. 7位或10位的地址位发送出去之后,ADDSEND置1,软件应该将ADDSEND置0,如果地址是10位格式,软件应该再次将START位置1来重新产生一个START(Sr);在START产生后,SBSEND位置1,软件将SBSEND置0,然后地址头被发到I2C总线,ADDSEND再次被置1,软件将ADDSEND置0;
  5. 接收到第一个字节,RBNE位置1,软件可以从数据寄存器读取第一个字节,RBNE位置0。
  6. 此后任何时候RBNE被置1,软件就可以从数据寄存器读取一个字节;
  7. 接收完倒数第二个字节(N-1)数据之后,软件应该立即将ACKEN位置0,并将STOP位置1,
    这一过程需要在最后一个字节接收完毕之前完成,以确保NACK发送给最后一个字节;
  8. 最后一个字节接收完毕后,RBNE位置1,软件读取最后一个字节,由于ACKEN已经在前一步骤中被清0,I2C不再为最后一个字节发送ACK,并在最后一个字节发送完毕后产生一个STOP结束位。

说明:
RBNE全称Read Buffer Not Empty,“接收缓冲区非空”标志位。
ACKEN全称Acknowledge Enable,“应答帧使能”标志位。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

方案2

简要流程:

  1. 使能I2C外设时钟,配置时钟相关寄存器来确保正确的I2C时序,等待START起始位;
  2. 软件将START位置1,从而在I2C在总线上产生一个START起始位,SBSEND置1,进入主机模式;
  3. 写一个7位地址位或带有地址头的10位地址位到数据寄存器,SBSEND置0,若是10位地址,那么先写入高地址,发送后ADD10SEND置1,再写入低地址ADD10SEND置0;
  4. 7位或10位的地址位发送出去之后,ADDSEND置1,软件应该将ADDSEND置0,如果地址是10位格式,软件应该再次将START位置1来重新产生一个START(Sr);在START产生后,SBSEND位置1,软件将SBSEND置0,然后地址头被发到I2C总线,ADDSEND再次被置1,软件将ADDSEND置0;
  5. 第一个字节被接收,RBNE位置1,软件从数据寄存器读读取第一个字节,RBNE位被置0;
  6. 此后任何时候,一旦RBNE位被置1,软件就可以从数据寄存器读取一个字节的数据,直到主机接收了N-3个字节;
  7. 软件从数据寄存器读出倒数第三个(N-2)字节,同时也将BTC位置0;
  8. 此后第N-1个字节从移位寄存器被移到数据寄存器,总线得到释放然后开始接收最后一个字节;
  9. 最后一个字节接收完毕后,硬件再次把BTC位和RBNE置1,软件将STOP位置1,主机发出一个STOP结束位;
  10. 软件读取第N-1个字节,BTC置0,此后最后一个字节从移位寄存器被移动到数据寄存器;
  11. 软件读取最后一个字节,RBNE置0;

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

从机发送方

简要流程:

  1. 使能I2C外设时钟,配置时钟相关寄存器来确保正确的I2C时序,等待START起始位和地址;
  2. 接收一个START起始位及随后的地址,ADDSEND位置1,软件将ADDSEND置0;如果地址是10位格式,从机在检测到START(Sr)和紧接着的地址头之后会继续将ADDSEND位置1,软件第二次将ADDSEND位置0;
  3. I2C进入数据发送状态,TBE位置1,软件写入第一个字节数据到数据寄存器,写入数据寄存器的字节被立即移入内部移位寄存器;
  4. 移位寄存器非空,I2C开始发送数据到总线上;
  5. 第一个字节的发送期间,软件写第二个字节到数据寄存器,此时TBE位被置0;
  6. 在此之后,任何时候TBE被置1,只要依然有数据待被发送,软件都可以写入一个字节到数据寄存器;
  7. 倒数第二个字节发送期间,软件写最后一个数据到数据寄存器来将TBE置0;
  8. 倒数第二个字节发送完成后,TBE置1;
  9. 检测到STOP结束位,TBE置0。

根据I2C协议,I2C主机将不会对接收到的最后一个字节发送应答,所以在最后一个字节发
送结束后,I2C从机的AERR会置1以通知软件发送结束,软件写0到AERR位可以清除此
位。
AERR全称Acknowledge Error,“应答错误”标志位。

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

从机接收方

简要流程:

  1. 使能I2C外设时钟,配置时钟相关寄存器来确保正确的I2C时序,等待START起始位以及地址;
  2. 在接收到START起始条件和匹配的7位或10地址之后,ADDSEND位置1,软件将ADDSEND位置0;
  3. 一旦接收到第一个字节,RBNE位被硬件置1,软件可以读取数据寄存器的第一个字节,此时RBNE位也被清0;
  4. 任何时候RBNE被置1,软件可以从数据寄存器读取一个字节;
  5. 接收到最后一个字节后,RBNE被置1,软件可以读取最后的字节;
  6. 当I2C检测到I2C总线上一个STOP结束位,STPDET位被置1,软件将STPDET位置0。

STPDET全称Stop Detect,“停止位检测”标志位。
【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

例程

GD32F103C8T6上有2个I2C设备,正好用来测试,它们的对应管脚如下表所示。

设备 SCL SDA
I2C0 PB6 PB7
I2C1 PB10 PB11

在对管脚初始化时,I2C的两个管脚都必须设置为复用开漏模式
因为GD32F10C8T6的I2C外设没有内部上拉电阻,所以在接线的时候要在SDA和SCL分别加外部上拉电阻,如下图。
VCC为电源电压,一般为3.3V或5V;上拉电阻的阻值推荐为4.7kΩ或10kΩ

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

主机发送从机接收

现象:主机每秒向从机发送一串数据
i2c.c文件

#include "i2c.h"

void I2C_MasterInit(void)
{
    /* 初始化GPIO */
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
    
    /* 初始化I2C */
    rcu_periph_clock_enable(RCU_I2C0);
    /* 初始化时钟,频率10kHz,占空比50% */
    i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
    /* 设置地址,7位 */
    i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x82);
    /* 使能I2C0 */
    i2c_enable(I2C0);
    /* 使能应答 */
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}

void I2C_SlaveInit(void)
{
    /* 初始化GPIO */
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);
    
    /* 初始化I2C */
    rcu_periph_clock_enable(RCU_I2C1);
    /* 初始化时钟,频率10kHz,占空比50% */
    i2c_clock_config(I2C1, 100000, I2C_DTCY_2);
    /* 设置地址,7位 */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x72);
    /* 使能I2C1 */
    i2c_enable(I2C1);
    /* 使能应答 */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);

}

void I2C_MasterSendSlaveReceive(void)
{
    uint8_t i2c_transmitter[16];
    uint8_t i2c_receiver[16];
    
    memset(i2c_transmitter, 0x00, sizeof(i2c_transmitter));
    memset(i2c_receiver, 0x00, sizeof(i2c_receiver));
    
    printf("Master transmit: ");
    for(uint8_t i = 0; i < 16; i++)
    {
        i2c_transmitter[i] = i + 0x80;
        printf("%x ", i2c_transmitter[i]);
    }
    printf("\n");
    
    /* 等待总线空闲 */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));

    /* 主机发送起始位 */
    i2c_start_on_bus(I2C0);

    /* 主机等待SBSEND置1 */
    while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));

    /* 主机发送从机地址 */
    i2c_master_addressing(I2C0, 0x72, I2C_TRANSMITTER);

    /* 等待ADDSEND置1 */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    /* ADDSEND置0 */
    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    
    for(uint8_t i = 0; i < 16; i++)
    {
        /* 发送一个字节 */
        i2c_data_transmit(I2C0, i2c_transmitter[i]);
        /* 等待主机发送完成 */
        while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
        /* 等待从机接收完成 */
        while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE));
        /* 从机读取数据 */
        i2c_receiver[i] = i2c_data_receive(I2C1);
    }
    /* 发送停止位 */
    i2c_stop_on_bus(I2C0);
    /* 等待STPDET位置1 */
    while(I2C_CTL0(I2C0)&0x0200);
    while(!i2c_flag_get(I2C1, I2C_FLAG_STPDET));
    /* STPSET置0 */
    i2c_enable(I2C0);
    
    printf("Slave receive: ");
    for(uint8_t i = 0; i < 16; i++)
    {
        printf("%x ", i2c_receiver[i]);
    }
    printf("\n");
}

main.c文件

#include "gd32f10x.h"
#include "main.h"
#include "systick.h"
#include "usart.h"
#include "i2c.h"
#include <stdio.h>
#include <string.h>

int main(void)
{	
    systick_config();
    USART_Config();
    I2C_MasterInit();
    I2C_SlaveInit();
        
    while(1)
    {
        I2C_MasterSendSlaveReceive();
        delay_ms(1000);
    }
}

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

主机接收从机发送

现象:主机每秒接收从机发送的一串数据
i2c.c文件

#include "i2c.h"

void I2C_MasterInit(void)
{
    /* 初始化GPIO */
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
    
    /* 初始化I2C */
    rcu_periph_clock_enable(RCU_I2C0);
    /* 初始化时钟,频率10kHz,占空比50% */
    i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
    /* 设置地址,7位 */
    i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x82);
    /* 使能I2C0 */
    i2c_enable(I2C0);
    /* 使能应答 */
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}

void I2C_SlaveInit(void)
{
    /* 初始化GPIO */
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);
    
    /* 初始化I2C */
    rcu_periph_clock_enable(RCU_I2C1);
    /* 初始化时钟,频率10kHz,占空比50% */
    i2c_clock_config(I2C1, 100000, I2C_DTCY_2);
    /* 设置地址,7位 */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x72);
    /* 使能I2C1 */
    i2c_enable(I2C1);
    /* 使能应答 */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);

}

void I2C_MasterReceiveSlaveSend(void)
{
    uint8_t i2c_transmitter[16];
    uint8_t i2c_receiver[16];
    
    memset(i2c_transmitter, 0x00, sizeof(i2c_transmitter));
    memset(i2c_receiver, 0x00, sizeof(i2c_receiver));
    
    printf("Slave transmit: ");
    for(uint8_t i = 0; i < 16; i++)
    {
        i2c_transmitter[i] = i + 0x80;
        printf("%x ", i2c_transmitter[i]);
    }
    printf("\n");

    /* 等待总线空闲 */
    while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
    /* 主机发送起始信号 */
    i2c_start_on_bus(I2C0);
    /* 主机等待SBSEND置1 */
    while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
    /* 主机发送从机地址 */
    i2c_master_addressing(I2C0, 0x72, I2C_RECEIVER);
    /* 主机等待ADDSEND置1 */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
    /* 主机ADDSEND置0 */
    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
    /* 从机等待ADDSEND置1 */
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    /* 从机ADDSEND置0 */
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    
    /* 从机发送n-1个字节 */
    for(uint8_t i = 0; i < 15; i++)
    {
        /* 发送一个字节 */
        i2c_data_transmit(I2C1, i2c_transmitter[i]);
        /* 从机等待发送完成 */
        while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
        /* 主机等待接收完成 */
        while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
        /* 获取一个字节 */
        i2c_receiver[i] = i2c_data_receive(I2C0);
    }
    /* 关闭ACK */
    i2c_ack_config(I2C0, I2C_ACK_DISABLE);
    /* 发送最后一个字节 */
    i2c_data_transmit(I2C1, i2c_transmitter[15]);
    /* 从机等待发送完成 */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
    /* 主机等待应答错误位置1 */
    while(!i2c_flag_get(I2C1, I2C_FLAG_AERR));
    /* 主机发送停止信号 */
    i2c_stop_on_bus(I2C0);
    while(I2C_CTL0(I2C0)&0x0200);
    /* 获取最后一个字节 */
    i2c_receiver[15] = i2c_data_receive(I2C0);
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);
    /* 从机AERR置0 */
    i2c_flag_clear(I2C1, I2C_FLAG_AERR);

    printf("Master receive: ");
    for(uint8_t i = 0; i < 16; i++)
    {
        printf("%x ", i2c_receiver[i]);
    }
    printf("\n");

}

main.c文件

#include "gd32f10x.h"
#include "main.h"
#include "systick.h"
#include "usart.h"
#include "i2c.h"
#include <stdio.h>
#include <string.h>

int main(void)
{	
    systick_config();
    USART_Config();
    I2C_MasterInit();
    I2C_SlaveInit();
        
    while(1)
    {
        I2C_MasterReceiveSlaveSend();
        delay_ms(1000);
    }
}

【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程文章来源地址https://www.toymoban.com/news/detail-434255.html

到了这里,关于【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【51单片机】AT24C20数据帧(I2C总线)

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Love Story】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 小吉先向大家道个歉,因为最近在期末突击,所以文章久久没有更新,也请大家多多见谅😥 目录   🎁I2C总线 🏳️‍🌈

    2024年02月08日
    浏览(60)
  • 51单片机——模拟I2C总线与AT24C02通信

    目录 一、写在前面 二、功能描述 三、主要模块介绍 3.1 I2C总线介绍 3.2 I2C总线协议 3.2.1数据有效规定 3.2.2起始信号和停止信号  3.2.3 发送应答和接收应答 3.2.4 主机发送一个字节和接收一个字节 3.3 AT24C02介绍 3.3 字节写和随机读 四、测试文件test.c 五、现象描述 AT24C02芯片有I

    2024年02月14日
    浏览(46)
  • STM32硬件I2C通信外设

    本文主要介绍stm32自带的I2C通信外设,对比与软件模拟I2C,硬件I2C可以自动生成时序,时序的操作更加及时规范,可以实现更加高性能的IIC通信。 本文内容与I2C软件通信有诸多类似之处,I2C软件通信可见:https://blog.csdn.net/qq_53922901/article/details/136662006?spm=1001.2014.3001.5501 在8位指

    2024年04月08日
    浏览(90)
  • 【STM32】| 02——常用外设 | I2C

    系列文章目录 【STM32】| 01——常用外设 | USART 【STM32】| 02——常用外设 | I2C 失败了也挺可爱,成功了就超帅。 本文详细介绍 I2C协议及 MCU I2C配置使用 I2C是一种常用的串行通信总线,由串行数据线SDA 和串线时钟线SCL组成。I2C是一种多主机控制总线,由飞利浦公司为了让主板

    2024年01月19日
    浏览(35)
  • STM32--MPU6050与I2C外设

    在51单片机专栏中,用过I2C通信来进行实现AT24C02的数据存储; 里面介绍的是 利用程序的编程来实现I2C的时序 ,进而实现AT24C02与单片机之间的关系连接; 本章将介绍使用I2C的硬件外设来实现I2C通信,和介绍MPU6050,利用I2C通信实现STM32对MPU6050的控制. I2C通信软件实现程序链接

    2024年02月11日
    浏览(46)
  • 【STM32】STM32学习笔记-I2C通信外设(34)

    I2C(Inter-Integrated Circuit)总线 是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 串行的 8 位双向数据传输位速率在标准模式下可

    2024年01月17日
    浏览(53)
  • 【单片机】UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB、SD卡、1-WIRE、Ethernet等常见通信方式

    在单片机开发中,UART、I2C、RS485等普遍在用,这里做一个简单的介绍 UART口指的是一种物理接口形式(硬件)。 UART是异步(指不使用时钟同步,依靠帧长进行判断),全双工(收发可以同时进行)串口总线。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收

    2024年02月11日
    浏览(33)
  • 【GD32】从0开始学GD32单片机(10)—— TIMER基本定时器详解+1毫秒延时例程

    在GD32中定时器是非常重要的外设,它可以帮我们精准的控制程序的调度,就如之前讲过的SysTick就是一个定时器,我们可以通过设置这个定时器的寄存器实现延时函数。 GD32的定时器可大致分为3种—— 基本定时器、通用定时器、高级定时器 。 它们之间的区别如下图所示: 这

    2024年01月17日
    浏览(46)
  • 【GD32】从零开始学GD32单片机高级篇——外部存储器控制器EXMC详解+SDRAM读写例程

    外部存储器控制器EXMC,用来访问各种片外存储器,通过配置寄存器,EXMC可以把AMBA 协议转换为专用的片外存储器通信协议,包括 SRAM,ROM,NOR Flash,NAND Flash,PC Card和SDRAM 。 EXMC的工作原理其实就是把外部储存器的地址映射到内部的特定地址上,用户想访问外部的存储器,我们

    2024年02月10日
    浏览(88)
  • 【STM32学习】——STM32-I2C外设&硬件读写MPU6050&软硬件读写波形对比

    目录 前言 一、I2C外设 二、硬件I2C操作流程 1.主机发送时序 3.其他时序

    2024年02月10日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包