摘要:使用小熊派开发板,以合宙的AIR724为通信模组(Cat.1),以AT指令方式,通过mqtt协议接入云服务器。

本贴使用小熊派开发板+合宙的Air724(Cat.1模组),接入自己搭建的EMQ服务器

一、实验准备

1.实验环境

  • 一块stm32开发板(推荐使用小熊派),以及数据线
  • 已经安装STM32CubeMX
  • 已经安装KeilMDK,并导入stm32开发板对应的芯片包(小熊派使用的是STM32L431RCT6)
  • 一个Cat.1模块(Uart接口,AT指令)以及杜邦线

2.目标效果

  • 通过CubeMX创建工程并配置参数
  • 通过串口2,以AT指令控制通信模组
  • Cat.1发送相应的AT指令接入云服务器
  • 通过MQTT协议,完成数据订阅、发布

二、通过CubeMX生产MDK工程

A.芯片选择

  • 打开CubeMX,进入芯片选择:

  • 选择自己的stm32芯片(即STM32L431RCT6):

B.时钟源RCC设置

  • 更改系统时钟源

系统时钟默认使用内部的高速时钟(HSI),选择使用HSE,时钟更精确

  • 设置外部时钟对应的端口

  • 配置时钟树

STM32L431RCT6系统时钟最大可以为80MHz,我们配置到最大即可

C.参数配置(对应端口设置)

1)配置USART1

使用USART,模式为异步,波特率为115200,无硬件流控制

2)配置UART2,连接Cat.1

Cat.1模组烧录有AT固件,当然合宙的也支持Luat开发,我们为了更方便学习,就是要AT指令开发

我们使用小熊派的Uart2,小熊派引出的引脚为PA2->USART_TX,PA3->USART_RX

其他选项,波特率设置为9600,其他默认即可

3)打开Uart2中断,并开启接收DMA

开启中断

打开接收DMA

最后,生成代码就OK了

D.工程设置

一些基础的设置,包括工程名、存储位置、工程环境、工程中各个文件的组成

E.生成代码

三、编写相应代码

1. 串口1输出重定向

我们知道printf是打印函数,原理是根据传入的字符串参数格式化打印输出到stdout中。我们需要让printf打印到串口之中,只需要在usart.c文件中模仿printf写一个输出函数即可

  • 在添加头文件
/* USER CODE BEGIN 0 */
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
/* USER CODE END 0 */
写输出函数
/* USER CODE BEGIN 1 */
void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...)
{ unsigned char UsartPrintfBuf[296];
va_list ap;
unsigned char *pStr = UsartPrintfBuf; va_start(ap, fmt);
vsprintf((char *)UsartPrintfBuf, fmt, ap); //格式化
va_end(ap); while(*pStr != 0)
{
USART1->TDR = *pStr++;
while((USART1->ISR & 0x40) == 0);
}
} //注意:在usart.h中添加void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...);
//使用方法:UsartPrintf(&huart1;,"hello world\r\n");
/* USER CODE END 1 */

注意:自己添加的代码,需要在begin和end之间

2.通信的主要代码

我们创建两个文件,分别是Cat1.h和Cat.c
同时,完善串口2的收发功能,加入串口回调函数保证数据的完整

a).串口回调函数

因为在进行发送AT指令后,接受的数据要进行处理;一方处理速度跟不上,因此加入一个串口回调函数

//串口回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
{
if(Usart2type.UsartRecLen>0) //证明还有未完成数据
{
memcpy(&Usart2type.Usart2RecBuffer[Usart2type.UsartRecLen],Usart2type.Usart2DMARecBuffer,Usart2type.UsartDMARecLen); //转存到待处理区域
Usart2type.UsartRecLen += Usart2type.UsartDMARecLen;
}
else
{
memcpy(Usart2type.Usart2RecBuffer,Usart2type.Usart2DMARecBuffer,Usart2type.UsartDMARecLen); //转存到待处理区域
Usart2type.UsartRecLen = Usart2type.UsartDMARecLen;
}
memset(Usart2type.Usart2DMARecBuffer, 0x00, sizeof(Usart2type.Usart2DMARecBuffer)); //先清空DMA缓冲区
Usart2type.UsartRecFlag = 1;
}
}

b).串口2空闲中断

当发送或接受完成一组数据后,进入空闲中断

函数如下

