单芯片解决方案,开启全新体验——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 SMTP示例
本篇文章,我们将详细介绍如何在W55MH32芯片上面实现SMTP协议。并通过实战例程,为大家讲解如何在W55MH32上使用SMTP协议给他人发送电子邮件。
该例程用到的其他网络协议,例如 DHCP和DNS,请参考相关章节。有关 W55MH32 的初始化过程,请参考 Network Install 章节,这里将不再赘述。
1 SMTP协议简介
SMTP(Simple Mail Transfer Protocol,简单邮件传输协议) 是一种用于电子邮件传输的通信协议。它是互联网标准协议之一,专门设计用于电子邮件的发送和路由。SMTP定义了邮件如何从发件人发送到收件人的电子邮件服务器,并规范了服务器之间的邮件中继操作。
2 SMTP协议特点
面向文本:SMTP协议使用纯文本命令和响应(如HELO、MAIL FROM、RCPT TO等)来进行通信,邮件内容通常是以ASCII码表示。
请求-响应模式:SMTP通信是基于请求-响应模型的,客户端发送请求,服务器根据请求返回响应。
基于TCP:SMTP依赖于TCP协议来提供可靠的数据传输服务。SMTP会通过TCP建立连接并发送邮件。
广泛兼容性:SMTP 是国际标准邮件传输协议,广泛应用于邮件系统,确保不同系统间高效互通。
高效性与可靠性:SMTP 协议简单易用,支持错误处理和重试机制。邮件无法发送时,可暂存队列并重试,确保传输可靠。
可扩展性:通过扩展SMTP协议的命令和响应码,可以支持更多的邮件传输特性和功能。
安全性:SMTP 本身不处理加密,但可结合 SSL/TLS(SMTPS)提供加密通道,保障邮件传输的安全性。
异步传输:SMTP 支持异步传输,使邮件发送和接收可在不同时间进行,提升效率并支持批量处理。
灵活性:SMTP 设计灵活,可配置邮件路由、优先级、大小限制等,以满足不同需求。
3 SMTP应用场景
接下来,我们了解下在W55MH32上,可以使用SMTP协议完成哪些操作及应用呢?
物联网(IoT)设备远程监控:使用W55MH32实现SMTP通信,收集传感器数据,并发送定期报告或警报邮件。
环境监测系统:W55MH32通过SMTP协议将监测数据(如温湿度、CO2浓度等)发送到指定的邮箱,确保及时获取信息。
设备状态报告与日志记录:通过定时任务触发W55MH32每隔一段时间自动发送设备的状态报告或运行日志到管理人员邮箱。
远程故障报警与支持:结合传感器和W55MH32的邮件发送功能,可以实现自动报警,减少人工干预的需要。
工业自动化和远程监控:使用W55MH32连接到互联网,并利用SMTP协议将设备状态、报警等信息发送到指定的邮箱。
远程控制反馈:通过W55MH32接收邮件,解析邮件命令并执行相应操作,然后通过SMTP将执行结果反馈给发送者。
SMTP发送邮件流程
使用TCP协议连接SMTP服务器
发送握手消息
发送用户认证消息
设置邮件发送地址
传输邮件内容
完成邮件发送
4 STMP协议的主要命令

SMTP服务器响应状态码

