第二十七章 W55MH32 Interrupt示例

描述

单芯片解决方案,开启全新体验——W55MH32 高性能以太网单片机

W55MH32是WIZnet重磅推出的高性能以太网单片机,它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身,具体来说,一颗W55MH32内置高性能Arm® Cortex-M3核心,其主频最高可达216MHz;配备1024KB FLASH与96KB SRAM,满足存储与数据处理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP协议栈、内置MAC以及PHY,拥有独立的32KB以太网收发缓存,可供8个独立硬件socket使用。如此配置,真正实现了All-in-One解决方案,为开发者提供极大便利。

在封装规格上,W55MH32 提供了两种选择:QFN100和QFN68。

W55MH32L采用QFN100封装版本,尺寸为12x12mm,其资源丰富,专为各种复杂工控场景设计。它拥有66个GPIO、3个ADC、12通道DMA、17个定时器、2个I2C、5个串口、2个SPI接口(其中1个带I2S接口复用)、1个CAN、1个USB2.0以及1个SDIO接口。如此丰富的外设资源,能够轻松应对工业控制中多样化的连接需求,无论是与各类传感器、执行器的通信,还是对复杂工业协议的支持,都能游刃有余,成为复杂工控领域的理想选择。 同系列还有QFN68封装的W55MH32Q版本,该版本体积更小,仅为8x8mm,成本低,适合集成度高的网关模组等场景,软件使用方法一致。更多信息和资料请进入http://www.w5500.com/网站或者私信获取。

此外,本W55MH32支持硬件加密算法单元,WIZnet还推出TOE+SSL应用,涵盖TCP SSL、HTTP SSL以及 MQTT SSL等,为网络通信安全再添保障。

为助力开发者快速上手与深入开发,基于W55MH32L这颗芯片,WIZnet精心打造了配套开发板。开发板集成WIZ-Link芯片,借助一根USB C口数据线,就能轻松实现调试、下载以及串口打印日志等功能。开发板将所有外设全部引出,拓展功能也大幅提升,便于开发者全面评估芯片性能。

若您想获取芯片和开发板的更多详细信息,包括产品特性、技术参数以及价格等,欢迎访问官方网页:http://www.w5500.com/,我们期待与您共同探索W55MH32的无限可能。

单片机

第二十七章 W55MH32 Interrupt示例

本篇文章,我们将详细介绍如何在W55MH32芯片上面使用TOE中断功能,并通过实战例程,为大家讲解如何通过中断进行回环数据测试。

该例程用到的其他网络协议,请参考相关章节。有关 W55MH32 的初始化过程,请参考 Network Install 章节,这里将不再赘述。

1 TOE中断简介

在TOE中断模式下,可以设置多种中断事件,例如网络建立连接、数据接收、数据发送完成等。当某个事件发生时,通过PD9通知给处理器,处理可以立即响应中断,并进行相应的处理。这种方式可以提高系统的响应速度和效率,减少处理器在轮询状态下的资源浪费。

2 中断特点

实时性:在中断事件发生后,处理器会暂停当前正在执行的任务,立刻响应中断,当存在多个中断处理时,处理器会基于优先级进行对应处理。

提高系统效率:如果没有中断机制,处理器需要不断轮询寄存器状态,以检查是否需要进行处理,这会占用大量的处理器资源,而中断方式可以让处理器专注运行主程序,需要处理时再去处理相应的任务,提高了系统资源的利用率。

事件驱动:中断是由事件驱动的,这些事件可以是外部的(如外部设备的操作、信号变化等),也可以是内部的(如定时器溢出、计算结果异常等)

中断服务程序:每个中断源通常都有对应的中断服务程序,它们是专门为处理该中断事件而编写的一段独立的程序代码。

3 TOE中断应用场景

网络唤醒: 启用魔术包中断后,当W55MH32接收到魔术包时会触发中断,进而通知设备执行唤醒操作。

网络配置: 启用Socket接收中断后,W55MH32在接收到数据时触发中断,系统在中断触发后才进行消息读取配置,无需持续轮询,从而节省系统资源。

错误处理:当遇到错误时(例如IP地址冲突,网络不可达),W55MH32可以立即进行处理,提高系统的稳定性。

4 TOE中断源

IP冲突:在收到ARP请求时,发现发送方IP与本地IP重复时触发中断。

