打印
[应用相关]

通过4g访问STM32的TCP服务器并控制两个LED的亮和灭

[复制链接]
977|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STEP1:TCP服务器的建立


标准的简易TCP服务器模型包括:
服务器的初始化;
服务器对客户端连接的接受部分;
服务器的回复部分;

平台:STM32F767开发板
需要工具:
花生壳电脑客户端
手机端的TCP(我用的是Iphone的“网络”可以在Apple Store找到)

接下来是我服务器的代码tcp_server.h
这段代码的目的就是生成一个TCP服务器后可以通过客户端连接并给服务器发送LED0ON和LED0OFF来实现STM32LED的亮和灭LED1操作方法一致

#include "debug.h"
#include "stats.h"
#include "tcp.h"
#include "gpio.h"
#include "tcp_server.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


static err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err);
static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
char tcp_server_recvbuf[300];                                                                        //接受缓存



void Tcp_Server_Init(void)                                                                        //TCP服务器的初始化
{
        struct tcp_pcb *tcp_server_pcb;

        tcp_server_pcb = tcp_new();

        tcp_bind(tcp_server_pcb, IP_ADDR_ANY, 80);

        tcp_server_pcb = tcp_listen(tcp_server_pcb);

        tcp_accept(tcp_server_pcb, tcp_server_accept);
}


static err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err)                //TCP服务器接受客户端连接
{

                                tcp_arg(pcb, mem_calloc(sizeof(struct name), 1));

        tcp_write(pcb, "connect success£¡ \n\r",strlen("connect success£¡ \n\r  "), 1);

        tcp_recv(pcb, tcp_server_recv);

        return ERR_OK;
}


