船用嵌入式保护装置通信接口设计
2024-03-15张维佳
周 鑫,张维佳
(武汉船用电力推进装置研究所,武汉 430064)
0 引言
随着嵌入式设备的快速发展,网络技术的应用广泛。以太网接口以其传输速度快,效率高,实时性好等特点广泛运用于各嵌入式系统中,是信息传递的重要组成部分。在船用综合保护装置中,多采用以太网MODBUS/TCP 通信,经常出现一对多进行通讯,本文采取嵌入式多个网口,可以很好的解决这一问题。通过以ARM 内核的STM32F103zet6 单片机作为系统控制核心部分,dm9000c 作为网卡用于接收数据和发送数据,通过软件编程,实现下位机与上位机之间的TCP 协议网络通信。
1 芯片介绍
STM32F103 采是由STM 公司生产的32 位FLASH 存储器单片机,采用的是ARM Cortex-M3内核的增强型芯片。其最高工作频率为72MHZ,内部数据路径和寄存器都是32 位。具有高功能、低功耗、方便开发。以太网接口是一个重要的外设,通过双绞线进行数据传输,传输速度最快可达到100 MBPS 或1GBPS。
DM9000C,一个10/100M 自适应的PHY 和4K DWORD 值的SRAM 。
DM9000C 是一款完全集成的、性价比高、引脚数少、带有通用处理器接口的单芯片快速以太网控制器,并且DM9000C 属于并口网卡。通过采用STM32 的FSMC 接口来驱动DM9000C。该DM9000C 适用于提供支持8 位,16 位和32 位数据接口访问内部存储器,以支持不同的处理器。dm9000c 的特性可以自适应10、100M 收发器,内置16K 字节的SRAM,支持硬件帧校验,并且dm9000c 存在多种型号,有100 引脚,48 引脚。可以适用于不同型号的单片机芯片。
2 系统设计
2.1 系统总体框架
本项目采取通过STM32F103zet6 单片机同时控制2 个DM9000C 网卡芯片,连接两个客户端,实现同时进行数据传输。
首先在main 函数中对DM9000C 进行初始化,并设置好中断优先级,再将发送的数据以TCP/IP帧格式进行封包处理,然后将数据通过FSMC 写入SRAM 中,之后DM9000C 通过软件编程实现的TCP 通信协议将数据从网口发送给上位机。两个网口都是通过上述方法实现数据发送,且不会发生冲突。
STM32F103zet6 单片机通过接受中断来接受发送过来的数据。DM9000C 先将远程数据接收后,放入缓存当中,同时给单片机发送中断信号,单片机接到中断信号后,就会开始执行程序代码从FSMC 中将DM9000C 缓冲中的数据读取出来,进行相应的逻辑解析得到数据。这里要注意的是,两个网口存放数据的地址是不一样的,从DM9000C 中得到的数据要分别存放到不同缓存区,并且如果是两个DM9000C 传输,会产生两个接收数据中断信号,这时要设置不同的中断优先级,来区分数据处理的先后顺序,以免中断被另一中断打断。
通过将DM9000C 的片选信号CS与单片机的NE2 相连,当FSMC_NE2 发送低电平信号时,此时运行当前DM9000C 芯片,注意的是另一个DM9000C 片选信号链接单片机的 NE1。DM9000C 的读写信号RD 与WR 分别与单片机的NEW 和NOE 相连,另一个DM9000C 的链接方式一样。
CMD 信号决定单片机是收发命令还是数据,当为1 时,就是控制DM9000C 进行写数据操作,当为0 时,就是控制DM9000C 进行写命令操作。
2.2 软件接口设计
首先在程序中将DM9000c 初始化:设置好接收中断函数,以及中断优先级。
并且分别定义 DM9000c 网卡芯片接在FSMC 的数据地址。
#define DM9000_DATE_BASE 0x60000002
这是其中一个数据地址;#define DM9000_DATE_BASE2 0x64000002
这是另一个数据地址,然后将接收到的数据存入到不同的缓存区。
这样数据都已经写入到了缓存当中,同理另一个网口接收数据。之后将接收的数据按相应的逻辑处理即可。
将已经处理好的数据,通过前面定义好的地址发送出去
由于定义的地址不同,所以两个网口的数据并不会互相冲突。
2.2 驱动DM9000C 读写寄存器
图2 DM9000c 读时序
图3 DM9000c 写时序
想要实现读写寄存器,就必须先控制好CMD引脚。
先分别定义好两个dm9000c 芯片的基地址,这里举其中一个来说明。
需要注意的是读dm9000 里面的数据时,需要判断数据的长度和dm9000 读取数据时的状态是否正常,这里可以根据需要做相应逻辑上的异常处理。
在dm9000c 中,还有一些PHY 寄存器,PHY寄存器的地址空间为5 位。对这些寄存器的操作会影响网卡芯片的初始化和网络连接。一般不对它进行操作,一般PHY 寄存器采用分页技术,基本上所有的PHY 芯片扩展都采用这种类似方案
至此,我们已经写好了两个最基本的函数: int dm9000_tx()和structpbuf *dm9000_rx()。
3 网络模块软件设计
3.1 数据包的发送
dm9000c 将SRAM 作为缓存区用来接收和发送数据,其中发送数据的缓存区大小为3KB。数据包以结构体的形式发送到输出数据缓存区内。我们可以将这个结构体理解成为一个链表,这样传输数据的效率将会更高。
我们将playload 作为一个指针指向这个结构体起始的位置。用len 表示数据的长度。
Stm32 在发送数据之前通常会关闭dm9000网卡中断,然后将数据写到SRAM 中,每次只写一个字的数据,并判断其长度。随后设置好发送寄存器,然后将SRAM 里的数据发送出去。这时如果缓存区里的数据没有了,则表示已经发送完成。之后再次将指针指向起始的位置。如果发送不成功则直接返回结束,并清除中断标记。详细的流程图如下:
由于是多个以太网口,需要注意的是发送数据的地址是不一样的。
3.2 数据包的接收
dm9000 接收数据的方式是通过中断的形式接收的。接收数据之前会将中断标志清零并产生一个互斥变量锁住dm9000c,避免这时处理其他信息导致处理信息紊乱。当接收到的数据通过crc16 校验后,会产生一个中断信号,这个时候stm32 就可以在接收中断发生时,接收数据包并读取数据包的长度,随后按照TCP 协议将其进行解析,具体的流程图如下:
图4 数据包发送流程图
图5 数据包接收流程图
要注意的是,接收数据时扩开内存空间时,要选用2 个不同的内存空间,以免照成2 个网口接收数据紊乱,数据被互相覆盖。并且判断数据长度时如果小于64 或者大于设定的数据最大长度时,要将数据丢除。
4 TCP 通信实验
通过STM32 对数据包进行封包和解析后。再通过dm9000c 进行数据传输。采用tcp 通信进行实验验证:
将STM32 作为服务器,将PC 端作为客户端,将PC 端地址设为192.168.1.102,将服务器的2个网口芯片的IP 地址分别设为192.168.1.100;192.168.1.101。分别在PC 端ping 这两个IP 地址,发现丢包率为0。实验结果表明,设计的以太网接口的可靠性高,传输速度快,丢包率低。为嵌入式设备通讯提供了有效的方案。
5 结束语
本文章介绍了,dm9000c 与stm32 单片机的硬件接口方案以及软件接口方案和数据收发的原理以及软件实现的流程。并通过TCP 网络通信实验验证了该设计的可行性。