因实际使用需求我们测试一下网络通讯,在NUCLEO-F412ZG测试板上没有以太网部分,我们选择外接一个W5500的实验板。W5500支持SPI接口通讯,DC3.3V供源。而NUCLEO-F412ZG测试板已经将SPI1的各引脚SPI1_NSS(CN7_17)、SPI1_SCK(CN7_10)、SPI1_MISO(CN7_12)、SPI1_MOSI(CN7_14)引出到CN7,3.3VDC和GND也引导了CN8,可以方便的实现测试。如下图红框所示:

1、测试的准备工作

为了实现以太网通讯首先需要下载W5500的驱动源码,可以到WIZnet的官网下载:http://www.iwiznet.cn/

目前最新版本为V1.1,我选用的是V1.03下载下来的压缩包解压后如下图:

需要将ethernet文件夹拷贝到我们的项目目录中:

并在IAR的项目下添加相关的文件和路径,主要是socket.c、w5500.c、wizchip_.conf.c三个文件。这三个文件分别实现socket、硬件驱动及相关通讯配置功能,具体可以查看相应的源码级手册。

2、编写测试代码

在完成以上工作后就可以开始真正地移植工作了。具体步骤如下:

  • 硬件配置及初始化。
  • 以太网通讯配置的初始化。
  • 实现具体的通讯过程。

2.1、硬件的配置及初始化

由于W5500通过SPI接口与STM32通讯,所以硬件配置和初始化是非常简单的,与W5500实际上没有关系,使一些通用的操作。事实上就是STM32F412ZG的SPI接口初始化的过程,需要实现RCC、GPIO以及SPI的初始化就可以了。关于这部分可以查看ST的例程。

2.2、以太网通讯配置的初始化

以太网通讯配置的初始化主要有三个方面的内容:

  • 注册TCP通讯相关的回调函数  RegisterFunction();
  • 初始化芯片参数  ChipParametersConfiguration();
  • 初始化网络通讯参数  NetworkParameterConfiguration()

三个函数的具体实现内容如下:

//函数注册,首先,应由用户实现SPI注册回调函数来访问WIZCHIP

void RegisterFunction(void)

{

//临界区回调函数

reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);  //注册临界区函数

//片选回调函数

#if   _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_

reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);//注册SPI片选信号函数

#elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_

reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  // CS必须为低电平.

#else

#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_

#error "Unknown _WIZCHIP_IO_MODE_"

#else

reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);

#endif

#endif

//SPI的读写回调函数

reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);     //注册读写函数

}

注册函数实际上就是函数指针的调用,可参考C语言函数指针部分内容。对于以上注册的函数,SPI_WriteByte需要说明一下,无论是用可函数还是直接操作寄存器,在写完之后都需要再读一下(红色部分),否则就会在客户端出现连接TCPServer超时的报警,没明白什么原因。

//写1字节数据到SPI总线

void SPI_WriteByte(uint8_t TxData)

{

//  while((SPI2->SR&SPI_I2S_FLAG_TXE)==0);        //等待发送区空

//  SPI2->DR=TxData;                              //发送一个byte

//  while((SPI2->SR&SPI_I2S_FLAG_RXNE)==0);       //等待接收完一个byte

//  SPI2->DR;

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);        //等待发送区空

SPI_I2S_SendData(SPI2,TxData);                                        //发送一个byte

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);        //等待接收完一个byte

SPI_I2S_ReceiveData(SPI2);                                            //返回接收的数据

}

//初始化芯片参数

void ChipParametersConfiguration(void)

{

uint8_t tmp;

uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};

//WIZCHIP SOCKET缓存区初始化

if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){

//printf("WIZCHIP Initialized fail.\r\n");

while(1);

}

//PHY物理层连接状态检查

do{

if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){

//printf("Unknown PHY Link stauts.\r\n");

}

}while(tmp == PHY_LINK_OFF);

}

以上实现网络物理层的配置。

//初始化WIZCHIP中的网络参数信息

void NetworkParameterConfiguration(void)

{

uint8_t tmpstr[6];

ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);

ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);

ctlwizchip(CW_GET_ID,(void*)tmpstr);

}

其中gWIZNETINFO是一个wiz_NetInfo类型的结构体变量,该结构体在wizchip_conf.h中定义,用于设置mac地址、IP地址等网络参数,具体如下:

typedef struct wiz_NetInfo_t

