如何使用MAX20340通过电源线发送和接收数据

描述

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协议中没有内置从站寻址。如果用户应用程序不要求两个从站接收不同的数据,并且从属机从不尝试同时响应主站,则唯一地址不需要嵌入到数据字节中。如果未使用从站寻址方案,则两个从站都接收主站发送的数据。如果任何从站响应主站,则所有其他从站将此响应视为接收到的数据。如果两个从站尝试同时响应,则会发生通信错误。适当的从站寻址方案可以防止此类错误。

审核编辑:郭婷

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分