本实验基于STM32F767制作
本实验主要目的是通过Socket网络编程方法完成通过以太网控制两个LED的亮灭的,同理可用到继电器上控制其它高电压设备。
1.首先先生成一个带有LWIP和FreeRTOS的项目,并将网络ping通,如果不会的参照我第一篇文章STM32cubeMX将STM32F767+LAN8720+LwIP+FreeRTOS的以太网实现
2.先对项目进行编译,确认项目无误后新建一个名叫socketserver.c的文件,将以下代码附到文件中,代码内容讲解我已附在代码后
#include
#include
#include
#include
#include
#include //包含需要的所有头文件,(实现socket和标准输入输出)
#include "gpio.h" //LED灯的使能
#define SERVER_PORT 50000 //配置服务器端口号,最好设为2000以后,之前的端口部分在其它通信协议中被默认使用
uint8_t data_buffer[100]; //定义接收到的数据Buff大小为100
char tcp_server_recvbuf[300]; //定义数据处理Buff大小为300(为100也无所谓,只要大于等于100就好)
static void tcp_server_thread(void *p_arg) //定义TCP服务器线程
{
struct sockaddr_in server_addr; //服务器地址
struct sockaddr_in conn_addr; //连接地址
int sock_fd; //服务器的 socked
int sock_conn; // 请求的 socked
socklen_t addr_len; // 地址长度
int err;
int length;
int num;
// int count = 0;
sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //建立一个新的socket连接
memset(&server_addr, 0, sizeof(server_addr)); //将服务器地址清空
server_addr.sin_family = AF_INET; //地址家族
server_addr.sin_addr.s_addr =htonl(INADDR_ANY); //注意转化为网络字节序
server_addr.sin_port = htons(SERVER_PORT); //使用SERVER_PORT指定为程序头设定的端口号
err = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); //建立绑定
if (err < 0) //如果绑定失败则关闭套接字
{
closesocket(sock_fd); //关闭套接字
}
err = listen(sock_fd, 1); //监听连接请求
if (err < 0) //如果监听失败则关闭套接字
{
closesocket(sock_fd); //关闭套接字
}
addr_len = sizeof(struct sockaddr_in); //将链接地址赋值给addr_len
sock_conn = accept(sock_fd, (struct sockaddr *)&conn_addr, &addr_len); //对监听到的请求进行连接,状态赋值给sock_conn
if(sock_conn<0) //状态小于0代表连接故障,此时关闭套接字
{
closesocket(sock_fd);
}
else send(sock_conn, "connect success!\n\r", 20, 0); //连接成功则发送“connect success!”给客户端
while (1)
{
memset(data_buffer, 0, sizeof(data_buffer)); //清空接收Buff
length = recv(sock_conn, (unsigned int *)data_buffer, 100, 0); //将收到的数据放到接收Buff
for(num=0;num<100;num++) //接收Buff的数据转移到数据处理Buff,防止之后数据混乱
{
tcp_server_recvbuf[num]=data_buffer[num];
}
if(tcp_server_recvbuf[2]=='L'&tcp_server_recvbuf[3]=='E'&tcp_server_recvbuf[4]=='D'&
tcp_server_recvbuf[5]=='1'&tcp_server_recvbuf[6]=='O'&tcp_server_recvbuf[7]=='N')
//判断收到的数据是否为LED1ON
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); //打开LED1
send(sock_conn, "LED1已打开\n",strlen("LED1已打开\n"), 1); //回复客户端LED1已打开
}
if(tcp_server_recvbuf[2]=='L'&tcp_server_recvbuf[3]=='E'&tcp_server_recvbuf[4]=='D'&
tcp_server_recvbuf[5]=='1'&tcp_server_recvbuf[6]=='O'&tcp_server_recvbuf[7]=='F'&tcp_server_recvbuf[8]=='F')
//判断收到的数据是否为LED1OFF
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); //关闭LED1
send(sock_conn, "LED1已关闭\n",strlen("LED1已关闭\n"), 1); //回复客户端LED1已关闭
}
/*LED0使用指令*/
if(tcp_server_recvbuf[0]=='L'&tcp_server_recvbuf[1]=='E'&tcp_server_recvbuf[2]=='D'&
tcp_server_recvbuf[3]=='0'&tcp_server_recvbuf[4]=='O'&tcp_server_recvbuf[5]=='N')
//判断收到的数据是否为LED0ON
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //打开LED0
send(sock_conn, "LED0已打开\n",strlen("LED0已打开\n"), 1); //回复客户端LED0已打开
}
if(tcp_server_recvbuf[2]=='L'&tcp_server_recvbuf[3]=='E'&tcp_server_recvbuf[4]=='D'&
tcp_server_recvbuf[5]=='0'&tcp_server_recvbuf[6]=='O'&tcp_server_recvbuf[7]=='F'&tcp_server_recvbuf[8]=='F')
//判断收到的数据是否为LED0OFF
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //关闭LED0
send(sock_conn, "LED0已关闭\n",strlen("LED0已关闭\n"), 1); //回复客户端LED0已关闭
}
}
}
void tcp_server_init(void) //TCP服务器初始化
{
sys_thread_new("tcp_server_thread", tcp_server_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO - 1);
//进入TCP服务器线程
}
将上述文件包含在生成的项目中,打开项目,文件列表中找到Application/User/freertos.c,在该文件下生成的TCP任务中写上tcp_server_init();
如图所示
编译工程之后下载到开发板,设置好PC机的IP地址等连接测试
打开网络调试助手,对STM32进行连接,连接成功会提示connect success!
输入LED0ON发送后会返回LED0已打开,
开发板如图,DS0已亮
接下来就不给大家赘述了,以上就是该实验的全部过程,感谢采纳。
本文作者为CSDN的ASWaterbenben写博不易,转载的时候请附上来源,谢谢大佬。