嵌入式测量器件使用简单的串行接口

描述

简单串行接口(SSI)是一种二进制协议,用于与模拟嵌入式测量设备(78M6610+LMU、78M6610+PSU和MAX78630+PPM)通信。

概述

简单串行接口(SSI)是一种二进制串行协议,用于ADI公司嵌入式测量设备(EMD)上的UART通信。本应用笔记通过详细说明可用命令和相应的源代码示例来介绍该协议的特性和结构。该协议的主要特点是:

简单性:该协议可以在主机处理器上实现,而不会占用过多的系统资源。

健壮性:每个数据包都包含一个标头、字节计数、有效负载和校验和。如果命令的标头、字节计数和校验和不正确,则收件人可以拒绝数据包。

效率:数据以二进制编码而不是字符编码值交换,命令不需要回显到主机。此外,可以在单个数据包中发送多个命令,以进一步减少通信开销。

支持多点系统:目标设备寻址能力支持在单个串行总线上连接多个目标设备。

SSI 是一种基于数据包的协议,可实现主从或命令-响应通信。SSI 中使用两种类型的数据包:主数据包,由主机设备发出;和从数据包,由从属 EMD 发出,以响应来自主机或主站的命令。

下载相应的源代码。

串行接口选择

主站通过三个串行接口访问模拟 EMD:UART、SPI 和 I2C。SSI 使用 UART 接口,必须相应地配置 EMD 才能使用 SSI。这是通过器件相应引脚上的上拉或下拉电阻完成的。有关配置器件串行接口的说明,请参阅器件数据手册。

设备地址

EMD 的器件地址 (SSID) 通过 DevAddr 寄存器和器件的一个或两个引脚的组合进行设置,具体取决于器件的封装。有关设置器件SSID的说明,请参阅器件数据手册。

主数据包

主数据包始终包含以下内容:

单字节标头,0xAA

单字节数据包长度指示器,它是数据包中所有字节的计数,包括其自身

有效负载,可以包含多个命令

校验和,它是数据包中所有前面字节的模 256 和的二进制补码,从标头字节开始,包括有效负载的最后一个字节

从上面的描述中,有一些特征与所有有效的主数据包有关:

主数据包的长度始终为 4 个或更多字节。

主数据包的长度不能超过 255 字节。

字段字节计数为一个字节。

数据包的最大长度受从设备的命令缓冲区限制。请参阅从器件的数据手册,了解该器件的最大命令长度。

图 1 说明了主数据包的结构。

嵌入式

图1.SSI 主数据包结构。

从数据包

从数据包的结构因从设备从主设备接收的命令而异。最短的从数据包是单字节响应,表示对收到的命令进行肯定或否定确认。在 SSI 中实现的所有单字节数据包如表 1 所示。

 

法典 定义
0xAD 没有数据的正确认是接收和执行的有效命令,但不需要数据响应。
0xB0 否定确认
0xBC 错误命令是从设备不支持的已接收命令。
0xBD 校验和错误是在主数据包中检测到的校验和错误。
0xBF 缓冲区溢出表示主数据包太长。

 

包含数据的从数据包遵循与主数据包相同的一般结构,包括标头字节、字节计数、有效负载和校验和,如图 2 所示。

多字节从数据包的标头字节可以是0xAA(用数据确认)或0xAE(自动报告数据包)。自动报告数据包由 78M6610+PSU 等设备生成,这些设备可以定期自动传输测量数据。由于自动报告数据和命令响应数据有不同的标头,因此主机可以在从站发送自动报告数据时发送命令和接收响应。

嵌入式

图2.多字节从数据包。

主命令

SSI主站和从站之间的大多数通信都涉及请求从设备中寄存器的内容并写入这些寄存器。典型的命令序列包括向从站发送目标寄存器地址,并发出读或写命令以从目标地址开始读取或写入一个或多个寄存器。其他命令允许在单个总线上具有多个从设备的系统中选择或取消选择单个从设备。实现自动报告的设备还可以接受命令来更改自动报告数据包的内容。

当前版本的 SSI 中支持的所有主命令如表 2 所示。请注意,所有模拟 EMD 可能无法响应所有命令。请参阅器件的数据手册,以确定哪些命令可以在特定器件中执行。

 

