0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用LPC55S28 I2C从机功能,接收不定长的数据(通过字节数或者STOP条件判断)

li1756686189 来源:嵌入式 MCU 2023-01-13 10:12 次阅读

使用LPC55S28的I2C从机接口,比如实现 24LC系列的从机EEPROM 。可以提供以下操作,如字节写入、页面写入、当前地址读取、随机读取和顺序读取。接下来,使用Byte Write和Random Read作为示例来说明。首先明确需要判断的状态,包括以下内容:数据和地址-- 用于确定接收到的地址或数据。起始位-- 用于判断是否接收到起始位。读写-- 用于判断是写状态还是读状态。

随机读取

如果从设备生成kI2C_SlaveAddressMatchEvent,则表示从设备检测到主设备发送的启动或重复启动。可以在程序中设置一个变量,记录它是启动还是重复启动,并根据传输情况合理设置该变量的值。假设从设备检测到启动,那么根据接受容量字节大小,接收到两个字节或三个字节,那么第一个字节是包含读写操作的设备的地址,第二个和第三个字(如果存在)是要操作的数据的地址。接下来,LPC5528将再次检测启动,即再次接收具有读取操作的设备地址。LPC5528从相应的数据地址读取数据并将其返回给主机。

174e1536-9296-11ed-bfe3-dac502259ad0.png

字节写

如果从设备生成kI2C_SlaveAddressMatchEvent,则表示从设备检测到主设备发送的启动或重复启动。可以在程序中设置一个变量,记录它是启动还是重复启动,并根据传输情况合理设置该变量的值。假设从设备检测到启动,那么根据接收容量大小,接收到两个字节或三个字节,那么第一个字节是包含读写操作的设备的地址,第二个和第三个字(如果存在)是要操作的数据的地址。紧随其后的字节是数据。将此数据字节保存到上一步骤中获得的地址中。

1766365c-9296-11ed-bfe3-dac502259ad0.png

当主机设置STOP条件停止传输的时候,从机端需要获得一个提醒。可以参考例程"i2c_interrupt_b2b_transfer_slave.c" 实现基于I2C从机的例子。

177e05a2-9296-11ed-bfe3-dac502259ad0.png

179a525c-9296-11ed-bfe3-dac502259ad0.png

I2C驱动的状态机设置xfer->rxSize 和xfer->txSize 变量。

static void i2c_slave_callback(I2C_Type *base, volatile i2c_slave_transfer_t *xfer, void *userData)
{
switch (xfer->event)
{
/* Address match event */
case kI2C_SlaveAddressMatchEvent:
xfer->rxData = NULL;
xfer->rxSize = 0;
break;
/* Transmit request */
case kI2C_SlaveTransmitEvent:
/* Update information for transmit process */
xfer->txData = &g_slave_buff[2];
xfer->txSize = g_slave_buff[1];
break;

/* Setup the slave receive buffer */
case kI2C_SlaveReceiveEvent:
/* Update information for received process */
xfer->rxData = g_slave_buff;
xfer->rxSize = I2C_DATA_LENGTH;
break;

/* The master has sent a stop transition on the bus */
casekI2C_SlaveCompletionEvent:
g_SlaveCompletionFlag = true;
break;

default:
g_SlaveCompletionFlag = false;
break;
}

}

如果主机发送一定数据后,判断分支casekI2C_SlaveCompletionEvent将会执行,同时g_SlaveCompletionFlag 标志将会设置为 true。在SDK中,使用I2C_SlaveTransferNonBlocking 函数,有判断字节传输完成的动作。

/* Start accepting I2C transfers on the I2C slave peripheral */
reVal = I2C_SlaveTransferNonBlocking(EXAMPLE_I2C_SLAVE, &g_s_handle,
kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent);
if (reVal != kStatus_Success)
{
return -1;
}

/* Wait for transfer completed. */
while (!g_SlaveCompletionFlag)
{
}
g_SlaveCompletionFlag = false;

case k2IC_SlaveCompletionEvent 这个分支的进入不是根据主机发送的stop条件进入的,而是根据字节数进入的,譬如:如果主机发送256字节,接收字节数定义为16,当第16个数据接收完成后,就会进入该分支。但是 I2C 从机端事先并不知道 I2C 主机发送的字节数,所以无法判定停止。有什么办法能判断停止呢?

“API需要编写代码判断在I2C STOP停止时达到完成状态,而不是通过rxData计数到0。”参考示例代码只显示raData计数减到了0。如果要在停止时达到完成状态,在 i2c 从机回调函数i2c_slave_callback中,需要添加case kI2C_SlaveDeselectedEvent。

static void i2c_slave_callback(I2C_Type*base, volatile i2c_slave_transfer_t *xfer, void *userData)
{
switch (xfer->event)
{

...

casekI2C_SlaveDeselectedEvent:
g_SlaveCompletionFlag = true;
// 用户代码
break;

...

}
}

在传输函数中,需要添加kI2C_SlaveDeselectedEvent:

/* 在 I2C 从机外设中, 启动接收 I2C传输*/
reVal = I2C_SlaveTransferNonBlocking(EXAMPLE_I2C_SLAVE,&g_s_handle,kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent|kI2C_SlaveDeselectedEvent);

