MAX20340简化了通过电源线发送和接收数据的过程。任何具有 I 的系统2C主站可以在供电的同时发送和接收数据。本文讨论如何编写软件以在主站和从站之间发送和接收数据。它还提供了示例代码片段以加速开发。
介绍
本文说明如何使用MAX20340双向直流电力线通信管理IC发送和接收数据。该文件描述了用于将数据传输到单个从站或多个从站的主从固件。还包括示例代码片段。
通信概述
在最简单的配置中,主机仅通过两个物理触点连接到单个从站:PLC和接地。主机和从机各有自己的微控制器,通过I与各自的MAX20340通信。2C 发送和接收数据。
图1.主站和单个从站之间通信接口的简化框图。
传输数据
MAX20340简化了电力线数据传输。首先,要传输的数据是通过I写入的2C 到三个 8 位传输数据字节寄存器。然后,PLC传输位通过I2C 指定要传输的字节数。一旦写入 PLC 传输位,传输就开始了。
最多写入三个字节的数据以传输到传输数据字节寄存器(TX_DATA0、TX_DATA1和寄存器TX_DATA2 0x0D、0x0E、0x0F)。
将 PLC 传输位 (TX[1:0]) 写入PLC_COM_CTRL寄存器以触发最多三个字节的传输。写入 TX[1:0] 字段的值指定要传输的字节数。(PLC_COM_CTRL在登记册0x09中)。
图2.流程图显示了使用MAX20340通过电源线传输数据的步骤。
接收数据
接收从另一个MAX20340发送的数据也非常简单。断言“新数据”中断,指定接收数据时的字节数。然后,可以通过I2C在三个8位接收数据字节寄存器中读取接收的数据。
等待新数据中断(NEW_DATA1i并在寄存器2x0B中NEW_DATA0i)。
从接收数据字节寄存器(寄存器0x1、2x0 和 10x0)中读取最多三个字节的接收数据(RX_DATA11、RX_DATA0 和寄存器中的RX_DATA12)。
图3.流程图显示了使用MAX20340通过电源线接收传输数据的步骤。
主/从通信流程
在典型应用中,主从应用处理器遵循主/从通信顺序并检查传输错误。
MAX20340配置为主站,启动所有PLC通信。配置为从机的MAX20340只能在主站向其发送数据后向主站发送数据。主站传输数据后,启动定时器等待从站响应。如果计时器过期,则在主站上断言PLC_TMRi中断,表示从机没有响应。在发送任何新数据之前,主站应等待从站响应或超时。
主机和从站还应检查PLC_TX_ERRi和PLC_RX_ERRi中断指定的传输错误。
例子
这些实现示例假设主从应用处理器的输入引脚配置为中断,连接到MAX20340的中断引脚。调用“wait_for_interrupt()”会检查此引脚的状态并等待其为低电平。此功能的实现是特定于平台的。调用“I2C_write_register(...)”和“I2C_read_register(...)”可启动MAX8中20340位寄存器的读写,其实现也特定于平台。
假设在每个示例中都已取消屏蔽所有相关中断。其他一些实现通过 I 轮询中断寄存器2C 而不是取消屏蔽中断并使用中断引脚。
这些示例假设所有传输均以默认通信设置发送:24μs通信频率、288mA PLC灌电流、奇偶校验和10ms RX等待定时器。这些设置取决于应用程序。
将数据传输到单个从站
在本例中,PLC 主站连接到单个 PLC 从站(图 1)。主站传输三个字节,从站以一个字节响应。主机应仅在处于“从站发现充电”状态(FSM_STAT = 0b110)时尝试传输数据。
主传输
主固件遵循以下基本结构,在设置中断掩码后传输三个字节:
将一组三个字节加载到 TX_DATA0-2 寄存器中。
通过在PLC_COM_CTRL寄存器中写入 TX[1:0] 位来发送三个字节。
(可选)等待 NEWDATA1/2、TMR_ERR、TX_ERR 或 RX_ERR 中断。
或者,如果收到 NEWDATA1/2 中断,则从RX_DATA寄存器读取从属响应。
从属接收
设置中断掩码后,从属固件遵循以下基本结构,等待来自主站的数据,并可选择在主站的等待计时器到期之前做出响应:
等待 RX_ERR 或 NEW_DATA1/2 中断。
如果收到 NEWDATA1/2 中断,则从 RX_DATA0-2 个寄存器读取数据字节。
(可选)将响应加载到 TXDATA0 寄存器中。
(可选)通过在PLC_COM_CTRL寄存器中写入 TX[1:0] 位来发送一个字节。
主传输固件示例代码片段
主固件的代码片段如下所示。在此示例中,数据字节、0x55、0x5A和0xA5由主站传输。此代码旨在用作辅助开发的参考,不能按原样使用。
/*Load a set of three bytes into TX_DATA0-2 registers and write all three bytes at once (I2C auto-incrementation of register address)*/ uint8_t data_bytes[3]; data_bytes[0] = 0x55; data_bytes[1] = 0x5A; data_bytes[2] = 0xA5; I2C_write_register(AO23_MAST_ADDR, TX_DATA0_REG, data_bytes, 3); /*Send three bytes by writing 0b11 to the TX[1:0] bits in the PLC_COM_CTRL register (all other bits [7:2] are application dependent)*/ I2C_write_register(AO23_MAST_ADDR, PLC_COM_CTRL_REG, 0x97); /*Optional: wait for NEWDATA, TMR_ERR, TX_ERR, or RX_ERR interrupt (timeout should be added in typical system)*/ wait_for_interrupt(); /*Optional: Check if interrupt was caused by slave response (NEWDATA1/2)*/ uint8_t plc_int_buf[1]; I2C_read_register(AO23_MAST_ADDR, PLC_IRQ_REG, plc_int_buf, 1); bool new_data = (plc_int_buf[0] & 0x06) != 0; /*Optional: If NEWDATA interrupt, read single-byte slave response (response should be processed in typical system)*/ if(new_data){ uint8_t slave_resp_buf[1]; I2C_read_register(AO23_MAST_ADDR, RX_DATA0_REG, slave_resp_buf, 1); }
从站接收固件示例代码片段
A snippet from the slave firmware is shown below. The slave responds to the received data by transmitting a single byte: 0x55 in this example. This code is meant to be used as a reference to assist development and cannot be used as is./*Wait for RX_ERR or NEW_DATA1/2 interrupt*/ wait_for_interrupt(); /*Check if interrupt caused by received data (NEWDATA1/2)*/ uint8_t plc_int_buf[1]; I2C_read_register(AO23_SLAV_ADDR, PLC_IRQ_REG, plc_int_buf, 1); bool new_data = (plc_int_buf[0] & 0x06) != 0; /*If data received, read data and optionally respond*/ if(new_data){ /*Read all three data bytes from RX_DATA0-2 registers (I2C auto-incrementation of register address) (received data should be processed in typical system)*/ uint8_t data_reg_buf[3]; I2C_read_register(AO23_SLAV_ADDR, RX_DATA0_REG, data_reg_buf, 3); /*Optional: Load response into TXDATA0 register*/ I2C_write_register(AO23_SLAV_ADDR, TX_DATA0_REG, 0x55); /*Optional: Send one byte by writing the TX[1:0] bits in the PLC_COM_CTRL register (all other bits [7:2] are application dependent)*/ I2C_write_register(AO23_SLAV_ADDR, PLC_COM_CTRL_REG, 0x95); }
将数据传输到两个从站
在本例中,主机向两个连接的从站之一传输三个字节(图 4)。
图4.主站和两个从站之间通信接口的简化框图。
每个从机都配置了不同的RSEL电阻值,以确保它们具有唯一的PLC从机地址。目标接收方的 PLC 从地址被添加到第一个传输字节的 MSB 中。
从站以一个字节响应,并在响应字节的MSB中包含自己的PLC从地址。
有关本实现示例中使用的PLC从站寻址的更多详细信息,请参阅本文档的“多个从站注意事项”部分。
主传输
主固件遵循以下基本结构,在设置主等待计时器和中断掩码后传输三个字节:
将一组三个字节加载到 TX_DATA0-2 寄存器中(23 位中只有 24 位包含要发送的数据)。一位,即TX_DATA0的MSB,包含接收方的PLC从地址)。
通过在PLC_COM_CTRL寄存器中写入 TX[1:0] 位来发送三个字节。
(可选)等待 NEWDATA1/2、TMR_ERR、TX_ERR 或 RX_ERR 中断。
或者,如果收到 NEWDATA1/2 中断,则从RX_DATA寄存器读取从属响应。
从属接收
设置中断掩码后,从属固件遵循以下基本结构,等待来自主站的数据,并可选择在主站的等待计时器到期之前做出响应:
等待 RX_ERR 或 NEW_DATA1/2 中断。
如果收到 NEWDATA1/2 中断,则从 RX_DATA0-2 寄存器读取数据字节。
读取DEV_STATUS1寄存器的PS_ADD位。
检查RX_DATA0的 MSB。如果 MSB 不等于 PS_ADD,请忽略接收到的数据。
(可选)将响应加载到 TXDATA0 寄存器中(7 位中只有 8 位包含要发送的数据)。一位,即 TX_DATA0 的 MSB,包含 PS_ADD 位)。
(可选)通过在PLC_COM_CTRL寄存器中写入 TX[1:0] 位来发送一个字节。
主传输固件示例代码片段
主固件的代码片段如下所示。在此示例中,数据字节0x55、0x5A和0xA5由主站传输。数据以PLC从站地址“1”传输到从站。因此,发送的实际数据是0xD5、0x5A和0xA5(PLC 从地址添加到字节 1 的 MSB 中)。此代码旨在用作辅助开发的参考,不能按原样使用。
/*Load a set of three bytes into TX_DATA0-2 registers and write all three bytes at once (I2C auto-incrementation of register address)*/ uint8_t data_bytes[3]; data_bytes[0] = 0xD5; /*This byte contains 7 bits of actual data, MSB is recipient PS_ADD*/ data_bytes[1] = 0x5A; data_bytes[2] = 0xA5; I2C_write_register(AO23_MAST_ADDR, TX_DATA0_REG, data_bytes, 3); /*Send three bytes by writing 0b11 to the TX[1:0] bits in the PLC_COM_CTRL register (all other bits [7:2] are application dependent)*/ I2C_write_register(AO23_MAST_ADDR, PLC_COM_CTRL_REG, 0x97); /*Optional: Wait for slave response interrupt (timeout should be added in typical system)*/ wait_for_interrupt(); /*Optional: Check if interrupt caused by slave response (NEWDATA1/2)*/ uint8_t plc_int_buf[1]; I2C_read_register(AO23_MAST_ADDR, PLC_IRQ_REG, plc_int_buf, 1); bool new_data = (plc_int_buf[0] & 0x06) != 0; /*Optional: if NEWDATA interrupt, read slave response (response should be processed in typical system)*/ if(new_data){ uint8_t slave_resp_buf[1]; I2C_read_register(AO23_MAST_ADDR, RX_DATA0_REG, slave_resp_buf, 1); }
从站接收固件示例代码片段
从固件的代码片段如下所示。从站通过发送单个字节来响应接收到的数据:在本例中0x55。该从站的PLC从站地址为“1”。因此,发送的实际数据是0xD5(PLC从地址被添加到字节1的MSB)。此代码旨在用作辅助开发的参考,不能按原样使用。
/*Wait for RX_ERR or NEW_DATA1/2 interrupt*/ wait_for_interrupt(); /*Check if interrupt caused by received data (NEWDATA1/2)*/ uint8_t plc_int_buf[1]; I2C_read_register(AO23_SLAV_ADDR, PLC_IRQ_REG, plc_int_buf, 1); bool new_data = (plc_int_buf[0] & 0x06) != 0; /*If data received, read data, check if intended recipient, and optionally respond*/ if(new_data){ /*Read all three data bytes from RX_DATA0-2 registers (I2C auto-incrementation of register address) (received data should be processed in typical system)*/ uint8_t data_reg_buf[3]; I2C_read_register(AO23_SLAV_ADDR, RX_DATA0_REG, data_reg_buf, 3); /*read PS_ADD bit of the DEV_STATUS1 register*/ uint8_t slave_addr_buf[1]; I2C_read_register(AO23_SLAV_ADDR, DEV_STATUS1_REG, slave_addr_buf, 1); uint8_t PS_ADD = slave_addr_buf[0] & 0x01; /*Check if MSB of RX_DATA0 (intended recipient address) equals PS_ADD of this slave*/ uint8_t = recipient_plc_addr = (data_reg_buf[0] & 0x80) >> 7; bool is_recipient = (PS_ADD == recipient_plc_addr); if(is_recipient){ /*Optional: Load response into TXDATA0 register. This byte contains 7 bits of actual data, MSB is the slave's own PS_ADD*/ I2C_write_register(AO23_SLAV_ADDR, TX_DATA0_REG, 0xD5); /*Optional: Send one byte by writing the TX[1:0] bits in the PLC_COM_CTRL register (all other bits [7:2] are application dependent)*/ I2C_write_register(AO23_SLAV_ADDR, PLC_COM_CTRL_REG, 0x95); } }
多个从站注意事项
MAX20340主机可以连接任意数量的从机。PLC上的最大从站数量仅受主站可以提供的最大充电电流(1.2A)和PLC上的总电容的限制。
应使用用户定义的寻址方案,以防止当PLC主站与两个或多个PLC从机接口时,多个从站尝试同时响应。PLC从地址在传输过程中不会自动使用,尽管RSEL电阻可用于为从机分配具有唯一PLC从地址的从机。
当主站传输数据时,所有连接的从站都会接收数据,无论其配置的PLC从站地址如何。当 PLC 主站打算仅将数据包发送到其中一个 PLC 从站时,应在数据字节中嵌入唯一标识预期接收方的地址。用户可以灵活地将地址分配给任何数据字节位。
RSEL 设置的 PLC 从地址仅为 1 位。因此,它仅在寻址最多两个从站时才有用。如果连接了两个以上的PLC从站,则必须使用更多位传输的数据字节来唯一地寻址所有从站。
所有PLC从站接收相同的数据。因此,每个从站的应用处理器都应该从传输的数据中提取地址位,并将其与自己的唯一地址进行比较,以确定它是否是预期的接收者。然后,预期的从站相应地处理数据,而其他从站则简单地丢弃数据。
双从机寻址示例
假设有两个连接的从站,第一个具有PLC从地址“0”,第二个具有PLC从地址“1”(基于RSEL值并存储在DEV_STATUS1寄存器的PS_ADD位中)。用户选择将目标接收方的PLC从地址编码为第一个字节的最高有效位。
主机向第一个从站发送 23 位数据,如下所示:
字节 1: '0xxxx' 字节 2: 'xxxx'
字节 3: 'xxxxxx'
其中x是23位数据,字节1的MSB包含第一个从站的PLC从地址('0')。
主机向第二个从设备发送23位数据,如下所示:
字节 1: '1xxxx' 字节 2: 'xxxx'
字节 3: 'xxxxxxx'
其中x是23位数据,字节1的MSB包含第二个从站的PLC从地址(“1”)。
当主站传输此数据时,两个从站都将接收数据。
当从站接收数据时,如果字节1的MSB与配置的PLC从地址匹配,则此数据适用于它,并且应该处理数据。 如果MSB与配置的PLC从地址不匹配,则此数据不适用于它,它应该简单地丢弃/忽略数据。
如果预期的接收者从站响应主站,则所有其他从站也会收到响应。在具有多个从站的从站响应期间,预期的接收方从站自己的PLC从站地址应嵌入到响应的数据字节中。这可确保其他从站丢弃/忽略预期的从站对主站的响应。
请注意,这不是必需的,PLC协议中没有内置从站寻址。如果用户应用程序不要求两个从站接收不同的数据,并且从属机从不尝试同时响应主站,则唯一地址不需要嵌入到数据字节中。如果未使用从站寻址方案,则两个从站都接收主站发送的数据。如果任何从站响应主站,则所有其他从站将此响应视为接收到的数据。如果两个从站尝试同时响应,则会发生通信错误。适当的从站寻址方案可以防止此类错误。
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !