PKE8720DF-C13-F10开发板——I2C数据收发演示

目录

1. I2C概括

2. 硬件说明

2.1 连线说明

2.2 启动和停止条件

3. 软件说明

3.1 ImageTool

3.2 Linux/Windows开发环境

3.3 Tera Term

4. 代码介绍

4.1 Master

4.2 Slave

5. 实验结果


1. I2C概括

有关PKE8720DF-C13-F10开发板的介绍,请参考这一篇文章《快速上手PKE8720DF-C13-F10开发板》。

PKE8720DF-C13-F10中提供了一个I2C端口,用于传输和接收外部传感器的数据。
I2C总线有下面几个属性:

  1. 支持标准模式、快速模式、高速模式、超快速模式四种,但这里PKE8720DF-C13-F10支持前面两种,即标准模式(100kbps)和快速模式(400kbps)。
  2. 支持master和slave两种方式,这里的master也可以有多个,当有多个master时,由总线裁决方案来决定哪个master活动。
  3. 支持7位寻址和10位寻址两种。
  4. 最长为16字节的发送/接收缓存。
  5. 支持TX/RX DMA。

2. 硬件说明

2.1 连线说明

I2C用到了SDA线和SCL线,其中SDA表示串行数据线(serial data line),SCL表示串行时钟线(serial clock data)。在硬件连接时,两条线都要接上上拉电阻。

上拉电阻的具体计算比较复杂,细节可参考“I2C Bus Pullup Resistor Calculation”。

连线时,可以通过杜邦线将master和slave的板子连接起来,SDA连SDA,SCL连SCL。
在PKE8720DF-C13-F10的引脚图中,我们可以看到,SDA默认是PA26,SCL默认是PA25。

2.2 启动和停止条件

在主设备决定开始通信时,需要先发送开始信号:
SDA、SCL初始化默认是高电平(因为被拉高),然后SDA先降低,紧接着SCL再降低,然后就表示通信开始。
由于I2C支持多master、多slave,在一个master决定发起通信前,要先检查发起通信前,SDA当前是否处于高电平。
当主设备决定结束通信时,要发送停止信号:
当SDA从低电平拉高,紧接着SCL从高电平拉低时,表示停止通信。

3. 软件说明

在开始使用前,我们做下面的准备。

3.1 ImageTool

用于download编译好的image到板子上。

3.2 Linux/Windows开发环境

其源代码获取路径,和代码编译流程,均可参考《快速上手PKE8720DF-C13-F10开发板》。

3.3 Tera Term

可在“Tera Term Download”下载该工具。其作用是用于查看master和slave的收发数据。

4. 代码介绍

4.1 Master

将两个PKE8720DF-C13-F10开发板中的一个当作master处理,另一个当作slave处理。此时,两个板子上运行的是不同模式的程序。
对master而言,我们查看如下目录下的代码:

vim ${ambd_sdk}/project/realtek_amebaD_va0_example/example_sources/I2C/raw/i2c_dual_master/src/main.c

在这个文件里,我们看到有这一行:

#define I2C_MASTER_DEVICE

表示这里是处理的master方式。

另外还有它要发送/接收的slave的设备地址:

#define MBED_I2C_SLAVE_ADDR0    0x23

这里是写死的代码,只是测试使用,表示slave地址为0x23,因为这里处理的是一对一的master和slave。实际使用过程中,可能是一对多或者多对多,slave设备可能有多个,每个有自己的地址,那么,可以维护一个slave的地址列表,从中进行匹配。

#define MBED_I2C_BUS_CLK        100000

这个表示当前选择的是100kbps的标准模式。

#define MBED_I2C_SLV_SDA    PA_26
#define MBED_I2C_SLV_SCL    PA_25

表示使用默认的PA26和PA25作为SDA线和SCL线。

void i2c_Init(i2c_t *obj, PinName sda, PinName scl)
{
    // ......
    PAD_PullCtrl(sda, GPIO_PuPd_UP);               
    PAD_PullCtrl(scl, GPIO_PuPd_UP);
    // ......
}

这里表示,SDA、SCL已经进行了拉高处理,不需要再额外接上拉电阻。