、
5 实现过程
接下来,我们在W55MH32上实现SMTP邮件发送功能。
注意:因为本示例需要访问互联网,请确保 W55MH32 的配置能够访问互联网。
步骤一:SMTP发送内容初始化
发送指令定义:
char hello[50] = "HELO localhost"; // Identity command char hello_reply[] = "250 OK"; // Id successfully responded char AUTH[50] = "AUTH LOGIN"; // Authentication request char AUTH_reply[] = "334 dXNlcm5hbWU6"; // The authentication request was successfully sent char name_126[100] = "wiznethk@126.com"; // 126 Login email address char base64name_126[200]; // 126 base64 encoding of the login mailbox name char name_reply[] = "334 UGFzc3dvcmQ6"; // The login name was sent successfully char password_126[50] = "ZPURADLGRUPQLVBK"; // 126 Email login password char base64password_126[100]; // base64 123 Password for logging in to the mailbox char password_reply[] = "235 Authentication successful"; // Login successful response char from[] = "wiznethk@126.com"; // Sender email char from_reply[] = "250 Mail OK"; char to[] = "2510582273@qq.com"; // Recipient email address char to_reply[] = "250 Mail OK"; char data_init[10] = "data"; // Request data transfer char data_reply[] = "354"; // The request was successfully responded to HEAD char Cc[] = ""; // Cc to email char subject[] = "Hello!WIZnet!"; // subject char content[] = "Hello!WIZnet!"; // text part char mime_reply[] = "250 Mail OK queued as"; // The email was sent successfully char mailfrom[50] = "MAIL FROM:< >"; char rcptto[50] = "rcpt to:< >"; char mime[200] = "From:rn"; char mime1[50] = "To:rn"; char mime2[50] = "Cc:rn"; char mime3[50] = "Subject:rn"; char mime4[50] = "MIME-Version:1.0rnContent-Type:text/plainrnrn"; char mime5[50] = "rn.rn";
步骤二:发送邮件内容初始化:
mailmessage(); // Mail command information processing
mailmessage()函数内容如下:
void mailmessage(void)
{
uint16_t len_from = strlen(from);
uint16_t len_to = strlen(to);
uint16_t len_Cc = strlen(Cc);
uint16_t len_sub = strlen(subject);
strcat(hello, "rn");
strcat(AUTH, "rn");
base64encode(name_126, base64name_126);
base64encode(password_126, base64password_126);
strcat(base64name_126, "rn");
strcat(base64password_126, "rn");
str_insert(mailfrom, from, 11);
strcat(mailfrom, "rn");
str_insert(rcptto, to, 9);
strcat(rcptto, "rn");
strcat(data_init, "rn");
str_insert(mime, from, 5);
str_insert(mime1, to, 3);
str_insert(mime2, Cc, 3);
str_insert(mime3, subject, 8);
str_insert(mime5, content, 0);
strcat(mime, mime1);
strcat(mime, mime2);
strcat(mime, mime3);
strcat(mime, mime4);
strcat(mime, mime5);
}
步骤三:使用DNS协议解析SMTP服务器地址
if (do_dns(ethernet_buf, smtp_server_name, smtp_server_ip))
{
while (1)
{
}
}
步骤四:SMTP发送邮件操作
while (1)
{
do_smtp(SOCKET_ID, ethernet_buf, smtp_server_ip); // smtp run
}
do_smtp()函数内容如下:
void do_smtp(uint8_t sn, uint8_t *buf, uint8_t *smtp_server_ip)
{
volatile uint8_t ret;
uint32_t len = 0;
uint16_t anyport = 5000;
uint8_t Smtp_PORT = 25;
memset(buf, 0, ETHERNET_MAX_BUF_SIZE);
switch (getSn_SR(sn))
{
case SOCK_INIT:
ret = connect(sn, smtp_server_ip, Smtp_PORT);
break;
case SOCK_ESTABLISHED:
if (getSn_IR(sn) & Sn_IR_CON)
{
setSn_IR(sn, Sn_IR_CON);
}
while (!Mail_Send_OK)
{
len = getSn_RX_RSR(sn);
if (len > 0)
{
memset(buf, 0, ETHERNET_MAX_BUF_SIZE);
len = recv(sn, (uint8_t *)buf, len);
send_mail(sn, buf, smtp_server_ip);
}
}
disconnect(sn);
break;
case SOCK_CLOSE_WAIT:
if ((len = getSn_RX_RSR(sn)) > 0)
{
while (!Mail_Send_OK)
{
len = recv(sn, (uint8_t *)buf, len);
send_mail(sn, buf, smtp_server_ip);
}
}
disconnect(sn);
break;
case SOCK_CLOSED:
socket(sn, Sn_MR_TCP, anyport++, 0x00);
break;
default:
break;
}
if (Mail_Send_OK)
{
while (1)
{
}
}
}
在该函数中,程序会执行一个 TCP Client 模式的状态机,详细讲解请参考TCP Client章节,这里不再赘述。当程序处于 SOCK_ESTABLISHED (即成功连接上SMTP服务器)状态时,SMTP服务器会主动发送一条消息给W55MH32,当接收到这条消息后,进入send_mail()函数进行SMTP发送邮件流程:
send_mail()函数内容如下:
void send_mail(uint8_t sn, uint8_t *buf, uint8_t *smtp_server_ip)
{
volatile uint8_t ret;
switch (SMTP_STATE)
{
case waitfor220:
if (strstr((const char *)buf, "220") != NULL)
{
ret = send(sn, (uint8_t *)hello, strlen(hello));
SMTP_STATE = waitforHELO250;
}
else
{
printf("Connected failed!rn");
}
break;
case waitforHELO250:
if (strstr((const char *)buf, hello_reply) != NULL && strstr((const char *)buf, "Mail") == NULL)
{
ret = send(sn, (uint8_t *)AUTH, strlen(AUTH));
SMTP_STATE = waitforAUTH334;
}
else
{
printf("smtp handshake failed!rn");
}
break;
case waitforAUTH334:
if (strstr((const char *)buf, AUTH_reply) != NULL)
{
ret = send(sn, (uint8_t *)base64name_126, strlen(base64name_126));
SMTP_STATE = waitforuser334;
}
else
{
printf("AUTH authentication request failed!rn");
}
break;
case waitforuser334:
if (strstr((const char *)buf, name_reply) != NULL)
{
ret = send(sn, (uint8_t *)base64password_126, strlen(base64password_126));
SMTP_STATE = waitforpassword235;
}
else
{
printf("username send failed!rn");
}
break;
case waitforpassword235:
if (strstr((const char *)buf, password_reply) != NULL)
{
ret = send(sn, (uint8_t *)mailfrom, strlen(mailfrom));
SMTP_STATE = waitforsend250;
}
else
{
printf("password error!rn");
}
break;
case waitforsend250:
if (strstr((const char *)buf, from_reply) != NULL && strstr((const char *)buf, "queued as") == NULL)
{
ret = send(sn, (uint8_t *)rcptto, strlen(rcptto));
SMTP_STATE = waitforrcpt250;
}
else
{
printf("Send email failed to set up!rn");
}
break;
case waitforrcpt250:
if (strstr((const char *)buf, to_reply) != NULL)
{
ret = send(sn, (uint8_t *)data_init, strlen(data_init));
SMTP_STATE = waitfordate354;
}
else
{
printf("Failed to set the receiving mailbox!rn");
}
break;
case waitfordate354:
if (strstr((const char *)buf, data_reply) != NULL)
{
ret = send(sn, (uint8_t *)mime, strlen(mime));
SMTP_STATE = waitformime250;
}
else
{
printf("Failed to send content setuprn");
}
break;
case waitformime250:
if (strstr((const char *)buf, mime_reply) != NULL)
{
Mail_Send_OK = 1;
printf("mail send OKrn");
}
break;
default:
break;
}
}
send_mail()中,会执行一个发送邮件的状态机,流程如下图所示:

1.SMTP握手:发送 HELO命令,等待服务器返回 250 OK 响应码,确认握手成功。
2.用户认证:
(1) 请求认证:发送 AUTH LOGIN 命令,表明客户端需要认证,等待服务器返回 334 ,请求用户名。
(2) 提交用户名:发送经过Base64编码的用户名(如:base64name_126),等待服务器返回 334 ,请求密码。
(3) 提交密码:发送经过Base64编码的密码(如:base64password_126),等待服务器返回 235 ,确认认证成功。
3. 设置邮件发送地址:
(1) 设置发件人:发送 MAIL FROM:<发件人邮箱>,等待服务器返回 250 ,确认发件人地址成功设置。
(2) 设置收件人:发送 RCPT TO:<收件人邮箱>,等待服务器返回 250,确认收件人地址成功设置。
4. 传输邮件内容:
(1) 请求数据传输:发送 DATA 命令,表明开始传输邮件数据,等待服务器返回 354,表示已准备接收数据。
(2) 发送邮件数据:按以下格式发送邮件数据:
发件人信息:From:
收件人信息:To:
抄送信息:Cc:
邮件主题:Subject:
邮件内容:实际的文本部分
数据结束用 rn.rn 表示
等待服务器返回 250 ,确认邮件内容已成功排队
5. 完成邮件发送:
如果服务器返回 250 ,标志邮件成功发送。
设置 Mail_Send_OK = 1,并打印提示信息 mail send OK
6 运行结果
烧录例程运行后,首先进行了PHY链路检测,接着是通过DHCP获取网络地址信息,然后是通过DNS解析SMTP服务器域名,最后是进行邮件发送,如下图所示:

可以在设置接收邮件的账号中查找接收到的邮件:

通过wireshark抓包查看,流程与send_mail()函数一致。

7 总结
本文讲解了如何在 W55MH32 芯片上实现 SMTP 协议,通过实例详细展示了在该芯片上使用 SMTP 协议发送电子邮件的实现流程,包括 SMTP 发送内容初始化、使用 DNS 协议解析 SMTP 服务器地址、SMTP 发送邮件操作等核心步骤。文章还对 SMTP 协议的简介、特点、应用场景,以及主要命令和服务器响应状态码进行了分析,帮助读者理解其在邮件传输中的实际应用价值。
下一篇文章将介绍NetBIOS的原理及在网络通信中的应用,同时讲解如何在W55MH32芯片上实现NetBIOS功能,敬请期待!
WIZnet 是一家无晶圆厂半导体公司,成立于 1998 年。产品包括互联网处理器 iMCU™,它采用 TOE(TCP/IP 卸载引擎)技术,基于独特的专利全硬连线 TCP/IP。iMCU™ 面向各种应用中的嵌入式互联网设备。
WIZnet 在全球拥有 70 多家分销商,在香港、韩国、美国设有办事处,提供技术支持和产品营销。
香港办事处管理的区域包括:澳大利亚、印度、土耳其、亚洲(韩国和日本除外)。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !