NB-IOT开发|nbiot开发教程《三》AT指令类模组驱动-STM32实现AT指令状态机

article/2025/8/29 22:27:25
嵌入式开发中我们要时刻保持代码的高效与整洁看之前,先点赞
好习惯,要养成

一、前言

    嵌入式开发中我们要时刻保持代码的高效与整洁。在第一节中“NB-IOT开发|nbiot开发教程《一》AT指令类模组驱动解析”我们说到AT指令模组最好的驱动-状态机。本节我们就开始编写状态机。

                                                   

     目前网上可以看到的状态机如下图:

u8 NB_IoT_ack_chack(u8 *str)
{delay_ms(10);if(USART2_RX_STA!=0){USART2_RX_STA=0;if(strstr((const char*)USART2_RX_BUF,(const char*)str))//符合预期{ memset(USART2_RX_BUF,0, sizeof USART2_RX_BUF);    return 0;}else //不符合预期  { memset(USART2_RX_BUF,0, sizeof USART2_RX_BUF);    return 1;}                             	} else { memset(USART2_RX_BUF,0, sizeof USART2_RX_BUF);  //清空数组  		 return  1;}
}u8 NB_IoT_ZDFW()
{u8  x=0;cmd1: send_NB_IoT("AT+NCONFIG=AUTOCONNECT,TRUE\r\n") ;  if(!NB_IoT_ack_chack("OK"))  x++ ;else   goto cmd1;cmd2: send_NB_IoT("AT+CFUN=1\r\n") ;     if(!NB_IoT_ack_chack("OK"))  x++ ;else   goto cmd2;		cmd3: send_NB_IoT("AT+NRB\r\n") ; if(!NB_IoT_ack_chack("REBOOTING"))  x++ ;else   goto cmd3;	
}

    delay_ms(10); 对,你没有看错就是delay,死等,多么可怕的应用。而且死等10ms就一定能收到数据吗,有些模组中的指令返回时间并不是固定的,可见delay并不是很合适的使用,如果延时1s呢?????,如果此时有按键或者有屏幕刷新,1s的延时能接受吗??,显然是不能的。本次状态机拒绝使用死等!

二、代码实现

举例:

状态:

1.发送AT确认模组是否正常;2.配置模组参数;3.发送数据;(暂定三个状态)

动作:

1.发送AT确认模组是否正常->通过串口发送AT\r\n,模组正常会返回OK,模组不正常返回非OK数据或者不返回。

2.配置模组参数->通过串口发送AT+PARAM=10\r\n,模组正常会返回OK,模组不正常返回非OK数据或者不返回。

 3.发送数据->通过串口发送AT+SEND=2030559498473738292929394\r\n,模组正常会返回OK,模组不正常返回非OK数据或者不返回。

事件:

状态机进行状态切换需要事件驱动。

事件1:状态强制切换事件(event_change_state),用于将状态机强制切换到某个指定状态或者下一状态。

事件2:串口接收到完整数据包事件(event_uart_data),模组返回数据。

事件3:超时事件(event_timeout),例如发送AT后模组在1s或者指定时间内没有返回任何数据。

状态:

typedef enum
{STATE_HAL_RESET= 0x01,  /*模组复位*/STATE_AT,               /*发送AT指令测试*/STATE_SET_PARAM,        /*设置参数*/STATE_SEND_DATA,        /*发送数据*/STATE_IDEL,             /*空闲状态*/  
} nbiot_state_e;

    结合上图1中状态机我们用语言描述下AT指令。例如发送AT模组返回OK,首先这个具有两个状态,一个是当前状态,一个是下一状态;具有的动作就是发送AT,模组返回OK,两个执行动作;在实际使用时可能会存在模组不回复或者回复错误的时候,所以要尝试,尝试要记录重试次数try_cnt;发送完AT后模组要有一个反应时间,就是MCU等待时间,这个时间不确定,每条指令等待时间不一样,计做wait_time;

现在用C语言结构体描述上述文字

typedef struct 
{nbiot_state_e cur_state;    /*当前状态*/nbiot_state_e next_state;   /*下一个状态*/int  try_cnt;               /*重试次数*/int  wait_time;             /*等待时间*/int (*action1)(void);       /*动作1:发送AT*/int (*action2)(const void *arg,int len); /*动作2:判断接收到的数据是否为OK或者未接收到*/
} nbiot_fsm_state_t;

状态描述完了,还需要有一个游动指针指向当前正在执行的状态。

typedef struct
{int cur_state;  /*当前状态*/int trycnt;     /*当前状态已经重试的次数*/uint32_t init;  /*当前状态是执行action1还是执行action2*/const nbiot_fsm_state_t *fsm_state; /*当前状态是功能参数*/
} nbiot_fsm_state_index_t;
static nbiot_fsm_state_index_t nbiot_fsm_state_index;

状态中的两个执行动作C语言描述:action1->发送AT

action2:->判断接收到的数据是否为OK,如果是则执行下一状态,如果不是则等待,如果超时未收到数据就重试。

/** AT*/
static int at_action1(void)
{const char *cmd = "AT\r\n";return cola_device_write(uart_dev,0,cmd,strlen(cmd));
}
static int at_action2(const void *arg,int len)
{if(!len)return STATE_RETRY;char *pt = memmem(arg, len, "OK", strlen("OK"));if (pt) {return STATE_NEXT;}return STATE_WAIT;
}

每一个状态都写两个执行动作。

全部的状态列表:

static const nbiot_fsm_state_t nbiot_state_list[] =
{{STATE_HAL_RESET,STATE_AT,       1,  300,nbiot_reset_action1,nbiot_reset_action2},{STATE_AT,       STATE_SET_PARAM,3,  3000,at_action1,         at_action2         },{STATE_SET_PARAM,STATE_SEND_DATA,4,  3000,set_param_action1,  set_param_action2  },{STATE_SEND_DATA,STATE_IDEL,     5,  3000,send_data_action1,  send_data_action2  },{STATE_IDEL,     STATE_IDEL,     100,3000,state_idel_action1, state_idel_action2 },
};

状态写完了接下来还需要一个状态管理的函数,负责管理是执行action1还是执行action2;

状态管理函数:状态管理函数中等待模组返回数据采用的是软定时器,该方式很好的避免了死等问题。

状态和执行动作完成了,接下来就是事件,驱动状态机运行的驱动力--------事件。

事件1:状态强制切换事件

更新游动状态指针,并且给任务发送状态改变的信号cola_set_event(&nbiot_task,SIG_CHANGE_STATE);

static void nbiot_change_state(nbiot_state_e state)
{const nbiot_fsm_state_t *fsm_state = nbiot_get_state(state);if(fsm_state){nbiot_fsm_state_index.init = ACTION1;if(nbiot_fsm_state_index.cur_state != state) {nbiot_fsm_state_index.cur_state = state;nbiot_fsm_state_index.trycnt    = 0;nbiot_fsm_state_index.fsm_state = fsm_state;}cola_set_event(&nbiot_task,SIG_CHANGE_STATE);}
}

事件2:串口接收到完整数据包事件

上一节“NB-IOT开发|nbiot开发教程《二》AT指令类模组驱动-STM32串口实现接收不定长度数据”中提到的,不明白可以再看下。

串口接收到完整数据包后通知nbiot任务,cola_set_event(uart1_dev.owner,SIG_DATA);

static void uart_timer_cb(uint32_t event)
{if(uart1_dev.owner){cola_set_event(uart1_dev.owner,SIG_DATA);}
}

事件3:超时事件

static void nbiot_timer_cb(uint32_t event)
{cola_set_event(&nbiot_task,SIG_TIMEOUT);
}

三个驱动状态机运行的时间就完成了,既然这三个事件是驱动力,那么就需要在任务中管理这三个驱动事件。

事件管理

static void nbiot_task_cb(uint32_t event)
{int err = 0;if(event & SIG_CHANGE_STATE){nbiot_fsm_schedule(NULL,0);}if(event & SIG_TIMEOUT){nbiot_fsm_schedule(NULL,0);}if(event & SIG_DATA){err = cola_device_read(uart_dev,0,g_buf,sizeof(g_buf));if(err){nbiot_fsm_schedule(g_buf,err);}}
}

 

三、调试

状态机已经跑起来了,确实按照我们状态列表中编写的在跑,首先运行第一个状态硬件复位,300ms后执行AT指令发送,发送一次AT,尝试3次,而且等待时间为3000ms,如果尝试超过最大次数,则从新复位nbiot模组。如果接收到OK则执行下一个状态。

四、代码下载

        重要的就是代码下载了,不知道有木有人在看呀,等评论超100再上传吧,要不然没有动力写下去了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


http://chatgpt.dhexx.cn/article/tgsR5DAu.shtml

相关文章

基于华为云IOT平台实现多节点温度采集(STM32+NBIOT)

一、前言 当前的场景是,在高速公路上部署温度采集设备,在高速路地表安装温度检测传感器,检测当前路段的路面实际温度。一段高速路上有多个地点需要采集温度数据。 采集温度数据需要上传到云平台进行数据存储,并且通过可视化界面展示温度变化曲线,支持查询最近几天的温度信…

NB-IoT的优势是什么?

NB-IoT的优势 : • 强链接:在同一基站的情况下,NB-IoT可以比现有无线技术提供50-100倍的接入数。一个扇区能够支持10万个连接,支持低延时敏感度、超低的设备成本、低设备功耗和优化的网络架构。举例来说,受限于带宽&a…

MN316_OPEN(NBIOT)物联网模块环境搭建

因为项目的需要,这里要使用NBIOT,踩了一些坑,这里总结一下! 编译 官方给的SDK如下: 按照说明,在该目录下直接运行如下指令:".\build.bat dlvs_h0 demo"即可成功编译,但是我编译的时候不成功,报错如下: 最后发现是因为我的目录太深的原因造成的,把"MN316_Op…

stm32毕业设计 NBIOT远程通信系统

文章目录 1 简介2 NBIOT 简介2.1 NBIOT 的特点2.2 NBIOT 的优点2.3 NBIOT能做什么 NBIOT 模块使用4 实现效果5 STM32 驱动NBIOT模块6 最后 1 简介 Hi,大家好,NBIOT是近几年不比较火的远程通信模块,是物联网的重要技术,今天学长向…

NB-IoT技术实战开发 ----- NB-IoT介绍

一.1------初识NB-IoT 1、NB-IoT介绍2、 物联网技术发展2.1有线物联网2.2 无线网络网 3、为什么需要NB-IOT4、NB-IOT优势5、NB-IOT解决方案亮点和价值5.1 广覆盖5.2 低功耗5.3低成本5.4 大连接 6、NB-IOT的应用1.智能抄表2.智能停车3.宠物跟踪4.else 1、NB-IoT介绍 NB-----Na…

【物联网】LoRa vs NBIoT

LoRa (Long Range) VS NB-IoT(Narrow Band Internet of Things) LoRa和NB-IoT是什么 通常物联网设备分为三类: 无需移动性,大数据量,需较宽频段;移动性强&#xff0…

物联网协议之NBIOT

什么是NBIOT 在物联网行业目前常用的网络通信技术主要有以下这些: nbiot属于一种LTE网络,LTE网络是目前主流的通信网络,覆盖完整、技术成熟,未来大量物联网设备都需要在LTE网络中实现通讯功能。Cat.X这个值是用来衡量用户终端设…

浅谈NBIOT

一、什么是NBIOT? 1、概念 窄带物联网(Narrow Band Internet of Things, NB-IoT),NB-IoT构建于蜂窝网络,只消耗大约180KHz的带宽,使用License频段,可采取带内、保护带或独立载波等三种部署方式…

【物联网毕设基础】NBIOT 窄带物联网

文章目录 1 简介2 NBIOT简介3NB的型号介绍3.1 BC95:3.2 BC35:3.3 BC28:3.4 BC26:3.5 BC20:3.6 BC30: 4 NB物联网卡5 OpenCPU6 BC260模块详解6.1 基本性能6.2 引脚介绍6.3 模块供电 7 其他注意点8 最后 1 简介 Hi&…

NB-IoT学习笔记 —— NB-IoT介绍

一、简介 NB-IoT 是指窄带物联网(Narrow Band Internet of Things)技术,是一种低功耗广域(LPWA)网络技术标准,基于蜂窝技术,用于连接使用无线蜂窝网络的各种智能传感器和设备,聚焦于…

淘宝客解析url优惠链接获取商品ID

淘宝客解析商品链接获取PID 优惠链接都有一个e参数,提取e参数,直接解析e参数就可以获取推广链接的商品ID; 这是一个优惠推广链接:https://uland.taobao.com/coupon/edetail?ed4tkoUeRofIN%2BoQUE6FNzDiOaI9VHkxMoEVLjjyR2S%2Bki3b8ti%2Bp7j…

ANSI/CAN/UL 1973:2022 固定和运动辅助电源用电池安规要求-最新的英文2022完整版{135页}

ANSI/CAN/UL 1973:2022 Batteries for Use in Stationary andMotive Auxiliary Power Applications 固定和运动辅助电源用电池 UL1973-2022(February25,2022).pdf-其它文档类资源-CSDN下载UL1973-2022(February25,2022).pdf更多下…

java测试示例-生成ULID

ULID全称Universally Unique Lexicographically Sortable Identifier,直译就是通用唯一按字典排序的标识符,原始仓库是https://github.com/ulid/javascript,由前端开发者alizain发起,基于JavaScript语言。从项目中的commit历史来看…

scrapy_splash简单爬取淘宝页面信息

首先打开淘宝页面,搜索手机: https://uland.taobao.com/sem/tbsearch?refpidmm_26632258_3504122_32538762&clk104511dd93dde330d86022e9ce3a3dc46&keyword手机&page0 # 新建scrapy项目 scrapy startproject taobao # 进入项目目录: cd t…

淘宝API 优惠券查询接口

淘宝API 优惠券查询接口 item_search_coupon - 优惠券查询 返回值说明: 返回数据: Result Object: {“item”: [ {“pic_url”: “https://img.alicdn.com/bao/uploaded/i4/4190751820/O1CN01mohpC11PJbKKu33Gj_!!4190751820.jpg”, “num_iid”: “584401368799”, “se…

UL-1973-2022 储能电池安全标准

UL1973储能电池安全标准 UL-1973版发布于2013年2月15日,,最新更新2022年版。是全球储能电池系统的安全标准,标准主要涵盖给光伏、风能、后备电源、通信基站使用的各类储能电池,并包括对储能系统的结构评估和测试评估。UL1973-2022…

淘宝API 优惠券查询

item_search_coupon - 优惠券查询 Result Object: {“item”: [ {“pic_url”: “https://img.alicdn.com/bao/uploaded/i1/260030441/O1CN01jITAtS1F81EP8GV2T_!!0-item_pic.jpg”, “num_iid”: “562341312840”, “seller_id”: “260030441”, “title”: “预售红蜻蜓商…

Python + selenium 爬取淘宝网(销量,店铺名,价格等)

import time from selenium import webdriver from lxml import etreedef Run(keywords, numPage):# 构造无头的ChromeDriveroption webdriver.ChromeOptions()option.add_argument(headless)driver webdriver.Chrome(executable_pathD:\\Project\\Pycharm\\Driver\\chromedr…

python爬虫爬取淘宝商品并保存至mongodb数据库

使用工具介绍 python3.8 selenium(请确保你已经成功安装了谷歌驱动chromedriver) mongodb数据库 mongo-compass 谷歌浏览器 分析请求链接 打开淘宝首页的链接,https://www.taobao.com/如下: 这里以商品ipad为例,在搜索…