Arduino for PKE8720DF-C13-F10——I2C数据收发演示

PKE8720DF-C13-F10开发板I2C功能简介

PKE8720DF-C13-F10 中 I2C 的设计旨在低功耗或电池供电产品中的传感器应用。提供了一个 I2C port,用于获取或控制外部传感器数据。

I2C总线支持两种速度模式:标准模式下 100 k/s,快速模式下 400 k/s;支持 Master / Slave I2C 操作;支持7位和10位寻址;深度为16的发送和接收 buffer ;支持 Tx / Rx DMA;提供多主机能力,包括总线仲裁方案。

下图是 Master / Slave 和 Transmitter / Receiver 的关系图。

 Figure 1. Master/Slave and Transmitter/Receiver relationships

PKE8720DF-C13-F10开发板详细信息、引脚对应以及Arduino IDE配置方法可以参考之前的文章:使用PKE8720DF-C13-F10实现Arduino example——Button_deer_vickey的博客-CSDN博客 

Arduino IDE——I2C数据收发

1)所需材料

  • 2 × PKE8720DF-C13-F10开发板
  • 2 x USB转type-C数据线
  • 2 × 杜邦线

2)电路连接

  • Master board 的 SCL (PB25) 连接到 Slave board 的 SCL (PB25)
  • Master board 的 SDA (PB26) 连接到 Slave board 的 SDA (PB26)

3)代码解析

代码通过macro I2C_MASTER_DEVICE 区分 master 和 slave 的角色,从LOG_UART可以看到输出。完整的源代码文件 I2C_DUPLEX.ino 可以在下面的链接下载:https://download.csdn.net/download/deer_vickey/88148518?spm=1001.2014.3001.5503

include files

I2C功能的接口定义在下面的头文件中,相关函数可以在ambd_arduino源代码中查询,源代码可以从github下载:GitHub - ambiot/ambd_arduino: AmebaD Arduino third-party package SDK

    #include "PinNames.h"
    #include "basic_types.h"
    #include "diag.h"

    #include "i2c_api.h"
    #include "pinmap.h"

definitions and global variables

  • I2C_MASTER_DEVICE 用来区分 master 和 slave,进行 define 的话表示 master,没有 define 则表示 slave
  • I2C_BUS_CLK 是 I2C 总线的时钟,标准模式下它的值是100k/s
  • i2c_data_master_tx[] 存放 master 发送的数据
  • i2c_data_slave_tx[] 存放 slave 发送的数据
  • i2c_data_master_rx[] 和 i2c_data_master_rx[] 分别存放 master / slave 接收的数据
    #define I2C_MASTER_DEVICE

    //I2C1_SEL S0
    #define I2C_MTR_SDA    PA_26
    #define I2C_MTR_SCL    PA_25

    //I2C0_SEL S0
    #define I2C_SLV_SDA    PA_26
    #define I2C_SLV_SCL    PA_25

    #define I2C_SLAVE_ADDR0    0x23
    #define I2C_BUS_CLK        100000  //hz

    #define I2C_DATA_LENGTH         10
    uint8_t	i2c_data_master_tx[I2C_DATA_LENGTH];
    uint8_t	i2c_data_slave_rx[I2C_DATA_LENGTH];
    uint8_t	i2c_data_slave_tx[I2C_DATA_LENGTH];
    uint8_t	i2c_data_master_rx[I2C_DATA_LENGTH];