目标不可抵达:在接收到ICMP(目的端口不可达)包后触发中断。

PPPoE连接关闭:在PPPoE模式下,PPPoE连接断开时触发中断。

Magic Packet:当网络唤醒模式启用并通过UDP接收到Magic Packet网络唤醒包时触发中断。

以下为Socket 中断:

发送完成:成功发送数据给对方时触发中断。

超时:当ARP超时或者TCP超时时触发中断。

接收到数据:接收到对方数据时触发中断。

关闭连接:接收到对方的FIN 或 FIN/ACK包时触发中断。

建立连接:成功与对方建立连接时触发中断。

5 使用中断接收数据的流程

初始化中断引脚;

开启对应Socket的中断功能,相关寄存器及描述如下:

单片机

开启Socket RECV中断功能,相关寄存器及描述如下:

单片机

编写中断处理函数,在接收到数据时进行处理。

6 实现过程

接下来,我们看看如何在W55MH32上实现中断回环数据测试。

注意:测试实例需要PC端和W55MH32处于同一网段。

步骤1:初始化中断引脚

 

 1. void wizchip_int_init(void)
 2. {
 3.     GPIO_InitTypeDef GPIO_InitStructure;
 4.     NVIC_InitTypeDef NVIC_InitStructure;
 5.     EXTI_InitTypeDef EXTI_InitStructure;
 6.  
 7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
 8.  
 9.     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
11.     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
12.     GPIO_Init(GPIOD, &GPIO_InitStructure);
13.  
14.  
15.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource8);
16.  
17.     NVIC_InitStructure.NVIC_IRQChannel                   = EXTI9_5_IRQn;
18.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
19.     NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;
20.     NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
21.     NVIC_Init(&NVIC_InitStructure);
22.  
23.  
24.     EXTI_InitStructure.EXTI_Line    = EXTI_Line8;
25.     EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
26.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
27.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
28.     EXTI_Init(&EXTI_InitStructure);
29. }
30.  

 

步骤2:中断处理

 

 1. void EXTI9_5_IRQHandler(void)
 2. {
 3.     if (EXTI_GetITStatus(EXTI_Line8) == SET)
 4.     {
 5.         if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8) == RESET)
 6.         {
 7.             wizchip_ISR();
 8.         }
 9.     }
10.     EXTI_ClearITPendingBit(EXTI_Line8);
11. }
12.  
13.  
14. /**
15.  * @brief  Determine the interrupt type and store the value in I STATUS
16.  * @param  none
17.  * @return none
18.  */
19. void wizchip_ISR(void)
20. {
21.     uint8_t SIR_val = 0;
22.     uint8_t tmp, sn;
23.     SIR_val = getSIR();
24.     if (SIR_val != 0xff)
25.     {
26.         setSIMR(0x00);
27.         for (sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++)
28.         {
29.             tmp = 0;
30.             if (SIR_val & IR_SOCK(sn))
31.             {
32.                 tmp           = getSn_IR(sn);
33.                 I_STATUS[sn] |= tmp;
34.                 tmp          &= 0x0f;
35.                 setSn_IR(sn, tmp);
36.             }
37.         }
38.         setSIMR(0xff);
39.     }
40. }
41.  

 

在TOE成功触发中断后,会调用wizchip_ISR()函数,在这里会记录中断标志位并清空中断标志。

步骤3:开启中断功能

 

1.     setSIMR(0x01); // enable socket0 interrupt
2.     setSn_IMR(SOCKET_ID, 0x0f);//enable all interrupt functions of socket 0.
3.  

 

步骤4:主循环中运行TCP回环服务器

 

