Nucleo生态系统的一个缺点是缺乏带有以太网连接的版本或ST官方支持的专用防护板。 共有90种不同的STM32 MCU提供以太网MAC接口(这意味着仅需一个外部以太网收发器(也称为phyter),而将MCU引入物联网世界所需的其他条件很少)。 STM32Cube(ST正式支持的HAL)还提供了对lwIP堆栈的支持。 但是,当前所有的Nucleo板都设计有不带以太网接口的MCU。 这意味着,如果没有专用的扩展板,就不可能为我们的Nucleo添加网络连接。
在Arduino世界中,官方的Ethernet Shield是为Arduino添加Internet连接性的最受欢迎的解决方案。 由于其在Arduino社区(WIZnet的W5100)中的普及,基于网络处理器的以太网防护板才变得真正流行。
在本系列的第一部分中,我将展示如何在STM32 Nucleo板上使用Arduino以太网防护板。 我将显示所有必需的硬件配置步骤。 我还将展示如何在新的STM32项目中导入WIZNet ioLibrary,以及如何配置该库以开始使用此防护板。
硬件和软件
如前所述,W5100芯片是一个联网的TCP / IP嵌入式以太网控制器,可简化向MCU添加以太网连接的过程。 W5100在单芯片中提供10/100以太网MAC,端口和完整的TCP / IP堆栈,并支持TCP,UDP,IPv4,ICMP,ARP,IGMP和PPPoE。 W5100使用16字节内部缓冲器在内部芯片存储器和MCU之间交换数据。 可以同时使用4个独立的硬件插座。 用户可以为每个套接字定义TX和RX的缓冲存储量。 提供BUS(直接和间接)和SPI(串行外设接口),以便与外部MCU轻松集成。
W5100芯片的编程过程包括以下步骤:
根据MCU和W5100规范配置SPI总线。 W5100作为SPI从设备运行,并支持最常见的模式-SPI模式0 和3。
设置MAC地址,IP地址,网络掩码和网关。正如我们将在下一篇文章中讨论的那样,W5100本身并不支持DHCP协议,但是WIZnet提供了一个使用RAW套接字实现DHCP发现协议的库。
配置用于TX和RX的内部套接字缓冲区。 用户可以决定从0K到8K独立扩展此存储器。 请注意,TX和RX的内存在所有4个插槽之间共享,并且8K是每个缓冲区的总量(TX为8K,RX为8K)。 默认配置为TX和RX缓冲区的每个套接字使用2K字节。
在我们的应用程序中配置我们需要的套接字。这意味着确定套接字的类型(TCP,UDP,IP RAW等)等等。
使用套接字发出命令,根据此状态图将套接字置于给定状态
幸运的是,我们不需要处理W5100芯片的这些低级方面。 得益于WIZNet的ioLibrary,以及一点点“胶水”,使其可以适应STM32Cube HAL,我们可以以非常简单的方式使用我们最喜欢的STM32 MCU开发物联网应用。
硬件设置
不幸的是,我们可以在STM32 Nucleo上轻松使用Arduino以太网防护板。 原因是防护板使用Arduino ICSP连接器作为SPI引脚的源(MISO,MOSI和SCK-SS映射到D10引脚),如下图所示。
Nucleo不提供该连接器。这意味着我们需要将这些引脚“重新路由”到其他引脚。查看Nucleo-F401RE的引脚排列,我们可以使用与SPI2外设相关的morpho连接器上的引脚,如下所示。
我们需要进行以下关联:
接线
我已经使用了4个连接线,如下图所示。
配置SPI接口
现在我们可以开始编写代码了。第一步是配置与PB_12…15引脚关联的SPI接口:SPI2。 我不得不说,执行此操作的更简单方法是使用STM32CubeMX工具。 它会自动生成所有必要的内容以正确配置SPI端口。 但是,CubeMX生成的代码在几个例程和源文件中都有详细说明。 因此在这里使用它是不切实际的,因为这会使本教程变得过于复杂。 我已经在main.c文件中定义了此函数:
此例程执行两件事。 首先,它可以正确配置SPI接口以与W5100芯片一起使用。 这是通过设置hspi2变量完成的,该变量的类型为SPI_HandleTypeDef。 该变量在main.c文件中定义为全局变量,因为我们将在其他例程中使用它。 其次,例程配置与SPI2接口相关的引脚:PB12至PB15。 PB13至PB15引脚被配置为备用功能(AF)引脚,因为它们将用作SPI接口。 PB12引脚是片选(CS)引脚,在上拉模式下被配置为输出引脚(防止引脚悬空时为“低”)。
配置USART
在此项目中,我们将使用与ST-Link接口关联的USART在虚拟COM端口上输出一些消息。 您可以在这里找到更多有关此的信息。 在我们可以在串行上打印消息之前,我们需要相应地配置USART2接口。 这项工作是通过main.c文件中定义的以下功能完成的。
正如我们对SPI接口所做的那样,我们首先需要配置USART2外设(选择的参数为:波特率115200、8位,1个停止位,无奇偶校验,无硬件流控制)。 接下来,我们需要将关联的引脚(PA2和PA3)配置为备用功能引脚。
配置库文件
WIZnet ioLibrary的设计使其可以与市场上的大多数MCU(和HAL)一起使用。 这意味着它是以抽象方式设计的,因此用户有责任提供与硬件一起使用的特定代码。 在我们的案例中,我们需要提供4个自定义函数:
在SPI传输期间选择从机芯片的函数(即,在本例中为将与CS相关的GPIO引脚拉低的功能-PB_12)。
取消选择从芯片的函数。
在SPI接口上写入1个字节的函数。
在SPI接口上读取1个字节的函数。
ioLibrary需要其他两个功能才能使用突发模式在SPI接口上进行写入/读取。 繁忙模式是现代和快速SPI器件用于一次传输字节块的模式,即无需进行X次完整传输。 突发模式可以加快MCU和SPI芯片之间的传输,特别是在MCU支持SPI DMA模式的情况下(如STM32一样)。 但是,W5100不支持此传输模式(其他W5x00芯片则支持)。 这意味着我们不需要提供其他自定义函数。
我们必须在main.c文件中定义这四个函数。
这些函数确实是不言自明的。 cs_sel()和cs_desel()只需使用HAL_GPIO_WritePin()函数将PB12引脚拉低和拉高即可。 spi_rb()函数用于使用HAL_SPI_Receive()函数在SPI接口上读取1个字节。 以相同的方式,spi_wb()在SPI上写入1个字节。
一旦定义了与定制硬件相关的函数,就必须将它们“传递”到ioLibrary。这项工作是在main()函数内部完成的。
这是main()函数的第一部分。 首先,我们需要初始化HAL,系统时钟和GPIO引脚(我省略了对MX_GPIO_Init()函数的描述,因为它仅配置了与LED LD2和用户按钮(Nucleo上的蓝色按钮)相关的引脚) ,SPI和USART。 接下来,我们使用reg_wizchip_cs_cbfunc()和reg_wizchip_spi_cbfunc()函数配置ioLibrary以使用我们的自定义函数。
构建简单App
本文完整代码
详情参阅 - 亚图跨际