void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE) ==SET) //触发空闲中断
{
uint16_t temp = 0;
__HAL_UART_CLEAR_IDLEFLAG(&huart2); //清除串口2空闲中断标志位
HAL_UART_DMAStop(&huart2); //关闭DMA
temp = huart2.Instance->ISR; //清除SR状态寄存器 F0 ISR
temp = huart2.Instance->RDR; //读取DR数据寄存器 F0 RDR 用来清除中断
temp = hdma_usart2_rx.Instance->CNDTR; //获取DMA中未传输的数据个数
Usart2type.UsartDMARecLen = USART2_DMA_REC_SIE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
HAL_UART_RxCpltCallback(&huart2); //串口接收回调函数
}
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
HAL_UART_Receive_DMA(&huart2,Usart2type.Usart2DMARecBuffer,USART2_DMA_REC_SIE); //重新打开DMA接收 /* USER CODE END USART2_IRQn 1 */
}

C).AT指令通信流程

主要的AT指令如下

tsATCmds ATCmds[] =
{
{"AT\r\n","OK",200,NO_REC,10}, //测试 {"AT+CIMI\r\n","4600",200,NO_REC,10}, // 移动卡号 {"AT+CSQ\r\n","+CSQ",200,NO_REC,10}, //信号 {"AT+CEREG?\r\n","+CEREG: 0,1",200,NO_REC,10}, //网络 {"AT+CGATT?\r\n","+CGATT:1",200,NO_REC,10}, //驻网 {"AT+CCLK?\r\n","+CCLK",200,NO_REC,10}, //时间 {"AT+MCONFIG=0001,door,2020\r\n","OK",200,NO_REC,10}, //MQTT参数
//{"AT+MCONFIG=111,device1,123456\r\n","OK",200,NO_REC,100},
{"AT+MDISCONNECT\r\n","",200,NO_REC,5}, //断开MQTT连接 {"AT+MIPCLOSE\r\n","",200,NO_REC,5}, //断开TCP连接
{"AT+MIPSTART=123.56.117.8,1883\r\n","CONNECT OK",200,NO_REC,5}, //建立TCP连接 {"AT+MCONNECT=1,60\r\n","CONNACK OK",200,NO_REC,5}, //建立MQTT连接 {"AT+MSUB=","SUBACK",200,NO_REC,5}, //订阅主题 {"AT+MPUB=","OK",200,NO_REC,5}, //发布主题 {"AT+MQTTSTATU\r\n","+MQTTSTATU",200,NO_REC,5}, //状态
//AT+MQTTSTATU 0-离线 1-正常 2-需发送MCONNECT
{"AT+RESET\r\n","",200,NO_REC,5}//重启 };

四、编译+下载

点击编译后,0 error,0 warning

小熊派连接在电脑上,代码下载到开发板

五、连接硬件

1.将Cat.1的uart1_tx连接小熊派uart2_rx,cat.1的uart1_rx连接小熊派uart2_tx;Gnd连Gnd;

注意:一定要连接GND哦,需要共地的。

2.调试

此时,我们进行最后一次调试;将小熊派串口1用作串口打印,打开串口调试助手,查看运行状态(在每次发送指令后进行printf()打印相应信息)。

附件中包含CubeMX工程、MDK工程

下一步,打算将此设备接入华为云IoTDA,更好的完成设备管理

 

点击关注,第一时间了解华为云新鲜技术~

小熊派开发实践丨小熊派+合宙Cat.1接入云服务器的更多相关文章

  1. 开发实践丨用小熊派STM32开发板模拟自动售货机

    摘要:本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代码,通过云端开发和设备终端开发,实现终端数据在的华为云平台显示. 本文内容是讲述用小熊派开发板模拟自动售货机,基于论坛提供的工程代 ...

  2. WePY - 小程序敏捷开发实践丨掘金开发者大会

    声明:内容转载他处,如有侵权,可协商下架 本主题虽然在其它地方讲了很多次,但还是有非常多新内容.因为很多东西正在做或者想要做.本次分享主要分为以下几个部分: WePY 的介绍 WePY 的用户 上面展 ...

  3. 微信小程序开发实践

    目录 项目是否适合移植到小程序上? 概要介绍 实践得到的经验 规则 小程序不支持的 新特性 小窍门 会话管理 进阶 项目是否适合移植到小程序上? 小程序由于微信提供了一些组件,在微信中的一些体验确实不 ...

  4. 【小程序】微信小程序开发实践

    帐号相关流程 注册范围 企业 政府 媒体 其他组织 换句话讲就是不让个人开发者注册. :) 填写企业信息 不能使用和之前的公众号账户相同的邮箱,也就是说小程序是和微信公众号一个层级的. 填写公司机构信 ...

  5. $微信小程序开发实践点滴——Bmob基本REST API的python封装

    Refer:Bmob后端云REST API接口文档:http://docs.bmob.cn/data/Restful/a_faststart/doc/index.html 本文使用python对Bmo ...

  6. $微信小程序开发实践点滴——接入Bmob后端云

    Bmob后端云官网:http://www.bmob.cn/ 微信公众平台官网:https://mp.weixin.qq.com/ 微信小程序官方开发文档:https://mp.weixin.qq.co ...

  7. 微信小程序开发详解——小程序,大颠覆!

    微信小程序开发 联系 苏念 188.1414.7927  微信小程序系统开发 微信新功能开发 小程序开发 小程序怎么开发 app小程序开发 简化小程序开发 微信小程序定制 小程序制作 开发微信小程序  ...

  8. 微信小程序开发01 --- 微信小程序项目结构介绍

    一.微信小程序简单介绍: 微信官方介绍微信小程序是一个不需要下载安装就可使用(呵呵,JS代码不用下载吗?展示的UI不用下载吗?)的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用. ...

  9. 微信小程序开发实战-天气小程序

    园龄6年8个月了,还一篇文章都没写过,惭愧! 最近周末做了个天气预报小程序,在这里整理一下开发过程和注意点,给对小程序开发感兴趣的伙伴们提供点参考. 废话不多说,先上图最终效果: 下面进入正文: 第一 ...

  10. QQ小程序开发与发布小教程

    QQ小程序QQApp,和微信小程序类似,可以直接在手机QQ中直接打开,应用内应用,省去了安装手机APP,非常方便.官方的介绍:QQ小程序为QQ体系下的应用开放平台,可为不同类型的产品提供框架,并在QQ ...