{

uint8_t mac[6];  ///< Source Mac Address

uint8_t ip[4];   ///< Source IP Address

uint8_t sn[4];   ///< Subnet Mask

uint8_t gw[4];   ///< Gateway IP Address

uint8_t dns[4];  ///< DNS server IP Address

dhcp_mode dhcp;  ///< 1 - Static, 2 - DHCP

}wiz_NetInfo;

至此网络部分的初始化就已完成。

2.3、具体通讯过程的实现

经过前面的配置网络已经可以ping通了,下面可以实现具体的应用。对于我这个项目就是可是实现Modbus TCP的编写了。

编写TCP Server,这部分有很多资料,直接附代码:

//TCP服务器数据通讯

int32_t TCPServer(uint8_t sn, uint16_t port)

{

int32_t ret;

uint8_t socketStatus=getSn_SR(sn);

switch(socketStatus)

{

case SOCK_ESTABLISHED :

{

if(getSn_IR(sn) & Sn_IR_CON)

{

setSn_IR(sn,Sn_IR_CON);

}

uint16_t size=0;

if((size = getSn_RX_RSR(sn)) > 0)

{

if(size > DATA_BUFFER_SIZE)

{

size = DATA_BUFFER_SIZE;

}

uint8_t rxBuffer[DATA_BUFFER_SIZE];

ret = recv(sn,rxBuffer,size);

if(ret <= 0)

{

return ret;

}

//添加数据解析及响应的函数

uint8_t txBuffer[DATA_BUFFER_SIZE];

uint16_t length=ReceivedDataParsing(rxBuffer,txBuffer);

uint16_t sentsize=0;

while(length != sentsize)

{

ret = send(sn,txBuffer+sentsize,length-sentsize);

if(ret < 0)

{

close(sn);

return ret;

}

sentsize += ret; // 不用管SOCKERR_BUSY, 因为它是零.

}

}

break;

}

case SOCK_CLOSE_WAIT :

if((ret=disconnect(sn)) != SOCK_OK)

{

return ret;

}

break;

case SOCK_INIT :

if( (ret = listen(sn)) != SOCK_OK)

{

return ret;

}

break;

case SOCK_CLOSED:

if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)

{

return ret;

}

break;

default:

break;

}

return 1;

}

其中ReceivedDataParsing(rxBuffer,txBuffer)实现具体的应用协议,根据具体的需求而定,在此我们实现了简单的Modbus TCP协议。

3、测试结果

完成编写,调试无误后,将程序下载到目标板,首先既然是以太网通讯,我们就在上位机上机简单的网络测试。在目标板上我们设定的IP地址为:192.168.1.100,在CMD中使用简单的Ping命令测试如下:

由上图可以看到,网路没有问题。接下来我们用TCP&UDP测试工具进行进一步的测试,并使用Microsoft Network Monitor监视数据包。打开TCP&UDP测试工具,创建一个TCP客户端,目标IP还是目标板IP,端口用502(我们在软件中设定了)。

创建完成后,连接无误,在发送栏中以16进制发送一条指令,可以看到下方的接收栏中收到数据。

我们再看看Microsoft Network Monitor中捕获到的数据包核对一下数据是否正确。

由于我们实现了简单的Modbus TCP协议,所以我们在使用ModScan32来测试一下通讯是否正确。首先启动ModScan32,并做如下配置:

连接后数据显示出来,持续更新一段时间后没有问题。

同样,我们再看看Microsoft Network Monitor中捕获到的数据更新与ModScan32做一对比,数据包完整而且正确。

完成测试,通讯没有问题STM32F412与W5500实现以太网通讯简单方便。

