基于stm32的4G模块点灯实验

led模块功能封装

#include "led.h"
#include "sys.h"//初始化GPIO函数
void led_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//调用GPIO初始化函数gpio_initstruct.Pin  = GPIO_PIN_8 | GPIO_PIN_9;gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;gpio_initstruct.Pull = GPIO_PULLUP;//上拉gpio_initstruct.Speed= GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&gpio_initstruct);//关闭LEDled1_off();led3_off();}//点亮LED的函数void led1_on(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);}
//熄灭LED1的函数void led1_off(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);}
//翻转LED1状态的函数void led1_toggle(void)
{HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);}void led3_on(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);}
//熄灭LED1的函数void led3_off(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);}
//翻转LED1状态的函数void led3_toggle(void)
{HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);}

4G模块功能代码及指令

内网穿透

1. 内网穿透

内网穿透的原理就像在内网和外网之间搭建了一座桥梁,使得外部网络可以穿过内网的障碍,直接访问内部 的设备。

2. 花生壳配置

案例演示

 右边是通过官网的方式来连接的

4G模块

上位机配置: 1. 选择端口号(根据自己的端口选择) 2. 选择波特率(默认115200) 3. 打开串口 4. 点击进入配置,上位机会自动发送AT指令进行配置 5. 读取参数,此命令可以读取4g模块的详细信息,并打印带基本信息栏(这一步很重要,否则在第九步的 时候会出现问题) 6. 选择链路1 7. 默认是连接亿佰特的服务器 这边我们需要修改成我们自己的,具体从花生壳获取(是一串域名,或者 IP地址,他都支持,根据自己获取到的填写就可以) 8. 输入从花生壳获取的端口号 9. 点击保存配置(对应第五步,我们很多的配置需要获取到模块默认配置,保存时才会不改变) 10. 点击重启(重启后默认进入透传模式,无需在做其他操作,直接链接到串口助手上即可发送与接收信 息)

不用自己敲指令,有专门的上位机

服务端

进入AT模式后在链接2中,复制映射IP时不能复制端口,否则,外网与内容能连接但是不能通讯通过接口

重启之后就默认进入透传模式

TCPC代表端口

填入的是映射出来的地址

 4G模块可以左边能接收到,但是右边收不到

网络调试助手的TCP client打不开

解决问题1

联系快速的断连

有时候是连接的但是确实断的

解决方法

网络调试2 助手在协议类型为TCP Client打不开的情况则,需连接WiFi模块的wifi使其处在同一网段下,如果电脑连接路由器家庭WiFi则与服务器不是同一网段。

就会出现连接不了的情况

功能代码

头文件