随机推荐

  1. CF1676G

    题目简化和分析: 求一颗子树的黑白两数是否相等. 我们设黑 \(1\),白 \(-1\),若某一棵子树的权值为 \(0\),说明此刻的黑白个数相等,贡献加一. 从根搜索,每次将值传递给父亲,判断父亲此 ...

  2. client-go实战之九:手写一个kubernetes的controller

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<client-go实战> ...

  3. VLAN通信之单臂路由与三层交换

    VLAN之间通信 再次提及,vlan是虚拟局域网,用于分隔广播域,解决广播风暴.但是vlan之间无法直接通信.所有我们要用三层交换.单臂路由来实现vlan之间的通信. 单臂路由 使用场景:规划错误,只 ...

  4. Python自动化处理Excel数据

    需求描述:数据格式如下所示,需要分离出2023年7月1号之后的数据明细 数据核对与处理:从Excel文件中提取特定日期后的签收数据 1. 引言 在实际数据处理和分析过程中,经常会遇到需要从大量数据中提 ...

  5. 浅谈一下go语言中的slice及其一些小坑

    数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成.虽然数组元素可以被修改,但是数组长度是固定的,而且在go语言中数组的长度也是数组类型的组成部分,所以不同长度或不同 ...

  6. 信创就用国产的 Solon Java Framework,v2.6.0 发布

    先吹牛! 在 v2.6 这个新的里程碑节点,Solon 又完成了几件惊天大事(每一件,都是经历了漫长时间打磨与积累): (1)Solon Native,有了第一个开源案例:dromara/neutri ...

  7. C语言水仙花数

    #include<stdio.h> void main() { int i, j, k, n=100;//分别设置三个数和一个三位数 for(i=1;i<=9;i++) //一个一个 ...

  8. 开源推荐,灵活多变功能强大的CMDB

    一个完善的基础资源数据库是我们构建运维自动化上层应用的基础,所以构建CMDB系统成了有想法在DevOps运维自动化领域有所发展的企业离不开的重要一环,但受制于每家企业不同的内外部环境.资源配置以及管理 ...

  9. python循环语句(二)

    Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串. 知识点:for循环的语法格式如下: for iterating_var in sequence: statements(s) ...

  10. 上传代码到github和删除.git

    在本地建立目录,将想上传的代码放到该文件夹中 git init ###初始化 git add . ###将本地项目工作区的所有文件添加到暂存区 git commit -m "excu&quo ...