uint8_t    i2cdatasrc[I2C_DATA_LENGTH];
uint8_t    i2cdatadst[I2C_DATA_LENGTH];
uint8_t    i2cdatardsrc[I2C_DATA_LENGTH];
uint8_t    i2cdatarddst[I2C_DATA_LENGTH];

这里的几个全局数组,i2cdatasrc和i2cdatadst分别表示write的源数据和目的数据,i2cdatardsrc和i2cdatarddst表示read的源数据和目的数据。
在main()函数中,有对这几个数组进行初始化的操作,即将它们赋值为自己想要的数值,方便后面检查的时候,查看是否符合最开始时初始化设置的数值。

void i2c_master_rx_check(void)
{
    // ......
    if (i2cdatarddst[i2clocalcnt] != i2cdatardsrc[i2clocalcnt]) {
    // ......
}

为了检查master收到的data是否符合预期,我们可以将下面这一行注释打开,即可以将实际收到的data内容打印出来。

void i2c_master_rx_check(void)
{
    // ......
    for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
        DiagPrintf("i2c data: %02x \t %02x\n",i2cdatarddst[i2clocalcnt],i2cdatarddst[i2clocalcnt+1]);
    }
    // ......
}

这里就是master在接收data时,检查接收的数据,是否符合预期。
将这个main.c复制到src_hp路径下,覆盖里面的main.c。

cp -f main.c ../../../../../src/src_hp/

然后编译生成三个image文件,烧录到master板子中。

4.2 Slave

对slave而言,我们查看如下目录下的代码:

vim ${ambd_sdk}/project/realtek_amebaD_va0_example/example_sources/I2C/raw/i2c_dual_slave/src/main.c

我们可以用vimdiff或其它比较工具,将这个main.c文件,和上面master模式对应得main.c文件进行比较,可以发现,它里面的这一行是没有定义的:

// #define I2C_MASTER_DEVICE

也就是说,这一项关闭之后,下面的代码中,所有执行到编译选项“#ifdef I2C_MASTER_DEVICE”、“#else”的地方,都会执行slave的分支。
其余的几个定义,则是一样的。

#define MBED_I2C_SLAVE_ADDR0    0x23

这里表示当前这个slave设备的地址默认为0x23,是写死的。真实使用时,需根据实际情况进行调整。

#define MBED_I2C_BUS_CLK        100000

这个表示当前选择的是100kbps的标准模式,和master保持一致。

#define MBED_I2C_SLV_SDA    PA_26
#define MBED_I2C_SLV_SCL    PA_25

表示使用默认的PA26和PA25作为SDA线和SCL线。

void i2c_Init(i2c_t *obj, PinName sda, PinName scl)
{
    // ......
    PAD_PullCtrl(sda, GPIO_PuPd_UP);               
    PAD_PullCtrl(scl, GPIO_PuPd_UP);
    // ......
}

这里表示,SDA、SCL已经进行了拉高处理,不需要再额外接上拉电阻。
与master一样,为了检查slave收到的data是否符合预期,我们可以将下面这一行注释打开,即可以将实际收到的data内容打印出来。

void i2c_slave_rx_check(void)
{
    // ......
    for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) {
        DiagPrintf("i2c data: %02x \t %02x\n",i2cdatadst[i2clocalcnt],i2cdatadst[i2clocalcnt+1]);
    }
    // ......
}

将这个main.c复制到src_hp路径下,覆盖里面的main.c。

cp -f main.c ../../../../../src/src_hp/

然后编译生成三个image文件,烧录到slave板子中。

5. 实验结果

由于这里测试的是一对一的master、slave收发数据,所以将两者的SDA直接相连,SCL直接相连即可。
然后,将它们一起通过type-C USB线连接到PC机上,查看它们各自的port口。

打开两个Tera Term工具窗口,分别开启两个port的窗口,波特率选择115200。然后,先按下slave的reset键,再按下master的reset键。可以看到,在界面上,打印出来的data内容,和两个main.c里面设置的全局数组中的内容,是一致的。

 当然,测试者也可以根据自己的偏好,修改几个全局数组里面的data内容,查看最终master和slave实际接收的data,是否和自己填写的内容一致。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值