STM32F412应用开发笔记之五:结合W5500实现以太网通讯的更多相关文章

  1. STM32F412应用开发笔记之十:多组分气体分析仪设计验证

    本次将NUCLEO-F412ZG应用于我们的多组分气体分析仪的实现试验,从整体上测试实际项目的应用情况. 一.项目概述 多组分气体分析仪是我公司近期研发的三个主要产品之一.采用模块化设计,可增减配置, ...

  2. STM32F412应用开发笔记之九:移植FreeRTOS到F412ZG平台

    在开发实际应用系统时,我们经常需要考虑数据的实时性和多任务,嵌入式实时操作系统的出现为实现这一目的提供了很好的助力.FreeRTOS是近年来比较流行的嵌入式实时操作系统,而且是开源免费的,STM32C ...

  3. STM32F412应用开发笔记之一:初识NUCLEO-F412ZG

    今天终于收到了期待已久的NUCLEO-F412ZG,感谢电子发烧友论坛! 近几年来基本都是在STM32平台上做一些设计开发工作.STM32F103.STM32F107.STM32F429等都应用过,但 ...

  4. STM32F412应用开发笔记之三:SPI总线通讯与AD采集

    本次我们在NUCLEO-F412ZG试验模拟量输入采集.我们的模拟量输入采用ADI公司的AD7705,是一片16位两路差分输入的AD采集芯片.具有SPI接口,我们将采用SPI接口与AD7705通讯.两 ...

  5. STM32F412应用开发笔记之二:基本GPIO控制

    NUCLEO-F412ZG板子上的元器件并没有完全焊接,除去ST-LINK部分和电源部分后,还有用一个USB主机接口,三个LED灯和两个按钮,不过很多功能引脚都已经引到了插针.查看原理图可发现,由原理 ...

  6. Modbus库开发笔记之五:Modbus RTU Slave开发

    Modbus在串行链路上分为Slave和Master,这一节我们就来开发Slave.对于Modbus RTU从站来说,需要实现的功能其实与Modbus TCP的服务器端是一样的.其操作过程也是一样的. ...

  7. STM32F412应用开发笔记之六:使用片上Flash存储参数

    我们的项目中需要保存一些系统配置参数,这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能.这就需要考虑这些参数保存的问题.将这类数据存在指定 ...

  8. STM32F412应用开发笔记之四:与远红外炭氢传感器通讯

    远红外炭氢传感器是在多组分气体传感器中用来检测甲烷和丙烷浓度的,采用单总线串行通讯,TTL电平.所以我们需要用到UART口来实现与远红外炭氢传感器的通讯. 远红外传感器就是这个样子的: 再来一张进气和 ...

  9. STM32F412应用开发笔记之八:迪文串口屏显示驱动

    迪文的显示屏使用起来比较方便,其使用串口通讯,即可支持RS232,又可以支持TTL电平.在NUCLEO-F412ZG实验板上,USART2已经引到了CN9上,我们就利用USART2来实现与迪文串口屏的 ...

随机推荐

  1. Servlet学习笔记

    在这里记录最重要的要点 1,tomcat-->conf-->server.xml里面的东西是什么?(tomcat怎么知道“谁”去处理客户端来的请求?) 最主要的是一个依赖的控制,换句话说什 ...

  2. COGS2531. [HZOI 2016]函数的美 打表+欧拉函数

    题目:http://cogs.pw/cogs/problem/problem.php?pid=2533 这道题考察打表观察规律. 发现对f的定义实际是递归式的 f(n,k) = f(0,f(n-1,k ...

  3. 【poj3071】 Football

    http://poj.org/problem?id=3071 (题目链接) 题意 ${2^n}$个队伍打淘汰赛,输的被淘汰.第1个队打第2个队,第3个队打第4个队······给出第i个队伍打赢第j个队 ...

  4. php 使用函数中遇到的坑之----strpos

    strpos — 查找字符串首次出现的位置 mixed strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) <?ph ...

  5. css 通用reset,common

    /*------------------------------------*\ $RESET \*------------------------------------*/ body, div, ...

  6. tomcat/jsp/servlet版本关系

    Servlet Spec JSP Spec EL Spec WebSocket Spec JASPIC Spec Apache Tomcat version Actual release revisi ...

  7. HTML5学习总结-番外05 移动终端适配

    一 viewport 在使用移动端设备浏览网页时,移动端浏览器是直接把整个页面放到一个虚拟的视图里来显示的,通常来说这个虚拟的视图大小会比手机屏幕大,用户可以通过手势操作来平移.缩放这个视图. 如果不 ...

  8. Généralement c'est un mélange qui me devient personnellement

    Parmi mes plus grands problèmes personnels avec maisons de rue conventionnelles est en fait ils sont ...

  9. 在webapi2中使用OWIN 自寄宿模式

    OWIN  自寄宿模式说的直白一点就是不需要IIS了,直接通过路由访问cs模式的服务 敲了一遍官方的例子,首先安装Microsoft.AspNet.WebApi.OwinSelfHost,注意不要安装 ...

  10. Forward+

    http://aras-p.info/blog/2012/03/02/2012-theory-for-forward-rendering/ http://www.slideshare.net/taka ...