当 I2C主机发送 STOP,从机的STAT标志将会设置为1,函数 I2C_SlaveTransferHandleIRQ将会触发 kI2C_SlaveDeselectedEvent。查看驱动代码如下:

void I2C_SlaveTransferHandleIRQ(I2C_Type *base,i2c_slave_handle_t *handle)
{
uint32_t i2cStatus = base->STAT;

if (i2cStatus &I2C_STAT_SLVDESEL_MASK)
{
I2C_SlaveInvokeEvent(base, handle,kI2C_SlaveDeselectedEvent);
I2C_SlaveClearStatusFlags(base,I2C_STAT_SLVDESEL_MASK);
}

...

}

在 LPC55 参考手册第 637页面有相关描述。

17ba3be4-9296-11ed-bfe3-dac502259ad0.png

审核编辑:汤梓红。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8434

    浏览量

    150685
  • EEPROM
    +关注

    关注

    9

    文章

    1008

    浏览量

    81299
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1473

    浏览量

    122970
  • 状态机
    +关注

    关注

    2

    文章

    490

    浏览量

    27450
  • 从机
    +关注

    关注

    0

    文章

    3

    浏览量

    849

原文标题:使用 LPC55S28 I2C 从机功能,接收不定长的数据(通过字节数或者STOP条件判断)

文章出处:【微信号:嵌入式 MCU,微信公众号:嵌入式 MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    用STM32F030F4串口空闲中断接收不定长数据,发生中断后不知道如何计算接收到的字节数

    我用STM32F030F4串口空闲中断接收不定长数据,发生中断后不知道怎样计算接收到的字节数
    发表于 04-03 07:12

    STM32单片接收不定长字节数据的方法(适用于ARM单片

    串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。STM32F10x 的USART 模块也不过如此。  STM32单片接收
    发表于 05-27 07:00

    STM32单片接收不定长字节数据的方法

    串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。STM32F10x 的USART 模块也不过如此。  STM32单片接收
    发表于 05-31 08:00

    STM32单片接收不定长字节数据的方法解析相关资料推荐

    http://m.elecfans.com/article/899756.html今天说一下STM32单片接收不定长字节数据的方法。由于STM32单片
    发表于 07-01 09:41

    STM32单片接收不定长字节数据的方法

    STM32串口使用IDLE中断接收不定长数据原理与源程序转载 2016年07月16日 18:20:24原文来自 今天说一下STM32单片接收
    发表于 08-04 09:05

    STM32单片接收不定长字节数据的方法

    最近用到stm32的串口,中断一个字符一个字符接收好心累,网上度了一下发现了一篇好的帖子,和大家分享一下,再次感谢原贴楼主的分享,为了方便大家,我把原文复制过来》今天说一下STM32单片接收
    发表于 08-13 06:30

    STM32单片接收不定长字节数据的方法是什么

    IDLE中断什么时候发生?如何配置好IDLE中断?STM32单片接收不定长字节数据的方法是什么?
    发表于 10-19 07:00

    请问STM32单片如何接收不定长字节数据

    IDLE中断什么时候发生?STM32单片如何接收不定长字节数据
    发表于 10-25 06:46

    STM32串口接收不定长字节数据的方法

    STM32串口接收不定长字节数据的方法
    发表于 12-09 06:35

    STM32单片是如何利用IDLE中断接收不定长字节数据

    IDLE中断什么时候发生?如何配置好IDLE中断?STM32单片是如何利用IDLE中断接收不定长字节数据的?
    发表于 12-09 07:02

    STM32单片接收不定长字节数据的方法

    来说一下STM32单片接收不定长字节数据的方法。由于STM32单片带IDLE中断,所以利用这个中断,可以
    发表于 01-06 08:04

    STM32单片接收不定长字节数据的方法解析

    IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片一次发来1个字节或者一次发来8个
    发表于 04-02 14:30 5291次阅读
    STM32单片<b class='flag-5'>机</b><b class='flag-5'>接收</b><b class='flag-5'>不定长</b>度<b class='flag-5'>字节数据</b>的方法解析

    单片串口接收字节数据

    单片串口接收字节数据
    发表于 11-17 09:51 42次下载
    单片<b class='flag-5'>机</b>串口<b class='flag-5'>接收</b>多<b class='flag-5'>字节数据</b>

    stm32 串口接收不定长度数据及黏包处理 + 串口DMA接收

    1.不定长度数据 为什么会存在串口接收不定长度数据呢?首先,在通信双方进行数据传输的时候,由于不同的设备在实现控制,数据采样时,发送的
    发表于 12-23 19:09 27次下载
    stm32 串口<b class='flag-5'>接收</b><b class='flag-5'>不定长度数据</b>及黏包处理 + 串口DMA<b class='flag-5'>接收</b>

    I2C数据传输的三个主要API

    _client *client,char *buf,int count) client:I2C 设备对应的 i2c_client。 buf:要接收数据。 count:要
    的头像 发表于 07-22 15:04 1404次阅读
    <b class='flag-5'>I2C</b><b class='flag-5'>数据</b>传输的三个主要API