11.25:完善部分Markdown注释。

This commit is contained in:
2025-11-25 16:22:58 +08:00
parent c51e6a0ca0
commit 0a950411df
4 changed files with 248 additions and 228 deletions

View File

@@ -6,39 +6,59 @@
## 项目实现: ## 项目实现:
### 一、使用FreeRTOS操作系统 ### 一、使用FreeRTOS操作系统
**优点及作用:** **优点及作用:**
可保证每个任务不会因为延迟被阻塞,大幅度减小远程操控的延迟 可保证每个任务不会因为延迟被阻塞,大幅度减小远程操控的延迟,提高系统运行的稳定性。<br>
#### 环境监测节点为例 #### 环境监测节点:
**1、创建任务** **1、创建任务**
创建了LED状态灯任务、温湿度检测任务、向网关节点传输数据、从网关节点接收数据和检测执行器指令控制LED灯五个任务。 创建了LED状态灯、温湿度检测、向网关节点传输数据、从网关节点接收数据和检测执行器指令控制LED灯五个任务。<br>
**2、创建消息队列** **2、创建消息队列**
温湿度检测任务将采集到的温湿度数据通过队列发送到传输数据任务,实现数据的保护。 温湿度检测任务将采集到的温湿度数据通过队列发送到传输数据任务,实现数据的保护。<br>
**3、创建中断触发消息队列** **3、创建中断触发消息队列**
创建串口触发消息队列当串口3接收到消息触发中断后将数据包传送到消息队列同时创建一个任务用于接收消息队列并用于后续的检测接收到的数据包是否完整、是否有相关指令。 创建串口触发消息队列当串口3接收到消息触发中断后将数据包传送到消息队列同时创建一个任务用于接收消息队列并用于后续的检测接收到的数据包是否完整、是否有相关指令。<br>
**4、创建二值信号量** **4、创建二值信号量**
创建检测LED指令消息队列调用LoRa.c中检测数据包的函数检测消息队列是否有相关的控制指令若有相关的控制指令则触发信号量在其他任务中判断该信号量是否被触发若被触发则控制LED灯开启反之关闭。 创建检测LED指令消息队列调用LoRa.c中检测数据包的函数检测消息队列是否有相关的控制指令若有相关的控制指令则触发信号量在其他任务中判断该信号量是否被触发若被触发则控制LED灯开启反之关闭。<br>
#### 网关节点:
**1、创建任务**
创建了LED状态灯、Wi-Fi初始化、向子节点传输数据、从子节点接收数据、MQTT上发、MQTT下发6个任务。<br>
### 二、自定义传输协议: ### 二、自定义传输协议:
自定义传输协议仿照了ModBus传输协议其完善性相比有欠缺但是可满足非大型项目的基本使用。在自定义传输协议中使用十六进制数字进行传输分别由网关节点和子节点这里拿子节点举例。子节点的传输协议主要分为帧头、传感器ID、传感器数据、执行器ID、执行器指令和帧尾。其中帧头也是节点ID用于声明自己是哪个节点上发的数据传感器ID用于声明自己是什么传感器传感器数据如DHT11温湿度数据执行器ID也是同理用于声明自己是什么执行器执行器指令一般是0或10为关、1为开用于在执行网关节点下发的控制指令后的返回结果告诉网关节点是开了还是关了是否成功若失败了是什么原因最后一个是帧尾为帧头倒写添加帧头和帧尾的目的是在网关接收多个节点的数据是验证其数据是否完整不会被其他上传的数据打断 自定义传输协议仿照了ModBus传输协议其完善性相比有欠缺但是可满足非大型项目的基本使用。在自定义传输协议中使用十六进制数字进行传输分别由网关节点和子节点。
**1、节点** **1、节点**<br>
*规则:*
子节点的传输协议主要分为帧头、传感器ID、传感器数据、执行器ID、执行器指令和帧尾。其中帧头也是节点ID用于声明自己是哪个节点上发的数据传感器ID用于声明自己是什么传感器传感器数据如DHT11温湿度数据执行器ID也是同理用于声明自己是什么执行器执行器指令一般是0或10为关、1为开用于在执行网关节点下发的控制指令后的返回结果告诉网关节点是开了还是关了是否成功若失败了是什么原因最后一个是帧尾为帧头倒写添加帧头和帧尾的目的是在网关接收多个节点的数据是验证其数据是否完整不会被其他上传的数据打断。<br>
*节点ID* *节点ID*
D1为子节点1D2为子节点2以此类推。 D1为子节点1D2为子节点2以此类推。<br>
*传感器ID* *传感器ID*
EA为DHT11温湿度传感器EB为MQ2烟雾浓度传感器、EC为火焰传感器、ED为光敏传感器。 EA为DHT11温湿度传感器EB为MQ2烟雾浓度传感器、EC为火焰传感器、ED为光敏传感器。<br>
*传感器数据:* *传感器数据:*
如17、3517为温度数据、35为湿度数据将其转化为10进制分别为23℃、湿度53%。 如17、3517为温度数据、35为湿度数据将其转化为10进制分别为23℃、湿度53%。<br>
*执行器ID* *执行器ID*
FA为LED灯、FB为小风扇、FC为加湿器、FD为蜂鸣器、FE为舵机 FA为LED灯、FB为小风扇、FC为加湿器、FD为蜂鸣器、FE为舵机、FF为加热片。<br>
*执行器数据* *执行器指令*
0为关、1为开。 0为关、1为开。<br>
*帧尾:* *帧尾:*
D1倒过来就是1D以此类推。 D1倒过来就是1D以此类推。<br>
| 目标地址 | 目标信道 | 帧头也是节点ID | 传感器ID | 传感器数据 | 执行器ID | 执行器数据 | 帧尾(为帧头倒写) | | 目标地址 | 目标信道 | 帧头也是节点ID | 传感器ID | 传感器数据 | 执行器ID | 执行器指令 | 帧尾(为帧头倒写) |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| 03 E9 | 17 | D1 | EA | 17 35 | FA | 01 | 1D | | 03 E9 | 17 | D1 | EA | 17 35 | FA | 01 | 1D |
**2、网关**
*规则:*
网关的传输协议主要分为帧头、执行器ID、执行器指令和帧尾。其中帧头也是节点ID用于声明控制的是哪个节点的设备执行器ID同理一般是0或1用于声明控制的是哪个设备执行器指令用于声明执行器是开还是关最后一个是帧尾为帧头倒写。
*节点ID、执行器ID与上面相同。*
*执行器指令:*
一共有两种一种是常规的0和1另外一种是温控模式用于控制温度范围若超过这个范围就会触发执行器的指令。温控模式默认常开控制字为02后面跟的是温控的数据也就是限定的温湿度数值如17 20 35 50就是温度在23~26度之间湿度在53%~80%之间。。
*常规模式*
| 目标地址 | 目标信道 | 帧头也是节点ID| 执行器ID | 执行器指令 | 帧尾(为帧头倒写) |
| :---: | :---: | :---: | :---: | :---: | :---: |
| 03 E9 | 17 | D1 | FA | 01 | 1D |
*温控模式*
| 目标地址 | 目标信道 | 帧头也是节点ID| 执行器ID | 执行器指令 | 温控模式02 | 温控数据 | 帧尾(为帧头倒写) |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| 03 E9 | 17 | D1 | FA | 01 | 02 | 17 20 35 50 | 1D |
## 本系统在FreeRTOS中引用的api ## 本系统在FreeRTOS中引用的api
### 一、多任务创建与运行 ### 一、多任务创建与运行
**1、概念** **1、概念**
通过定义任务句柄、名称、优先级从而实现多任务同时在单核的单片机中以并发或抢占的形式运行。在FreeRTOS中时钟源频率通常被设定为1kHz(#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ))时间片1tick也就是1ms。在任务优先级相同的情况下多个任务按照一个时间片切换运行也就是轮询式调度当其中一个任务的优先级较高时数值较高该任务会打断其他任务的运行也就是抢占式调度。在创建任务后会产生任务控制块简称TCBTCB在切换任务的时候会将创建任务的指针保存到创建的栈里也就是保存任务现场直到任务切换过来后再复原现场。FreeRTOS的任务分为4个状态分别为就绪态、运行态、挂起态和阻塞态当其中一个任务遇到延时等情况会进入到阻塞态会执行其他任务知道延时结束低优先级任务被高优先级任务打断也同理。 通过定义任务句柄、名称、优先级从而实现多任务同时在单核的单片机中以并发或抢占的形式运行。在FreeRTOS中时钟源频率通常被设定为1kHz(#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ))时间片1tick也就是1ms。在任务优先级相同的情况下多个任务按照一个时间片切换运行也就是轮询式调度当其中一个任务的优先级较高时数值较高该任务会打断其他任务的运行也就是抢占式调度。在创建任务后会产生任务控制块简称TCBTCB在切换任务的时候会将创建任务的指针保存到创建的栈里也就是保存任务现场直到任务切换过来后再复原现场。FreeRTOS的任务分为4个状态分别为就绪态、运行态、挂起态和阻塞态当其中一个任务遇到延时等情况会进入到阻塞态会执行其他任务知道延时结束低优先级任务被高优先级任务打断也同理。<br>
**2、使用到的api函数** **2、使用到的api函数**
- 任务函数: - 任务函数:
```c ```c
@@ -61,7 +81,7 @@ vTaskStartScheduler();
``` ```
### 二、消息队列: ### 二、消息队列:
**1、概念** **1、概念**
在初始化消息队列函数种,有两个参数,第一个是队列的长度,也就是这个队列能存放多少个数据第二个参数就是每个数据的大小单位为字节在stm32中uint8_t指针的长度一般是4字节。在多个任务需要共用一个变量值以传递数据的时候使用消息队列可以很好地保护数据的传输不会被其他用到相关变量的任务干扰。消息队列通过发送队列和接收队列的函数将不同的任务搭建起一个传递参数的桥梁从而确保传递数据时不被其他任务干扰造成数据的误差。如DHT11接收到温湿度数据将温湿度数据传输到LoRa发送数据的任务中。 在初始化消息队列函数种,有两个参数,第一个是队列的长度,也就是这个队列能存放多少个数据第二个参数就是每个数据的大小单位为字节在stm32中uint8_t指针的长度一般是4字节。在多个任务需要共用一个变量值以传递数据的时候使用消息队列可以很好地保护数据的传输不会被其他用到相关变量的任务干扰。消息队列通过发送队列和接收队列的函数将不同的任务搭建起一个传递参数的桥梁从而确保传递数据时不被其他任务干扰造成数据的误差。如DHT11接收到温湿度数据将温湿度数据传输到LoRa发送数据的任务中。<br>
**2、使用到的api函数** **2、使用到的api函数**
- 创建队列句柄: - 创建队列句柄:
```c ```c
@@ -89,7 +109,7 @@ xQueueReceive(xQueueHandler, <要传递的变量,指向其地址>, portMAX_DEL
``` ```
### 三、信号量: ### 三、信号量:
**1、概念** **1、概念**
信号量一般用于任务管理。常用的分为二值信号量、计数型信号量和互斥信号量3种信号量,其中二值信号量全称为二进制信号量用于任务同步类似于状态机而后两者分别用于多资源和单资源的管理资源管理就相当于停车场多资源管理相当于停车场的多个车位若停车位停满车就不能停车了单资源同理。这三种信号量都只有0或1两种值。使用信号量的过程以二值信号量为例为创建二值信号量->释放二值信号量->获取二值信号量。释放二值信号量共有两个函数释放任务中信号量和释放中断中信号量。信号量和状态机类似释放信号量就相当于改变标志位而获取信号量相当于获取改变的标志位以决定是否改变执行器的状态。由于只有0和1两种值因此适用于只有开和关两种状态的执行器。 信号量一般用于任务管理。常用的分为二值信号量、计数型信号量和互斥信号量3种信号量,其中二值信号量全称为二进制信号量用于任务同步类似于状态机而后两者分别用于多资源和单资源的管理资源管理就相当于停车场多资源管理相当于停车场的多个车位若停车位停满车就不能停车了单资源同理。这三种信号量都只有0或1两种值。使用信号量的过程以二值信号量为例为创建二值信号量->释放二值信号量->获取二值信号量。释放二值信号量共有两个函数释放任务中信号量和释放中断中信号量。信号量和状态机类似释放信号量就相当于改变标志位而获取信号量相当于获取改变的标志位以决定是否改变执行器的状态。由于只有0和1两种值因此适用于只有开和关两种状态的执行器。<br>
**2、使用到的api函数** **2、使用到的api函数**
- 动态创建二值信号量: - 动态创建二值信号量:
```c ```c

File diff suppressed because one or more lines are too long

View File

@@ -936,7 +936,7 @@
<Group> <Group>
<GroupName>System</GroupName> <GroupName>System</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -1016,7 +1016,7 @@
<Group> <Group>
<GroupName>Drivers</GroupName> <GroupName>Drivers</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -1120,7 +1120,7 @@
<Group> <Group>
<GroupName>FreeRTOS/inc</GroupName> <GroupName>FreeRTOS/inc</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -1344,7 +1344,7 @@
<Group> <Group>
<GroupName>FreeRTOS/src</GroupName> <GroupName>FreeRTOS/src</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -1436,7 +1436,7 @@
<Group> <Group>
<GroupName>FreeRTOS/portable</GroupName> <GroupName>FreeRTOS/portable</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -1480,7 +1480,7 @@
<Group> <Group>
<GroupName>FreeRTOS/config</GroupName> <GroupName>FreeRTOS/config</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>

File diff suppressed because one or more lines are too long