#include "sys.h"
#include "e840.h"
#include "string.h"
#include "delay.h"
#include "stdarg.h"/* UART收发缓冲大小 */
#define E840_RX_BUF_SIZE            128
#define E840_TX_BUF_SIZE            64/* 错误代码 */
#define E840_EOK                     0      /* 没有错误 */
#define E840_ERROR                   1      /* 通用错误 */
#define E840_ETIMEOUT                2      /* 超时错误 */
#define E840_EINVAL                  3      /* 参数错误 */void e840_init(uint32_t baudrate);//所以增加新添加一个
uint16_t e840_receive_data(char *recv_data);
void e840_test(void);uint8_t e840_tx_buf[E840_TX_BUF_SIZE];
uint8_t e840_rx_buf[E840_RX_BUF_SIZE]; uint16_t e840_cnt = 0 ,e840_cntPre = 0; /* es840接收缓冲区 */UART_HandleTypeDef e840_handle;             /* esp8266句柄 */
#include "sys.h"
#include "e840.h"
#include "string.h"
#include "delay.h"
#include "stdarg.h"
uint8_t e840_tx_buf[E840_TX_BUF_SIZE];
uint8_t e840_rx_buf[E840_RX_BUF_SIZE]; uint16_t e840_cnt = 0 ,e840_cntPre = 0; /* es840接收缓冲区 */UART_HandleTypeDef e840_handle;             /* esp8266句柄 *//*** @brief       串口1初始化函数* @param       baudrate: 波特率, 根据自己需要设置波特率值* @retval      无*/
void e840_uart_init(uint32_t baudrate)//正常会有启动的流程只是作为一个串口的初始化
{/*esp8266 初始化设置*/e840_handle.Instance = USART2;                                         /* USART1 */e840_handle.Init.BaudRate = baudrate;                                  /* 波特率 */e840_handle.Init.WordLength = UART_WORDLENGTH_8B;                      /* 字长为8位数据格式 */e840_handle.Init.StopBits = UART_STOPBITS_1;                           /* 一个停止位 */e840_handle.Init.Parity = UART_PARITY_NONE;                            /* 无奇偶校验位 */e840_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;                      /* 无硬件流控 */e840_handle.Init.Mode = UART_MODE_TX_RX;                               /* 收发模式 */HAL_UART_Init(&e840_handle);                                           /* HAL_UART_Init()会使能e840 */
}/*** @brief       esp8266接收缓冲区清除* @param       无* @retval      无*/
void e840_rx_clear(void)
{memset(e840_rx_buf, 0, sizeof(e840_rx_buf));                          /* 清空接收缓冲区 */e840_cnt = 0;                                                       /* 接收计数器清零 */
}/*** @brief       串口1中断服务函数* @note        在此使用接收中断及空闲中断,实现不定长数据收发* @param       无* @retval      无*/
void USART2_IRQHandler(void)
{uint8_t receive_data = 0;   if(__HAL_UART_GET_FLAG(&e840_handle, UART_FLAG_RXNE) != RESET){        /* 获取接收RXNE标志位是否被置位 */if(e840_cnt >= sizeof(e840_rx_buf))                            /* 如果接收的字符数大于接收缓冲区大小, */e840_cnt = 0;                                               /* 则将接收计数器清零 */HAL_UART_Receive(&e840_handle, &receive_data, 1, 1000);            /* 接收一个字符 */e840_rx_buf[e840_cnt++] = receive_data;                        /* 将接收到的字符保存在接收缓冲区 */}if (__HAL_UART_GET_FLAG(&e840_handle, UART_FLAG_IDLE) != RESET)        /* 获取接收空闲中断标志位是否被置位 */{printf("recv: %s\r\n", e840_rx_buf);                               /* 将接收到的数据打印出来 */e840_rx_clear();__HAL_UART_CLEAR_IDLEFLAG(&e840_handle);                           /* 清除UART总线空闲中断 */}
}uint8_t e840_wait_receive(void)
{if(e840_cnt == 0)return E840_ERROR;if(e840_cnt == e840_cntPre){e840_cnt = 0;return E840_EOK;}e840_cntPre = e840_cnt;return E840_ERROR;
}uint8_t e840_send_command(char *cmd,char *res)//发送一个指令去   在指定时间内返回回来 否则没有接收到一个返回值
{uint8_t timeout_out = 250;e840_rx_clear(); //防止忍心内的数据影响HAL_UART_Transmit(&e840_handle,(uint8_t *)cmd,strlen(cmd),100);//发送命令 cmd在这里是一个uint8_t的数据 长度 阻塞的值//等待while(timeout_out--)//不停的等待{if(e840_wait_receive() == E840_EOK){if(strstr((const char*)e840_rx_buf, res) != NULL)//判断是否又有期待的字符串return E840_EOK;}delay_ms(10);}return E840_ERROR;//否则接收错误}//只是内部处理外部是不知道的用不了,为了便于外部能获取RX_BUF接收缓冲区内容接收到多少的数据,可以将接收到的字符,对代码进行修改
//复制一份给TX_BUF
//接收的函数通返回值传出来,这样RX_bUF就能传出来 memcpy(recv_data,)uint16_t e840_receive_data(char *recv_data)
{if(e840_wait_receive() == E840_EOK){printf("esp8266 recv: %s\r\n", e840_rx_buf);memcpy(recv_data, e840_rx_buf,strlen((const char *)e840_rx_buf));e840_rx_clear(); //清空之前一样的,清空为下一次数据做准备,用recv_data作为返回值return strlen((const char *)recv_data);}return 0;//没有接收到数据
}//发送的函数  不定长数据 参数不固定
void e840_send_data(char *fmt, ...)
{va_list ap;uint16_t len;va_start(ap,fmt);vsprintf((char *)e840_tx_buf,fmt, ap);va_end(ap);len = strlen((const char*)e840_tx_buf);HAL_UART_Transmit(&e840_handle, e840_tx_buf, len,100);//发送
}void e840_init(uint32_t baudrate)//所以增加新添加一个
{e840_uart_init(baudrate);}		//测试函数

main函数代码

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "e840.h"
#include "string.h"
int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();	/* LED初始化 */uart1_init(115200);e840_init(115200);printf("helloworld!\r\n");char recv_data[E840_RX_BUF_SIZE];//接收传入参数while(1){ e840_receive_data(recv_data);//接收到数据tcp服务器传输过来的字符串if(strstr(recv_data, "ON") != NULL)//判断字符串有ON,打开风扇					led1_on();else if(strstr(recv_data, "OFF") != NULL)led1_off();delay_ms(10);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/55866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序算法 —— 直接插入排序

目录 1.直接插入排序的思想 2.直接插入排序的实现 实现分析 实现代码 3.直接插入排序的分析 时间复杂度分析 空间复杂度分析 稳定性 1.直接插入排序的思想 直接插入排序的思想就是把待排序的元素按其关键码值的大小依次插入到一个已经排好序的有序序列中&#xff0c…

pycharm调试带参数命令行的程序

点击 run configuration 点击加号,选择python name填写程序名字,script填写程序路径,下一行填写传入的参数 点击apply,再点ok,即可debug 参考: pycharm 调试模式下命令行参数的传递_pycharm debug传参 ya…

项目实战:构建 effet.js 人脸识别交互系统的实战之路

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀构建 effet.js 📒1. 什么是effet.js📜2. 为什么需要使用effet.js📝3. effet.js的功能📚4. 使用…

【项目案例】-音乐播放器-Android前端实现-Java后端实现

精品专题: 01.C语言从不挂科到高绩点 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. SpringBoot详细教程 https://blog.csdn.ne…

HTML之表单设计

1、HTML表单 HTML表单是用于收集用户输入的信息,并将用户输入的内容信息传到后台服务器中。 表单是通过form标签实现。 特别注意:如果一些内容提交后,没有将内容提交给后台服务器,那么需要添加一个name属性,语法&am…

NC 单据模板自定义项 设置参照(自定义参照)

NC 单据模板自定义项 设置参照(自定义参照) 如图下图,NC 单据模板自定义项 设置参照: 1、选择需要设置参照的自定义字段,选择高级属性页签,在类型设置中,数据类型选择参照信息,即bd…

【热门主题】000004 案例 Vue.js组件开发

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【热…

JavaWeb合集11-Maven高级

十一、Maven高级 1、分模块设计与开发 为什么?将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享。 分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。 实现步骤&…

RabbitMQ下载与配置

安装Erlang Erlang 下载地址如下: https://erlang.org/download/otp_versions_tree.html 安装 RabbitMQ RabbitMQ 下载地址如下: https://www.rabbitmq.com/install-windows.html 查看服务,服务已经正常启动 打开Command Prompt 输入rabb…

bash之基本运算符

一.算术运算符 vim test.sh #!/bin/basha10 b20valexpr $a $b echo "a b : $val"valexpr $a - $b echo "a - b : $val"valexpr $a \* $b echo "a * b : $val"valexpr $b / $a echo "b / a : $val"valexpr $b % $a echo "b % a …

TH-OCR:强大的光学字符识别工具与车牌识别应用

在当今数字化的时代,高效准确地识别文本和图像中的字符变得至关重要。TH-OCR(清华 OCR)作为一款优秀的光学字符识别软件,以其卓越的性能和广泛的应用场景,受到了众多用户的青睐。其中,车牌识别功能更是在交…

Discuz | 全站多国语言翻译和繁体本地转换插件 特色与介绍

Discuz全站多国语言翻译和繁体本地转换插件 特色与介绍 特殊:集成了2个开源库1.多国语言翻译 来自:github.com/xnx3/translate特色:无限使用接口 免费使用2个翻译端 带有一级和二级缓存 实现秒翻译 2.简体 繁体(台湾&#xff09…

springboot项目多个数据源配置 dblink

当项目中涉及到多个数据库连接的时候该如何处理? 在对应的配置文件,配置对应的数据库情况,不过我确实没咋测试对于事务的处理我可以后续在多做测试 配置文件中配置对应的数据源 然后再使用的时候使用这个 DS(“pd_ob”)注解。 然后又长知识…

《计算机视觉》—— 基于dlib库的人检检测

文章目录 一、dlib库的安装1. 通过PyCharm的Settings安装2. 通过Anaconda安装(适用于Windows等操作系统)3. 通过命令行安装4.懒人安装 二、基于dlib库的人检测1.对图像进行人脸检测2.打开电脑摄像头,检测人脸 一、dlib库的安装 在PyCharm中&…

Vulnhub:Me-and-My-Girlfriend-1

一.环境启动/信息收集 (1)根据物理地址用nmap的主机发现功能得出IP地址 nmap -P 192.168.138.0/24 //同网段下主机发现得到IP为192.168.138.180(2)做nmap的目录扫描和端口扫描来发现其他站带以及信息 nmap -p- 192.168.138.180 …

使用CSS Flexbox创建简洁时间轴

使用CSS Flexbox创建简洁时间轴 在网页设计中,时间轴是一种常见且有效的方式来展示事件的顺序和进程。本文将介绍如何使用CSS Flexbox创建一个简洁优雅的时间轴,无需复杂的JavaScript代码。 基本HTML结构 首先,我们需要创建基本的HTML结构: html复制<div class"ti…

Ansible自动化工具

一、Ansible概述 1.1 什么是Ansible Ansible 是一个开源的自动化工具&#xff0c;用于配置管理、应用程序部署和任务自动化。它让你可以通过编写简单的 YAML 文件&#xff08;剧本&#xff0c;Playbooks&#xff09;&#xff0c;轻松管理和配置多个服务器。Ansible 的特点是无…

第十七周:机器学习笔记

第十七周周报 摘要Abstratc一、机器学习——生成式对抗网络&#xff08;Generative Adversarial Networks | GAN&#xff09;——&#xff08;中&#xff09;1. GAN 的理论介绍2. 用JS散度训练存在的问题3. WGAN 算法4. 拓展——流体 总结 摘要 本周周报主要对GAN进行了详细的…

学习笔记——交换——STP(生成树)工作原理

三、工作原理 STP的基本原理是在一个有二层环路的网络中&#xff0c;交换机通过运行STP&#xff0c;自动生成一个没有环路的网络拓扑。这个无环网络拓扑也叫做STP树(STP Tree)&#xff0c;树节点为某些交换机&#xff0c;树枝为某些链路。当网络拓扑发生变化时&#xff0c;STP…

js简单基础笔记

一 . js特点 1. Js是一门解释型语言&#xff0c;不用编译&#xff0c;而是直接执行 2. js是一门动态语言&#xff0c;其中的任何内容都是不确定的 3. 语法结构和Java&#xff0c;c都很像 4. ​ js是一门面向对象的语言 5.js严格区分大小写 二 . js使用 1…