setup()

  • 首先对Master、Slave需要传送的数据分别进行赋值操作,调用 trans_data_init() 函数:
  • i2c_data_master_tx[] :01 02 03 04 05 06 07 08 09 0a
  • i2c_data_slave_tx[] :0a 09 08 07 06 05 04 03 02 01
  • i2c_data_master_rx[] 和 i2c_data_master_rx[] 都初始化为0
    void trans_data_init(void)
    {
        int index = 0;
        for(index = 0; index < I2C_DATA_LENGTH; index++)
        {
            i2c_data_master_tx[index] = index + 1;
        }
        for(index = 0; index < I2C_DATA_LENGTH; index++)
        {
            i2c_data_slave_tx[index] = I2C_DATA_LENGTH - index;
        }
        _memset(&i2c_data_slave_rx[0], 0x00, I2C_DATA_LENGTH);
	    _memset(&i2c_data_master_rx[0], 0x00, I2C_DATA_LENGTH);
    }
  • Master:初始化成功之后调用 i2c_write() 把 i2c_data_master_tx[] buffer中的数据发送给 I2C Slave;再通过 i2c_read() 函数把 Slave 发送的数据读取到 i2c_data_master_rx[] buffer中。比较 Master 读到的数据和 Slave 发送的数据是否相同。
    int index = 0;
	i2c_init(&i2c_master, I2C_MTR_SDA , I2C_MTR_SCL);  
	i2c_frequency(&i2c_master, I2C_BUS_CLK);

    // Master write - Slave read
	printf("\r\nMaster write(i2c_data_master_tx)>>>\n");
    for(index = 0; index < I2C_DATA_LENGTH; index += 2)
    {
        printf(" %02x \t %02x\n",i2c_data_master_tx[index],i2c_data_master_tx[index+1]);
    }
    i2c_write(&i2c_master, I2C_SLAVE_ADDR0, (const char *)&i2c_data_master_tx[0], 
    I2C_DATA_LENGTH, 1);

    // Master read - Slave write
	printf("Master read(i2c_data_master_rx)>>>\n");
    i2c_read(&i2c_master, I2C_SLAVE_ADDR0, (char *)&i2c_data_master_rx[0], I2C_DATA_LENGTH, 1);

    i2c_master_rx_check();
  • Slave:初始化成功之后调用 i2c_slave_read() 函数把 Master 发送的数据读取到 i2c_data_slave_rx[] buffer中;再通过 i2c_slave_write() 把 i2c_data_slave_tx[] buffer中的数据发送给 I2C Master。比较 Slave 读到的数据和 Master 发送的数据是否相同。
    int index = 0;
	i2c_init(&i2c_slave, I2C_SLV_SDA, I2C_SLV_SCL);
	i2c_frequency(&i2c_slave, I2C_BUS_CLK);
	i2c_slave_address(&i2c_slave, 0, I2C_SLAVE_ADDR0, 0xFF);
	i2c_slave_mode(&i2c_slave, 1);

    // Master write - Slave read
	printf("\r\nSlave read(i2c_data_slave_rx)>>>\n");
	i2c_slave_read(&i2c_slave, (char *)&i2c_data_slave_rx[0], I2C_DATA_LENGTH);

    i2c_slave_rx_check();

	// Master read - Slave write
	printf("Slave write(i2c_data_slave_tx)>>>\n");
    for(index = 0; index < I2C_DATA_LENGTH; index += 2)
    {
        printf(" %02x \t %02x\n",i2c_data_slave_tx[index], i2c_data_slave_tx[index+1]);
    }
    i2c_slave_set_for_rd_req(&i2c_slave, 1);
	i2c_slave_write(&i2c_slave, (const char *)&i2c_data_slave_tx[0], I2C_DATA_LENGTH);

4)烧录image

  • Master:“Tools” --> “Port” 中选择 Master 的 COM 口,打开 I2C_MASTER_DEVICE,点击 “Sketch” --> “Upload” 把 image 烧录到板子中
  • Slave:“Tools” --> “Port” 中选择 Slave 的 COM 口,关闭 I2C_MASTER_DEVICE,点击 “Sketch” --> “Upload” 把 image 烧录到板子中

5)实验结果

使用 TeraTerm 查看 LOG_UART 的 output。打开两个 TeraTerm 窗口,在 Serial 中分别选择 Master 和 Slave 对应的 COM 口;把 “Setup” --> “Serial port” 中的 speed 设置成115200。

先按下 Slave 的 Reset 键,再按下 Master 的 Reset 键,可以看到下图的serial output。左侧的 COM31 是Master,右侧的 COM34 是 Slave。

  • 红色框内显示的是 Master write - Slave read
  • 蓝色框内显示的是 Master read - Slave write

可以看到接收端的 data 和发送端的 data 完全相同,结果符合预期。如果您的实验结果与本文不符,则需要在每条线上都外接一个上拉电阻(典型值为 4.7 kΩ),默认情况下将其保持为高电平。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值