static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recv_pbuf, err_t err)                                                //TCP服务器回复以及进行相应操作
{
//        struct pbuf *tcp_send_pbuf;
        struct name *name = (struct name *)arg;
//                                int i;
       
        if (tcp_recv_pbuf != NULL)
        {

                tcp_recved(pcb, tcp_recv_pbuf->tot_len);

                if (!name)
                {
                        pbuf_free(tcp_recv_pbuf);
                        return ERR_ARG;
                }
                                                                memcpy(tcp_server_recvbuf,tcp_recv_pbuf->payload,tcp_recv_pbuf->len);
                                                               
                                                                /*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]=='N')
                                                                {
                                                                HAL_GPIO_WritePin(GPIOB, DS1_Pin, GPIO_PIN_RESET);
                                                                tcp_write(pcb, "LED1已打开\n",strlen("LED1已打开\n"), 1);

                                                                }
                                                               
                                                                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[7]=='F')
                                                                {
                                                                HAL_GPIO_WritePin(GPIOB, DS1_Pin, GPIO_PIN_SET);
                                                                tcp_write(pcb, "LED1已关闭\n",strlen("LED1已关闭\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]=='N')
                                                                {
                                                                HAL_GPIO_WritePin(GPIOB, DS0_Pin, GPIO_PIN_RESET);
                                                                tcp_write(pcb, "LED0已打开\n",strlen("LED0已关闭\n"), 1);
                                                                }
                                                               
                                                                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[7]=='F')
                                                                {
                                                                HAL_GPIO_WritePin(GPIOB, DS0_Pin, GPIO_PIN_SET);
                                                                tcp_write(pcb, "LED0已关闭\n",strlen("LED0已关闭\n"), 1);
                                                                }

                                                               
                tcp_write(pcb, "\n", strlen("\n"), 1);


                pbuf_free(tcp_recv_pbuf);
        }
        else if (err == ERR_OK)
        {

                mem_free(name);
                return tcp_close(pcb);
        }

        return ERR_OK;
}


使用特权

评论回复
沙发
keaibukelian|  楼主 | 2021-7-1 17:26 | 只看该作者
以上文件中所包含的头文件tcp_server.h如下,和我一样的懒狗请照抄后保存为tcp_server.h

#ifndef TCP_SERVER_H
#define TCP_SERVER_H

#define     MAX_NAME_SIZE       32

struct name
{
        int     length;
        char    bytes[MAX_NAME_SIZE];
};

void Tcp_Server_Init(void);

#endif




在以上两个文件都存在的情况下,我们通过STM32CubeMX建立一个包含LWIP和FreeRTOS的工程后就可以吧上述两个文件放到工程里,记得要把tcp_server.h文件的路径包含在Keil工程找头文件的路径列表。


使用特权

评论回复
板凳
keaibukelian|  楼主 | 2021-7-1 17:26 | 只看该作者
编译、下载,之后我们尝试ping通我们的开发板,可以ping通之后,我们下载花生壳客户端,注册,每月6元氪金一次之后就可以开始配置了,以下是花生壳客户端的界面

使用特权

评论回复
地板
keaibukelian|  楼主 | 2021-7-1 17:26 | 只看该作者
我们点击内网穿透就能够进入网页管理穿透

使用特权

评论回复
5
keaibukelian|  楼主 | 2021-7-1 17:27 | 只看该作者
之后点击新增映射,就会出现以下设置页面

使用特权

评论回复
6
keaibukelian|  楼主 | 2021-7-1 17:27 | 只看该作者
图片我自己加的字已经说明的很清楚,IP地址在你生成的代码里写过了,下面我写一下在哪里找这几个东西
IP地址:项目文件的lwip.c,如下贴图;
端口号:我上面贴的tcp_server.h文件的第23行最后的数字;

IP_ADDRESS设置的4个数字表示你STM32的IP地址,自己设;
NETMASK_ADDRESS设置的4个数字表示你STM32的子网掩码,照着抄;
GATEWAY_ADDRESS设置的4个数字表示你STM32的网关,保证和IP地址在同一网段,也就是说只能最后一个数字不一样,偷懒的全部照抄,因为照抄你也不一定可以用啊,hhhhhhhhhhh


使用特权

评论回复
7
keaibukelian|  楼主 | 2021-7-1 17:27 | 只看该作者
言归正传,大家开发用家用的路由器时推荐用

192.168.1.30 作IP地址
255.255.255.0 作子网掩码
192.168.1.1 作网关

在学校的话你连上校园网看你本机的IP地址,根据你自己电脑的IP设置STM32的IP地址和网关

大神就当我前面几句话没写!!!!!!(大神也不会看我的博客,hhhhhhhhhhh)

点击确定后就能得到以下界面



使用特权

评论回复
8
keaibukelian|  楼主 | 2021-7-1 17:28 | 只看该作者
这个时候点诊断就可以出现4g可以访问的IP地址以及端口号了,话不多说,上图:

使用特权

评论回复
9
keaibukelian|  楼主 | 2021-7-1 17:28 | 只看该作者

知道端口号和IP地址之后保证STM32开启,网络正常、花生壳的映射开启的情况下打开手机的“网络”APP(我用的这个,其他可以用于TCP的软件都可以)话不多说,上图


使用特权

评论回复
10
keaibukelian|  楼主 | 2021-7-1 17:28 | 只看该作者
打开之后在对应位置写上刚刚你记住的地址和端口号后点连接

使用特权

评论回复
11
keaibukelian|  楼主 | 2021-7-1 17:28 | 只看该作者
出现以下回复证明连接成功

使用特权

评论回复
12
keaibukelian|  楼主 | 2021-7-1 17:28 | 只看该作者

之后再发送区输入并点击发送
“LED0ON”
引号不写,LED0ON前面写两个空格,我当时为了方便调试偷的懒,后果就是要在前面打两个空格,所以要么你们会改自己改,要么就乖乖打两个空格在前面

之后就会收到STM32回复的
“LED0已打开”
如图


使用特权

评论回复
13
keaibukelian|  楼主 | 2021-7-1 17:29 | 只看该作者

这个时候看你的STM32,就会发现它的灯亮了如图,前提是你生成工程的时候定义了你灯的引脚叫DS0和DS1
HAL_GPIO_WritePin(GPIOB, DS1_Pin, GPIO_PIN_SET);
才会工作(GPIO我不讲,做到这一步的人GPIO输出应该是要会做的)


到此为止,全部做完,谢谢大家!!!!!!!!!!


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

63

主题

4095

帖子

5

粉丝