1. void loopback_tcps_interrupt(uint8_t sn, uint8_t *buf, uint16_t port)
 2. {
 3.     uint16_t len = 0;
 4.     uint8_t  destip[4];
 5.     uint16_t destport;
 6.  
 7.     if (I_STATUS[sn] == SOCK_CLOSED)
 8.     {
 9.         if (!ch_status[sn])
10.         {
11. #ifdef INTERRUPT_DEBUG
12.             printf("%d:TCP server startrn", sn);
13. #endif
14.             ch_status[sn] = ready_status;
15.  
16.             if (socket(sn, Sn_MR_TCP, port, 0x00) != sn)
17.             {
18.                 ch_status[sn] = closed_status;
19.             }
20.             else
21.             {
22. #ifdef INTERRUPT_DEBUG
23.                 printf("%d:Socket openedrn", sn);
24. #endif
25.                 listen(sn);
26. #ifdef INTERRUPT_DEBUG
27.                 printf("%d:Listen, TCP server loopback, port [%d]rn", sn, port);
28. #endif
29.             }
30.         }
31.     }
32.     if (I_STATUS[sn] & Sn_IR_CON)
33.     {
34.         getSn_DIPR(sn, destip);
35.         destport = getSn_DPORT(sn);
36. #ifdef INTERRUPT_DEBUG
37.         printf("%d:Connected - %d.%d.%d.%d : %drn", sn, destip[0], destip[1], destip[2], destip[3], destport);
38.  
39. #endif
40.         ch_status[sn]  = connected_status;
41.         I_STATUS[sn]  &= ~(Sn_IR_CON);
42.     }
43.  
44.     if (I_STATUS[sn] & Sn_IR_DISCON)
45.     {
46.         printf("%d:Socket disconnectedrn", sn);
47.         if ((getSn_RX_RSR(sn))  > 0)
48.         {
49.             if (len  > ETHERNET_BUF_MAX_SIZE)
50.             {
51.                 len = ETHERNET_BUF_MAX_SIZE;
52.             }
53.             recv(sn, buf, len);
54.             buf[len] = 0x00;
55.             printf("%d:recv data:%srn", sn, buf);
56.             I_STATUS[sn] &= ~(Sn_IR_RECV);
57.             send(sn, buf, len);
58.         }
59.         disconnect(sn);
60.         ch_status[sn]  = closed_status;
61.         I_STATUS[sn]  &= ~(Sn_IR_DISCON);
62.     }
63.  
64.     if (I_STATUS[sn] & Sn_IR_RECV)
65.     {
66.         setIMR(0x00);
67.         I_STATUS[sn] &= ~(Sn_IR_RECV);
68.         setIMR(0xff);
69.         if ((len = getSn_RX_RSR(sn))  > 0)
70.         {
71.             if (len  > ETHERNET_BUF_MAX_SIZE)
72.             {
73.                 len = ETHERNET_BUF_MAX_SIZE;
74.             }
75.             len      = recv(sn, buf, len);
76.             buf[len] = 0x00;
77.             printf("%d:recv data:%srn", sn, buf);
78.             send(sn, buf, len);
79.         }
80.     }
81.  
82.     if (I_STATUS[sn] & Sn_IR_SENDOK)
83.     {
84.         I_STATUS[sn] &= ~(Sn_IR_SENDOK);
85.     }
86. }

 

进入函数后,首先检查Socket状态。如果Socket处于关闭状态,则启动一个TCP服务器。接着,根据记录的中断标志位判断是否触发了中断,并根据中断类型进行相应的处理。

7 运行结果

烧录例程运行后,首先可以看到进行了PHY链路检测,然后打印了设置的网络地址信息,接着是TCP中断回环测试,W55MH32接收到Socket数据后触发中断并进行回传。如下图所示:

单片机

8 总结

本文讲解了如何在 W55MH32 芯片上使用 TOE 中断功能并进行回环数据测试,通过实战例程展示了从初始化中断引脚、处理中断、开启中断功能到在主循环中运行 TCP 回环服务器的完整过程。文章详细介绍了 TOE 中断的概念、特点、应用场景、中断源以及使用中断接收数据的流程,帮助读者理解其在提升系统响应速度和资源利用率方面的实际应用价值。

下一篇文章将讲解在 W55MH32 芯片上实现以太网测速功能,解析其核心原理及在网络性能评估中的应用,同时通过实战例程讲解如何借助 Jperf 工具进行测速,敬请期待!

WIZnet 是一家无晶圆厂半导体公司,成立于 1998 年。产品包括互联网处理器 iMCU™,它采用 TOE(TCP/IP 卸载引擎)技术,基于独特的专利全硬连线 TCP/IP。iMCU™ 面向各种应用中的嵌入式互联网设备。

WIZnet 在全球拥有 70 多家分销商,在香港、韩国、美国设有办事处,提供技术支持和产品营销。

香港办事处管理的区域包括:澳大利亚、印度、土耳其、亚洲(韩国和日本除外)。

SF 

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

全部0条评论

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

×
20
完善资料,
赚取积分