打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
手把手教-单片机和w5500模块基于rt-thread中wiznet软件包的使用

一、开发环境

硬件:stm32f407野火开发板,w5500模块

软件:rt-thread操作系统,wiznet软件包,基于正点原子stm32f407的bsp包(需要根据实际修改系统时钟)

引脚连接方式:

单片机引脚:PB12,PB13,PB14,PB15PC6PB4

整个系统的连接方式:

开发板<---->路由器<---->电脑

二、软件包说明和适配

        WIZnet 软件包是 RT-Thread 基于 WIZnet 官网 ioLibrary_Driver 代码库的移植实现,目前只支持 W5500 设备。该软件包在原代码库功能的基础上,对接 RT-Thread SAL 套接字抽象层,实现对标准 BSD Socket APIs 的支持,完美的兼容多种软件包和网络功能实现,提高 WIZnet 设备兼容性。

目录结构:

依赖:

添加软件包的步骤:

①使能spi2

②添加wiznet软件包

引脚的值计算方式,例如

PA3的值=16*0+3=3;

PB4的值=16*1+4=20;

PC6的值=16*2+6=38

③spi引脚初始化

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi){ GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hspi->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE(); /**SPI1 GPIO Configuration PB3 ------> SPI1_SCK PB4 ------> SPI1_MISO PB5 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 interrupt Init */ HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); /* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */ } else if(hspi->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); //SPI2 GPIO Configuration
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */ }
}

④修改头文件,将#include <sal_low_lvl.h> 改为#include <sal.h>。因为在软件包中未找到 sal_low_lvl.h 文件。(如果使用rt-thread studio开发工具时,不用修改,因为软件包中有sal_low_lvl.h 文件.....

⑤增加stm32f4头文件,初始化中注册spi20设备。

三、socket代码

    ping 命令测试正常说明 WIZnet 设备网络连接成功,之后可以使用 SAL(套接字抽象层) 抽象出来的标准 BSD Socket APIs 进行网络开发(MQTT、HTTP、MbedTLS、NTP、Iperf 等),WIZnet 软件包支持的协议簇类型为:主协议簇为 AF_WIZ、次协议簇为 AF_INET。

测试代码-tcp client

#include <rtthread.h>#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */#include <netdb.h>#include <string.h>#include <finsh.h>#define BUFSZ   1024static const char send_data[] = 'This is TCP Client from RT-Thread.'; /* 发送用到的数据 */void tcpclient(int argc, char **argv){    int ret;    char *recv_data;    struct hostent *host;    int sock, bytes_received;    struct sockaddr_in server_addr;    const char *url;    int port;    if (argc < 3)    {        rt_kprintf('Usage: tcpclient URL PORT\n');        rt_kprintf('Like: tcpclient 192.168.12.44 5000\n');        return ;    }    url = argv[1];    port = strtoul(argv[2], 0, 10);    /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */    host = gethostbyname(url);    /* 分配用于存放接收数据的缓冲 */    recv_data = rt_malloc(BUFSZ);    if (recv_data == RT_NULL)    {        rt_kprintf('No memory\n');        return;    }    /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)    {        /* 创建socket失败 */        rt_kprintf('Socket error\n');        /* 释放接收缓冲 */        rt_free(recv_data);        return;    }    /* 初始化预连接的服务端地址 */    server_addr.sin_family = AF_INET;    server_addr.sin_port = htons(port);    server_addr.sin_addr = *((struct in_addr *)host->h_addr);    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));    /* 连接到服务端 */    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)    {        /* 连接失败 */        rt_kprintf('Connect fail!\n');        closesocket(sock);        /*释放接收缓冲 */        rt_free(recv_data);        return;    }    while (1)    {        /* 从sock连接中接收最大BUFSZ - 1字节数据 */        bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);        if (bytes_received < 0)        {            /* 接收失败,关闭这个连接 */            closesocket(sock);            rt_kprintf('\nreceived error,close the socket.\r\n');            /* 释放接收缓冲 */            rt_free(recv_data);            break;        }        else if (bytes_received == 0)        {            /* 默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 */            closesocket(sock);            rt_kprintf('\nreceived error,close the socket.\r\n');            /* 释放接收缓冲 */            rt_free(recv_data);            break;        }        /* 有接收到数据,把末端清零 */        recv_data[bytes_received] = '\0';        if (strncmp(recv_data, 'q', 1) == 0 || strncmp(recv_data, 'Q', 1) == 0)        {            /* 如果是首字母是q或Q,关闭这个连接 */            closesocket(sock);            rt_kprintf('\n got a 'q' or 'Q',close the socket.\r\n');            /* 释放接收缓冲 */            rt_free(recv_data);            break;        }        else        {            /* 在控制终端显示收到的数据 */            rt_kprintf('\nReceived data = %s ', recv_data);        }        /* 发送数据到sock连接 */        ret = send(sock, send_data, strlen(send_data), 0);        if (ret < 0)        {            /* 接收失败,关闭这个连接 */            closesocket(sock);            rt_kprintf('\nsend error,close the socket.\r\n');            rt_free(recv_data);            break;        }        else if (ret == 0)        {            /* 打印send函数返回值为0的警告信息 */            rt_kprintf('\n Send warning,send function return 0.\r\n');        }    }    return;}MSH_CMD_EXPORT(tcpclient, a tcp client sample);

四、结果测试

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
W5500问题集锦(二)
st7735s SPI驱动显示图标
嵌入式开发笔记——CPLD与MCU模拟SPI通信
软件模拟SPI接口程序代码(4种模式)
万字长文解读STM32-1
基于RT-Thread的智慧路灯案例实验分享
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服