STM32G0+EMW3080+阿里云飞燕平台实现单片机WiFi智能联网功能(三)STM32G0控制EMW3080实现IoT功能
- 项目描述:该系列记录了STM32G0+EMW3080实现单片机智能联网功能项目的从零开始一步步的实现过程;
- 硬件环境:单片机为STM32G030C8T6;物联网模块为EMW3080V2-P;网联网模块的开发板为MXKit开发套件,具体型号为XCHIP
MXKit-Base V2.2;- 软件环境:STM32需要的软件有STM32CubeMX和STM32CubeIDE;开发IDE为eclipse;MXKit的串口调试工具使用的是putty.exe;
- 串口指令:串口指令使用的是AT指令; 通信方式使用的是UART
- 项目过程:本项目采用模块化的形式一步步的实现STM32G0+EMW3080+阿里云实现单片机智能联网功能;第一步先使用MXKit开发板和PC进行通信;第二步是配置阿里云飞燕平台;第三步是MXKit开发板实现配网功能,MXKit和阿里云之间成功通讯;第四步是STM32G0单片机实现和EMW3080的串口通讯;第五步是测试整体的功能;
本节为该项目的第四节,主要任务是实现STM32G030C8T6控制EMW3080实现IoT功能,即STM32G030C8T6控制EMW3080实现配网、断网重连、以及数据的下发、app控制设备等;最终的结果是,单片机上电后,向EMW3080发送配网指令,配网成功后,在云智能app端下发指令能够控制单片机上的LED等开和关;当然也支持wifi断开重连等功能;
经过上一篇文章,STM32G0+EMW3080+阿里云飞燕平台实现单片机WiFi智能联网功能(三)EMW3080完成配网,EMW3080连接到阿里云飞平台,通过串口调试EMW3080已经能成功的进行配网了,所以我们现在要做的就是,让STM32G030C8T6来发送配网指令,完成EMW3080的配网过程,并且在完成配网后,可以向STM32G030C8T6发送和接收数据用于控制设备;
文章目录
- 一、硬件连接
- 二、代码实现
- 笔记
一、硬件连接
STM32G030C8T6和EMW3080的连接原理图如下图所示:
其中,使用STM32G030C8T6的UART1串口,接到EMW3080的UART串口上,接线如上图所示;然后STM32G030C8T6通过STLINK或JLINK连接到电脑上,便于调试和烧写程序;EMW3080开发板通过自带电源线也连接到电脑的USB端口上用于供电;这样接线部分就接好了;
需要注意的是,STM32G030C8T6我是用的是USART1;EMW3080开发板上有“UART”和“DEBUG”两个区域都由RX和TX,
我们需要使用UART区域中的RX和TX,而不是DEBUG中的,如果不小心使用了DEBUG中的RX和TX,指令虽然也能发送到EMW3080,但是无法识别;
接线完成后,实物图如下所示:
二、代码实现
接下来就是在STM32G030C8T6中编写代码实现向EMW3080发送AT指令进行配网,并根据返回的信息判断是否配网成功;待配网成功后,STM32G030C8T6接收云端发下来的指令,并进行响应的控制;本代码示例中通过下发LED等开和关的指令,控制STM32上的灯亮和灭;
整个工程的代码可以从以下链接中下载(https://download.csdn.net/download/AnChenliang_1002/88511568)
下载后的资源可以直接用STM32CubeIDE运行;
下面大致讲解一下代码结构:
主要的源文件如上图所示,其中我们IoT的功能主要在wilo_wifiMoudule.c中实现;
附上wilo_wifiMoudule.c的完整代码:
#include "wilo_wifiModule.h"#include "wilo_uart.h"#define DISCONNECT_TRUE 1
#define DISCONNECT_FALSE 0extern UART_HandleTypeDef huart1;
extern uint8_t rxBuffer[128];
extern __IO uint8_t receivedIndex;//跟踪接收到的字符的索引
extern uint8_t stringMatched ;//是否接收到完整的字符串
extern uint8_t receivedData[128]; // 全局数组用于存储完整接收到的内容
extern __IO uint8_t receivedLength; // 当前接收到的数据长度,为0时表示未收到数据,大于0时表示收到了数据
extern uint8_t preReceivedLength;//前一次接收到的数据长度
extern const char* atCommands[] ;// 声明一个设备参数变量
DeviceParameters deviceParams;void reset_receive()
{// 重置接收索引,准备接收下一段内容receivedIndex = 0;stringMatched = 0;receivedLength = 0;preReceivedLength = 0;memset(receivedData,0,sizeof(receivedData));
}// 发送指令并等待回复函数
HAL_StatusTypeDef sendCommandAndWait(const char* command, const char* expectedReply)
{// 发送指令HAL_UART_Transmit_IT(&huart1, (uint8_t*)command, strlen(command));// 接收回复HAL_UART_Receive_IT(&huart1, &rxBuffer[receivedIndex], 1); while((0 == receivedLength))//如果还未接收到数据,一直等待;直到收到数据{OLED_ShowString(0,4,"wait response");}//HAL_UART_Transmit_IT(&huart1, (uint8_t*)"wait!!!!\r\n", 10);//OLED_Clear();//OLED清零while(0 == stringMatched )//如果还没有接收完所有数据,一直等待,直到接收完所有数据{ReceivedAll();//判断是否接收完所有字符串了}//HAL_UART_Transmit_IT(&huart1, (uint8_t*)"111\r\n", 5);//HAL_Delay(1000);//HAL_UART_Transmit_IT(&huart1, (uint8_t*)"received\r\n", 10);OLED_Clear();//OLED清零OLED_ShowString(0,4,"received:");OLED_ShowString(80,4,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);//replyBuffer = receivedData;if (strstr((const char *)receivedData, expectedReply) != NULL){// 重置接收,准备接收下一段内容reset_receive();// 收到期望的回复return HAL_OK;}// 重置接收,准备接收下一段内容reset_receive(); return HAL_ERROR;
}
#if 0
//等待wifi配网成功
HAL_StatusTypeDef WaitConnected()
{//uint32_t startTime = HAL_GetTick();//uint32_t elapsedTime = 0;int Connected = 0;//是否配网完成// 持续等待回复,直到收到配网成功的回复;当TimeOut_flag为2时说明超时了while ( 1 != Connected){HAL_UART_Receive_IT(&huart1, &rxBuffer[receivedIndex], 1);if(0 == stringMatched)//还未接收到数据,一直等待{OLED_Clear();//OLED清零OLED_ShowString(0,4,"000 wait Connect");// 延时3秒//HAL_Delay(3000);while( stringMatched == 0){ReceivedAll();//判断是否接收完所有字符串了}}if(1 == stringMatched){OLED_Clear();//OLED清零OLED_ShowString(0,0,"received:");OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒HAL_Delay(3000);if (strstr(receivedData, "ILOPEVENT:ILOP,CONNECTED") != NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,"Connect OK");// 延时3秒//HAL_Delay(3000);// 重置接收,准备接收下一段内容reset_receive();Connected = 1;return HAL_OK;//配网成功}// 重置接收,准备接收下一段内容reset_receive();}// 更新经过的时间//elapsedTime = HAL_GetTick() - startTime;}return HAL_TIMEOUT;
}
#endif//等待wifi配网成功
HAL_StatusTypeDef WaitConnected()
{//uint32_t startTime = HAL_GetTick();//uint32_t elapsedTime = 0;OLED_Clear();//OLED清零OLED_ShowString(0,4," waiting Connect");int Connected = 0;//是否配网完成// 持续等待回复,直到收到配网成功的回复;当TimeOut_flag为2时说明超时了while ( 1 != Connected){HAL_UART_Receive_IT(&huart1, &rxBuffer[receivedIndex], 1);if(0 != receivedLength)//收到数据了{//OLED_Clear();//OLED清零//OLED_ShowString(0,4,"000 wait Connect");// 延时3秒//HAL_Delay(3000);while( stringMatched == 0)//判断是否接收完数据,如果未接收完,则一直循环,直到接收完{ReceivedAll();//判断是否接收完所有字符串了}OLED_Clear();//OLED清零OLED_ShowString(0,0,"received:");OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);if (strstr((const char *)receivedData, "ILOPEVENT:ILOP,CONNECTED") != NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,"Connect OK");// 延时3秒//HAL_Delay(3000);// 重置接收,准备接收下一段内容reset_receive();Connected = 1;return HAL_OK;//配网成功}// 重置接收,准备接收下一段内容reset_receive();}}return HAL_TIMEOUT;
}// 进入WiFi配网过程的函数
HAL_StatusTypeDef WiFiConfigInit()
{HAL_StatusTypeDef status;// 发送指令 "AT",直到收到的回复是OKstatus = sendCommandAndWait(atCommands[0], "OK");while (status != HAL_OK){OLED_Clear();//OLED清零OLED_ShowString(0,4,"AT Not OK");status = sendCommandAndWait("AT\r\n", "OK");}OLED_Clear();//OLED清零OLED_ShowString(0,4,"AT OK");// 延时10秒//HAL_Delay(10000);// 发送指令 "AT+ILOPAWSAP\r\n"status = sendCommandAndWait("AT+ILOPAWSAP\r\n", "OK");while (status != HAL_OK){OLED_Clear();//OLED清零OLED_ShowString(0,4,"SWAP Not OK");status = sendCommandAndWait("AT+ILOPAWSAP\r\n", "OK");}OLED_Clear();//OLED清零OLED_ShowString(0,4,"SWAP OK");// 延时10秒//HAL_Delay(10000);if(HAL_OK == WaitConnected()){OLED_Clear();//OLED清零OLED_ShowString(0,4,"Connect OK");}else{OLED_Clear();//OLED清零OLED_ShowString(0,4,"Connect TimeOut");return HAL_TIMEOUT;}// 配网成功return HAL_OK;
}void DeviceInit()
{deviceParams.powerState = 0;
}
/*判断wifi是否断开,返回DISCONNECT 表示wifi断开;返回CONNECT表示wifi处于连接状态*/
uint8_t wifi_isDisconnected()
{uint8_t disConnected = DISCONNECT_FALSE;//默认没有断开if (strstr((const char *)receivedData, "ILOPEVENT:ILOP,CONNECTING") != NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,"wifi disconnect ");// 延时3秒//HAL_Delay(3000);// 重置接收,准备接收下一段内容reset_receive();disConnected = DISCONNECT_TRUE;//wifi断开} return disConnected;
}void wifi_task()
{HAL_UART_Receive_IT(&huart1, &rxBuffer[receivedIndex], 1);//if(0 == stringMatched)//还未接收到数据,一直等待if(0 != receivedIndex)//说明接收到消息了{//OLED_ShowString(0,4,"Recive date begin");// 延时3秒//HAL_Delay(3000);while( 0 == stringMatched){ReceivedAll();//判断是否接收完所有字符串了}OLED_Clear();//OLED清零OLED_ShowString(0,0,"received:");OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);if(DISCONNECT_TRUE == wifi_isDisconnected())//如果wifi断开了{OLED_Clear();//OLED清零OLED_ShowString(0,4,"wifi DisConnect ");// 延时3秒//HAL_Delay(3000); //while(HAL_OK != WaitConnected());WaitConnected();//等待wifi重连成功OLED_Clear();//OLED清零OLED_ShowString(0,4,"wifi recover ");// 延时3秒//HAL_Delay(3000); }else{OLED_Clear();//OLED清零OLED_ShowString(0,4,"wifi parse Task ");//HAL_Delay(3000);parseWiFiCommand((char *)receivedData);deviceControl();reset_receive(); }}{OLED_Clear();//OLED清零OLED_ShowString(0,4,"wifi connect "); } }void parseWiFiCommand(const char* command)
{const char* keyword = "+ILOPEVENT:SETJSON,property,";const char* powerstateKeyword = "\"powerstate\":";const char* powerstateValue = NULL;// 检查指令是否以关键字开头if (strncmp(command, keyword, strlen(keyword)) != 0) {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,"error 1");}//return;}// 定位到powerstate关键字的位置powerstateValue = strstr(command, powerstateKeyword);if (powerstateValue == NULL) {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,"error 2");}//return;}// 解析powerstate的值powerstateValue += strlen(powerstateKeyword);int powerstate = *powerstateValue - '0';//将powerstateValue指针所指向的字符转换为整数,并将结果存储在powerstate变量中。*powerstateValue表示取指针所指向的字符,然后通过减去字符'0'的ASCII值,实现将字符转换为对应的整数值。// 根据powerstate设置state的值if (powerstate == 0) {deviceParams.powerState = 0;} else if (powerstate == 1) {deviceParams.powerState = 1;} else {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,"error 3");}}
}void deviceControl()
{if(0 == deviceParams.powerState)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//灯灭elseHAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);//灯亮
}// 发送数据
void sendWiFiData(const char* paramName, const char* paramValue) {// 构建发送数据的格式//sprintf(txBuffer, "+ILOPEVENT:SETJSON,%s,%d,{\"%s\":%s}\r\n", paramName, strlen(paramValue), paramName, paramValue);// 在这里实现串口发送功能,将txBuffer中的数据发送出去// 例如:HAL_UART_Transmit(&huart1, (uint8_t*)txBuffer, strlen(txBuffer), HAL_MAX_DELAY);
}
笔记
记录几个开发中的细节:
1、单片机向wifi模块发送指令 AT+ILOPAWSAP\r\n
进行配网
2、当单片机收到wifi模块返回的信息中,包含ILOPEVENT:ILOP,CONNECTED
时,说明配网成功
3、当单片机收到wifi模块返回的信息中,包含ILOPEVENT:ILOP,CONNECTING
时,说明wifi已经断开,正在重连
4、云端向EMW3080发送的控制指令,也就是单片机需要解析的指令,格式如下(以参数“开关状态”为例):
+ILOPEVENT:SETJSON,property,16,{"powerstate":0}
+ILOPEVENT:SETJSON,property,16,{"powerstate":1}
相关文章:

STM32G0+EMW3080+阿里云飞燕平台实现单片机WiFi智能联网功能(三)STM32G0控制EMW3080实现IoT功能
项目描述:该系列记录了STM32G0EMW3080实现单片机智能联网功能项目的从零开始一步步的实现过程;硬件环境:单片机为STM32G030C8T6;物联网模块为EMW3080V2-P;网联网模块的开发板为MXKit开发套件,具体型号为XCH…...

IntelliJ IDEA - Git Commit 后 Commit 窗口不消失解决方案
这个现象是在 2023 年版本后开始的,一开始以为是 Mac 系统的原因,后来发现原来 Windows 也这样,所以应该只跟 IDEA 版本有关 可以看到左侧 commit 后,这个侧边栏还在,按理讲在以前的版本是之前消失,这样使…...

Vue 组件化编程 和 生命周期
目录 一、组件化编程 1.基本介绍 : 2.原理示意图 : 3.全局组件示例 : 4.局部组件示例 : 5.全局组件和局部组件的区别 : 二、生命周期 1.基本介绍 : 2.生命周期示意图 : 3.实例测试 : 一、组件化编程 1.基本介绍 : (1) 开发大型应用的时候,页面往往划分成…...

《数字图像处理-OpenCV/Python》连载(41)图像的旋转
《数字图像处理-OpenCV/Python》连载(41)图像的旋转 本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 第 6 章 图像的几何变换 几何变换分…...

案例 - 拖拽上传文件,生成缩略图
直接看效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>拖拽上传文件</title>&l…...

PHP 使用递归方式 将其二维数组整合为层级树 其中层级id 为一个uuid的格式 造成的诡异问题 已解决
不啰嗦 直接上源代码 <?php function findChildren($list, $p_id){$r array();foreach ($list as $k > $item) {if ($item[fid] $p_id) {unset($list[$k]);$length count($r);$r[$length] $item;if ($t findChildren($list, $item[id])) {$r[$length][children] …...

rv1126-rv1109-添加分区,定制固件,开机挂载功能
===================================================================== 修改分区: 这里是分区的txt文件选择; 这里是分区的划分,我这里回车了,方便看 FIRMWARE_VER: 8.1 MACHINE_MODEL: RV1126 MACHINE_ID: 007 MANUFACTURER: RV1126 MAGIC: 0x5041524B ATAG: 0x00200…...

一台电脑使用多个gitee账号,以及提交忽略部分文件
目录 编辑 一:前言 二:解决方法 三:提交gitee时忽略文件 一:前言 在开发中,我们拥有不止一个 gitee 账号,通常而言一个是公司的,一个是私人的。有时候我们在公司写了一些自己的东西&#…...
解析邮件文本内容; Mime文本解析; MimeStreamParser; multipart解析
原始文本 ------_Part_46705_715015081.1699589700255 Content-Type: text/html;charsetUTF-8 Content-Transfer-Encoding: base64PGh0bWwCiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBodHRwLW VxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRt bDsgY2hhcnNldD1VVEYtOCICiAgICAgIC…...

获取请求IP以及IP解析成省份
某些业务需要获取请求IP以及将IP解析成省份之类的,于是我写了一个工具类,可以直接COPY /*** IP工具类* author xxl* since 2023/11/9*/ Slf4j public class IPUtils {/*** 过滤本地地址*/public static final String LOCAL_ADDRESS "127.0.0.1&quo…...

YOLOv8-seg改进:复现HIC-YOLOv5,HIC-YOLOv8-seg助力小目标分割
🚀🚀🚀本文改进:HIC-YOLOv8-seg:1)添加一个针对小物体的额外预测头,以提供更高分辨率的特征图2)在backbone和neck之间采用involution block来增加特征图的通道信息;3)在主干网末端加入 CBAM 的注意力机制; 🚀🚀🚀HIC-YOLOv8-seg小目标分割检测&复杂场景…...

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower
vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower 第一次用vscode,然后遇到这个问题,在设置里搜索 terminal.integrated.defaultProfile.windows 将这里的null改成"Command Prompt" 重启就可以了...

【中间件篇-Redis缓存数据库02】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)
Redis高级特性和应用(慢查询、Pipeline、事务、Lua) Redis的慢查询 许多存储系统(例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关…...

栈 和 队列
什么是栈? 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出(LIFO - Last In First Out)的原则。 从数据结构的角度来看&…...

【推荐】一款AI写作大师、问答、绘画工具-「智元兔 AI」
在当今技术飞速发展的时代,越来越多的领域开始应用人工智能(Artificial Intelligence,简称AI)。其中,AI写作工具备受瞩目,备受推崇。在众多的选择中,智元兔AI是一款在笔者使用过程中非常有帮助的…...

阿里云付费用户破100万 用户规模亚洲最大
导读阿里巴巴集团公布2018财年第一季度财报,阿里云达到一个重要里程碑,云计算付费用户数量首次超过100万,成为亚洲首家达到百万级用户规模的云计算公司。同时,企业级市场被云计算人工智能等新技术全面激活,推动该季度营…...

人工智能基础——Python:Matplotlib与绘图设计
人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…...
Ubuntu 配置 Github 的 SSH keys
先进入已有的 Git 目录或使用新建的一个 Git 仓库下。 设置 Github 用户名和邮箱: $ git config --global user.name [Github用户名] $ git config --global user.email [Github认证邮箱]生成 SSH 密钥文件: $ ssh-keygen -t rsa -C [Github认证邮箱]…...
Flink—— Flink Data transformation(转换)
Flink数据算子转换有很多类型,各位看官看好,接下来,演示其中的十八种类型。 1.Map(映射转换) DataStream → DataStream 将函数作用在集合中的每一个元素上,并返回作用后的结果,其中输入是一个数据流&…...
前端读取文件当文件选择相同文件名的文件,内容不会变化
前端读取文件当文件选择相同文件名的文件,内容不会变化 今天遇到个奇怪的bug,使用打开文件,并选择文件时,正常情况会读取文件信息。 但是如果先选择相同的文件名,则内容不会发生变化。 先说结论 只要不使用事件中e…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...