命令 参数 描述
0xA0  
0xA1 1 字节,地址 [7:0] 设置目标地址位 [7:0]。
0xA2 1 字节,地址 [15:8] 设置目标地址位 [15:8]。
0xA3 2 字节,地址 [7:0],[15:8] 设置目标地址位 [15:0]。
0xD0 数据 写入字节,从目标地址开始,由字节计数的剩余部分设置。
0xD1-0xDF 数据 从目标地址开始写入 1–15 个字节。
0xE0 1 字节,字节数 从目标地址开始读取字节,需要指示要读取的字节数的参数。
0xE1-0xEF 从目标地址开始读取 1–15 个字节,不需要参数,使用低半字节。
0xAE 安装新的自动报告命令。
以下命令用于选择和取消选择目标设备
0xC0 取消选择当前选定的从属设备
0xC1-0xCE 选择目标设备,不需要参数,使用低半字节。
0xCF 1 字节,设备的 SSID 选择目标设备,需要指示从设备SSID的参数

 

超时

当设备空闲(即等待来自主站或目标站的数据包)时,接收缓冲区指针将重置并指向第一个缓冲区位置。收到第一个字节时,设备会检查它是 SSI 标头还是应答 (0xAA)。如果是这样,则重置超时计时器,并且每个后续接收字节也会重置计时器。如果在超时间隔内未收到任何字节,并且数据包被视为不完整,则设备将返回空闲状态,而不发送任何内容。此时,主服务器可以重新发送最后一个命令或发送新命令。

当数据包损坏或未选择目标时,可能会发生超时。主设备和从设备都必须实现超时。如果在接收数据包期间以当前波特率在大约 50 字节时间内未收到字节,则会发生超时。在重新发送命令之前,主服务器应至少等待此时间。

SSI 源代码和示例

开发以下示例是为了帮助理解 SSI 协议,并为构建自定义应用程序奠定基础。提供的源代码不执行任何特定的应用程序;但是,它确实提供了与模拟EMD接口所需的基本功能。提供的源代码文件及其说明列于表 3 中。

 

文件 描述
maxim_ssi.c SSI 读取、写入等的函数定义
maxim_ssi.h 函数原型和 SSI 命令#defines
maxim_em_device.h 定义应用中使用的嵌入式测量设备的头文件
78M6610_LMU.h 嵌入式测量设备头文件
78M6610_PSU.h 嵌入式测量设备头文件
MAX78630_PPM.h 嵌入式测量设备头文件
华华 客户的硬件特定功能定义(ssi_tx_byte、ssi_rx_byte)
呵呵 客户的硬件特定功能原型

 

maxim_ssi.c和maxim_ssi.h

头文件 maxim_ssi.h 提供 SSI 函数原型,并定义主命令、从属响应和最大数据包长度。

maxim_ssi.c 提供以下功能:

无符号字符ssi_get_checksum(无符号字符 CNT,无符号字符×数据) 函数 ssi_get_checksum()

计算 SSI 数据包的相应校验和。

int ssi_send_packet(无符号字符byte_cnt,无符号字符 x 有效负载) 函数 ssi_send_packet()

需要有效负载字节计数和指向有效负载的指针作为其参数。如果数据包字节计数(有效负载字节计数 + 3)大于从设备头文件中定义的MAX_PACKET_LEN,则 ssi_send_packet() 将返回 -1 以指示故障。如果没有,该函数通过将标头、数据包字节计数添加到有效负载的前面来完成数据包构建,然后调用 ssi_get_checksum() 将校验和添加到数据包的末尾。然后,该函数将数据包一次发送到 ssi_tx_byte()。

maxim_ssi.c 提供的所有剩余功能都调用 ssi_send_packet() 并提供嵌入式测量应用所需的基本功能。但是,最终用户可以自由构建自定义数据包并从其应用程序调用 ssi_send_packet()。如果他们选择这样做,请务必记住,该函数仅期望有效负载中的字节数作为其参数和指向该有效负载的指针。标头、实际数据包字节计数和校验和由函数添加。

int ssi_deselect_device(void) 函数 ssi_deselect_device() 构建适当的 SSI 有效负载,用于在串行总线上发送 DE_SELECT_TRGT (0xC0)

master 命令,然后调用函数 ssi_send_packet()。该函数返回从设备响应或 -1 以指示故障。

在任何应用程序的开头调用此函数,以确保在继续之前未选择任何设备。图 3 显示了调用 ssi_deselect_device 函数的预期主数据包和从属响应。

 

嵌入式

int ssi_select_device(unsigned char ssid) 函数 ssi_select_device()

需要一个字节作为其参数,即要选择从设备的 SSID。然后,该函数构建适当的 SSI 有效负载,用于在串行总线上发送 SELECT_TRGT(0xCF 或 0xC1–0xCE)主命令,然后调用函数 ssi_send_packet()。该函数返回从设备响应或 -1 以指示故障。图 4 和图 5 显示了调用 ssi_select_device() 函数的预期主数据包和从属响应。

 

嵌入式

 

嵌入式

int ssi_set_rw_adrs(emd_register_t adrs) 函数 ssi_set_rw_adrs()

需要枚举类型的emd_register_t作为其参数。此数据类型表示嵌入式测量设备寄存器的字地址。参数可以是关联从设备头文件中定义的寄存器的名称,也可以是单词地址的整数表示形式。

该函数构建适当的 SSI 有效负载以发送 RW_ADRS (0xA3) 主命令,然后调用函数 ssi_send_packet()。该函数返回从设备响应或 -1 以指示故障。图 6 显示了调用 ssi_set_rw_adrs() 函数的预期主数据包和从属响应。

 

嵌入式

int ssi_clear_adrs(void) 函数ssi_clear_adrs构建适当的 SSI 有效负载以发送 CLEAR_ADRS (0xA0)

master 命令,然后调用函数 ssi_send_packet()。该函数要么返回从设备响应,要么返回 -1 以指示故障。图 7 显示了调用 ssi_clear_adrs 函数的预期主数据包和从属响应。

 

嵌入式

无符号字符 x ssi_read_3bytes(emd_register_t ADRS) 函数 ssi_read_3bytes()

期望将寄存器的字地址作为参数读取。该函数构建适当的 SSI 有效负载来设置目标地址并从该地址读取三个字节,然后调用函数 ssi_send_packet()。该函数返回指向从属设备的响应的指针。图 8 显示了调用 ssi_read_3bytes() 函数的预期主数据包和从属响应。

 

嵌入式

int ssi_write_3bytes(emd_register_t ADRS, unsigned char x data) 函数 ssi_write_3bytes()

期望写入寄存器的字地址和指向要写入的数据的指针作为其参数。该函数构建适当的 SSI 有效负载以设置目标地址并将三个字节写入该地址,然后调用函数 ssi_send_packet()。该函数返回从设备响应或 -1 以指示故障。图 9 显示了调用 ssi_write_3bytes() 函数的预期主数据包和从属响应。

 

嵌入式

无符号字符 x ssi_read_Nbytes(emd_register_t ADRS, 无符号字符 n_bytes) 函数 ssi_read_Nbytes()

期望读取第一个寄存器的字地址和请求的字节数。该函数构建适当的 SSI 有效负载来设置目标地址并从该地址读取 N 个字节,然后调用函数 ssi_send_packet()。该函数返回指向从属设备的响应的指针。图 10 显示了调用函数 ssi_read_Nbytes() 的预期主数据包和从属响应。

 

嵌入式

int ssi_write_Nbytes(emd_register_t ADRS, 无符号字符 x 数据, 无符号字符 n_bytes) 函数 ssi_write_Nbytes()

期望写入寄存器的起始地址、指向要写入的数据的指针以及要写入的字节数作为其参数。该函数构建适当的 SSI 有效负载以设置目标地址并从给定地址开始写入 N 个字节,然后调用函数 ssi_send_packet()。该函数返回从设备响应或 -1 以指示故障。图 11 显示了调用 ssi_write_Nbytes() 函数的预期主数据包和从属响应。

 

嵌入式

maxim_em_device.h

头文件 maxim_em_device.h 为那些可能在其应用程序中使用部分或全部器件的开发人员提供了一种定义应用中使用的模拟 EMD 的便捷方法。该文件仅具有可以注释或取消注释的#defines,具体取决于所使用的设备。

78M6610_LMU.h, 78M6610_PSU.h, MAX78630_PPM.h

头文件 78M6610_LMU.h、78M6610_PSU.h 和 MAX78630_PPM.h 通过使用枚举类型emd_register_t使用户应用程序代码可读,为正在使用的嵌入式测量设备的寄存器提供别名。此外,还提供用于设备寄存器的位掩码。

HW.C 和 HW.H

文件 hw.c 提供了函数 ssi_tx_byte() 和 ssi_rx_byte()。这是用户实现其硬件特定函数调用的适当文件。可以使用的功能init_hardware()由用户自行决定删除;它仅为方便起见而提供。

结论

ADI公司EMD的简单串行接口顾名思义:简单。本应用笔记和随附的源代码旨在阐明协议,并在尽可能短的开发时间内启动并运行应用。

审核编辑:郭婷

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

全部0条评论

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

×
20
完善资料,
赚取积分