STM32第一节——初识STM32
1 硬件介绍
1.1 硬件平台
配套硬件:以野火的STM32 F1霸道开发板为平台,若用的是别的开发板,可自己进行移植。
1.2 什么是STM32
STM32是由意法半导体(STMicroelectronics)公司推出的一系列32位的ARM Cortex-M微控制器。这些微控制器广泛用于嵌入式系统和物联网(IoT)应用中。以下是有关STM32的一些主要特征和信息:
-
架构: STM32微控制器使用ARM Cortex-M内核,其中包括Cortex-M0、Cortex-M3、Cortex-M4和Cortex-M7等不同型号。这些内核提供了高性能、低功耗的处理能力。
-
丰富的外设: STM32微控制器集成了丰富的外设,包括但不限于通用输入/输出(GPIO)、定时器、串口通信(USART、SPI、I2C)、模拟和数字转换器(ADC、DAC)、PWM控制、以太网控制器、USB接口等。
-
开发工具: STMicroelectronics提供了一套完整的开发工具,包括ST-LINK调试器、集成开发环境(IDE)如STM32CubeIDE,以及丰富的软件库和示例代码。这些工具使得开发人员可以方便地进行嵌入式系统的开发。
-
丰富的型号: STM32系列包括多个型号和系列,以满足不同应用的需求。不同系列的型号可能具有不同的性能、外设和封装选项。
-
生态系统支持: STM32拥有强大的生态系统,包括广泛的社区支持、技术文档、在线培训课程等。这使得开发人员能够轻松获取帮助和资源。
-
广泛的应用: 由于其灵活性和性能,STM32微控制器广泛用于各种应用领域,包括工业控制、汽车电子、智能家居、医疗设备、消费电子等。

2 芯片
芯片(这里指内核,或者叫 CPU)和外设之间通过各种总线连接,其中驱动单元有 4 个,被动单 元也有 4 个,具体见图 2.1。为了方便理解,我们都可以把驱动单元理解成是 CPU 部分,被动单 元都理解成外设。下面我们简单介绍下驱动单元和被动单元的各个部件。
2.1 ICode总线
在STM32微控制器中,ICode(Instruction Code)总线是指令代码总线,它是与存储器相关的一个概念。在STM32中,存储器包括Flash存储器,其中存储了程序的指令代码。
ICode总线用于从Flash存储器读取指令代码,以供CPU执行。具体而言,ICode总线连接了CPU和Flash存储器,使得CPU能够从Flash中读取指令。这样,当程序在Flash存储器中时,CPU可以通过ICode总线有效地访问并执行这些指令。
在STM32的体系结构中,存储器总线分为指令总线(ICode总线)和数据总线(DCode总线)。这种划分有助于提高存储器访问的效率。ICode总线专门用于传输指令代码,而DCode总线用于传输数据。这种分离可以提高系统的性能,特别是在存在并行访问指令和数据的情况下。
总体而言,ICode总线在STM32中是与指令存储器Flash相关的一部分,用于高效地传输指令代码到CPU,以支持程序的正常执行。
2.2 驱动单元
2.2.1 DCode总线
在STM32微控制器中,DCode(Data Code)总线是数据代码总线,用于传输数据。与ICode总线(指令代码总线)相对应,DCode总线是用于访问数据存储器的总线。DCode总线连接了CPU和数据存储器,其中数据存储器可以包括RAM(随机存储器)和其他存储器设备。当CPU需要读取或写入数据时,DCode总线允许它与数据存储器进行通信。
在STM32的存储器总线结构中,ICode总线和DCode总线是分开的,这样的分离有助于提高存储器访问的效率。ICode总线专门用于传输指令代码,而DCode总线用于传输数据。这种架构允许在执行指令的同时,同时进行对数据存储器的读取或写入操作,从而提高了整个系统的性能。
总的来说,DCode总线在STM32中是与数据存储器相关的一部分,用于支持CPU与数据存储器之间的高效数据传输,以满足程序的数据处理需求。因为数据可以被 Dcode 总线和 DMA 总线访问,所以为了避免访问冲突,在取数的时候需要经过一个总线矩阵来 仲裁,决定哪个总线在取数。
2.2.2 系统总线
在STM32微控制器中,系统总线是连接不同部件和模块的一个关键总线系统,它促使各种外设和内部组件之间进行通信和数据传输。系统总线主要是访问外设的寄存器,我们通常说的寄存器编程,即读写寄存器都是通过这根系统 总线来完成的。
2.2.3 DMA总线
在STM32微控制器中,DMA(Direct Memory Access)总线是一种用于高效数据传输的机制。这个数据可以是在某个外设的数据寄存器,可以在 SRAM, 可以在内部的 FLASH。因为数据可以被 Dcode 总线和 DMA 总线访问,所以为了避免访问冲突, 在取数的时候需要经过一个总线矩阵来仲裁,决定哪个总线在取数。DMA允许外设或内存之间的数据传输,而无需CPU的直接干预,从而提高了系统的性能和效率。
2.3 被动单元
2.3.1 内部的闪存存储器
STM32微控制器中的闪存存储器通常是指Flash存储器。Flash存储器是一种非易失性存储器,用于存储程序代码、配置数据和其他常驻信息。以下是关于STM32内部Flash存储器的一些关键信息:
-
程序存储: 主要用于存储微控制器的程序代码。在STM32中,Flash存储器通常分为不同的扇区,每个扇区可以用于存储不同的程序段。程序可以通过编程器或Bootloader等方式被烧录到Flash存储器中。
-
非易失性: Flash存储器是一种非易失性存储器,这意味着它可以在断电后保持存储的数据。这使得它非常适合用于存储嵌入式系统的程序代码,因为程序代码在断电后仍然可以被保留。
-
扇区和页: Flash存储器被分为不同的扇区,每个扇区通常包含多个页。在STM32中,一般可以通过扇区擦除和页编程的方式对Flash进行操作。擦除是将整个扇区的数据清除,而编程是将数据写入到特定的页中。
-
擦写次数: Flash存储器有一个擦写次数的限制,超过这个限制可能导致存储器损坏。因此,在设计中需要注意避免频繁的擦写操作。一些STM32微控制器提供了内部的Flash管理功能,可以帮助延长Flash寿命。
-
自校准: 一些STM32微控制器具有自校准功能,可以在Flash存储器的使用过程中进行自动的校准,以提高性能和可靠性。
-
Bootloader: 一些STM32微控制器集成了Bootloader,允许通过外部接口(如串口)更新Flash中的程序代码,而无需使用外部编程器。
总体而言,STM32内部的Flash存储器是关键的系统组件,用于存储程序代码和其他关键数据。开发者在使用时需要注意擦写次数的限制以及合理使用擦写和编程操作以确保存储器的可靠性和寿命。
2.3.2 内部的SRAM
STM32微控制器中的SRAM(Static Random Access Memory)是一种用于存储数据的随机存取存储器。与Flash存储器不同,SRAM是易失性存储器,即在断电时会丢失其中的数据。以下是关于STM32内部SRAM的一些关键信息:
-
数据存储: SRAM主要用于存储程序执行过程中产生的临时数据,包括变量、堆栈、和其他运行时数据。与Flash存储器不同,SRAM的读写速度很快,适合用于频繁的数据读写操作。
-
易失性: SRAM是一种易失性存储器,这意味着在断电时会丢失其中的数据。因此,SRAM通常用于需要在设备运行期间进行快速读写的应用,而不是长期存储。
-
内部结构: STM32微控制器的SRAM通常被分为不同的块或区域,例如数据RAM(用于存储变量)、堆栈RAM(用于存储函数调用时的堆栈数据)等。这些不同的区域有不同的用途和访问特性。
-
访问速度: 与Flash存储器相比,SRAM的访问速度更快,因为它是基于静态存储单元的,而不需要进行擦写和编程的操作。
-
功耗: 由于SRAM是易失性存储器,它在持续通电的情况下能够快速读写,但在断电后会失去存储的数据。这也意味着在需要长期存储数据时,应该使用Flash等非易失性存储器。
-
容量: STM32微控制器的SRAM容量因型号而异,通常有几十KB到几百KB的范围,具体取决于具体的芯片型号。
开发者在使用STM32内部SRAM时需要注意其易失性特性,并确保适当地选择存储数据的位置,以满足程序的需求。通常,SRAM用于存储临时数据,而长期存储数据则需要使用Flash等非易失性存储器。
2.3.3 FSMC
在STM32微控制器中,FSMC(Flexible Static Memory Controller)是一种用于连接外部存储器设备的控制器。它提供了灵活的接口,可以与各种静态存储器设备(如SRAM、NOR Flash、NAND Flash等)进行通信。以下是有关STM32中FSMC的一些关键信息:
-
灵活性: FSMC设计的目的是为了与多种外部存储器设备进行通信,包括静态RAM(SRAM)、NOR Flash存储器、NAND Flash存储器等。这种灵活性使得STM32微控制器可以与不同类型的存储器设备进行接口,满足不同应用的需求。
-
并行接口: FSMC支持并行接口,这意味着它可以同时传输多个比特的数据,提高了数据传输的效率。这对于要求高速数据传输的存储器设备是非常重要的。
-
FSMC与SRAM: 在一些应用中,FSMC常用于连接外部的SRAM,提供了高速的RAM存储器,用于存储数据。通过FSMC,微控制器可以通过并行接口与外部SRAM进行数据的读写。
-
FSMC与NOR Flash: FSMC还可用于连接NOR Flash存储器,这是一种用于存储程序代码的非易失性存储器。通过FSMC,可以实现从外部NOR Flash读取程序代码。
-
FSMC与NAND Flash: 对于NAND Flash存储器,FSMC也提供了支持。NAND Flash通常用于存储大容量的数据,例如文件系统、图像等。
-
配置和控制: 配置FSMC的参数需要设置寄存器,包括时序参数、数据宽度、地址宽度等。通过正确的配置,可以确保FSMC与外部存储器设备的正常通信。
-
DMA支持: FSMC可以与DMA(Direct Memory Access)控制器结合使用,以实现高效的数据传输,减轻CPU的负担。
使用FSMC可以方便地连接外部存储器设备,扩展STM32微控制器的存储容量和功能。开发者在使用FSMC时需要了解外部存储器的规格,并正确配置FSMC以确保稳定的数据传输。另外,FSMC 只能扩展静态的内存,即名称里面的 S:static,不能是动态的内存,比如 SDRAM 就不能扩展。
2.3.4 AHB 到 APB 的桥
在STM32微控制器中,AHB(Advanced High-performance Bus)和APB(Advanced Peripheral Bus)是两个不同的总线系统,用于连接不同的硬件模块。有时候,需要通过一个桥接器将AHB总线上的设备连接到APB总线上。这样的桥接器通常称为AHB到APB的桥。
以下是关于STM32中AHB到APB桥的一些关键信息:
-
总线体系结构: STM32微控制器使用了分层的总线体系结构,其中AHB总线是一个高性能的系统总线,而APB总线则是用于连接外围设备的低功耗总线。
-
AHB总线: AHB总线连接了一些性能较高、对响应时间要求较严格的硬件模块,如内核、高速外设等。
-
APB总线: APB总线则用于连接一些低速外设,如GPIO、UART、I2C等。这些外设对响应时间的要求相对较低。
-
AHB到APB桥: 由于AHB和APB总线之间的性能差异,有时需要一种机制来连接在AHB上的外设到APB上,以便在APB总线上进行控制和配置。
-
时钟域: AHB和APB通常具有不同的时钟域。AHB时钟可能更高,因此需要桥接器来适应这两个时钟域之间的差异。
-
桥接功能: AHB到APB桥提供了在两个总线之间传输数据的功能。它能够接收来自AHB总线的访问请求,并将其转发到APB总线上的相应外设。
-
配置和控制: 桥接器的配置通常涉及一些寄存器的设置,以确保正确的时钟分频和传输设置,以适应不同总线之间的差异。
使用AHB到APB桥的场景包括连接高性能外设或存储器到低功耗总线,以提供对这些外设的控制和配置。在具体的STM32微控制器系列和型号中,桥接的实现和特性可能有所不同,因此在具体的芯片手册和参考手册中可以找到详细的信息。

3 存储器映射
在图1中,被控单元的 FLASH,RAM,FSMC 和 AHB 到 APB 的桥(即片上外设),这些功能部 件共同排列在一个 4GB 的地址空间内。我们在编程的时候,可以通过他们的地址找到他们,然 后来操作他们(通过 C 语言对它们进行数据的读和写)。
3.1 存储器映射
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配的,给存储器分配地址的过程就 称为存储器映射,具体见图 3.1。如果给存储器再分配一个地址就叫存储器重映射。存储器映射的目的是为了方便程序访问这些存储器,并提供一种一致的访问方式。

4 寄存器映射
STM32微控制器的寄存器映射是一种将各种外设和系统寄存器映射到特定地址空间的方式,以便CPU能够通过读写这些地址来配置和控制微控制器的功能。以下是一般情况下STM32微控制器寄存器映射的一些基本概念:
-
Flash存储器映射: STM32微控制器的程序代码通常存储在Flash存储器中。Flash存储器的基地址通常被映射到程序地址空间的开始处,以便CPU可以从这里执行指令。
-
SRAM存储器映射: 静态RAM(SRAM)用于存储程序执行期间的数据。SRAM通常映射到数据地址空间,供程序使用。
-
外设寄存器映射: 每个外设都有一组相关的寄存器,用于配置和控制外设的行为。这些寄存器通常被映射到特定的地址空间,以便程序可以通过访问这些地址来与外设进行通信。
-
系统控制寄存器映射: 一些寄存器用于配置微控制器的系统级功能,例如时钟控制、中断控制等。这些寄存器被映射到系统地址空间。
-
中断向量表映射: 中断向量表包含中断服务程序的地址。在某些STM32微控制器中,中断向量表可能映射到Flash或SRAM中的特定位置。
-
Bootloader区域映射: 如果微控制器集成了Bootloader,Bootloader区域通常有一个特定的地址范围,用于支持程序的更新。
-
特殊功能寄存器映射: 一些微控制器可能具有特殊功能寄存器,用于控制特殊的硬件功能,例如电源管理、看门狗定时器等。
具体的寄存器映射细节取决于STM32微控制器的型号和系列。为了了解特定型号的寄存器映射,你需要查阅相应型号的参考手册或数据手册。这些手册通常提供了详细的寄存器映射表和寄存器描述,帮助开发者正确配置和操作微控制器的各个部分。
寄存器就是给一个已经分配好地址的特殊的内存空间取的一 个别名,这个特殊的内存空间可以通过指针来操作。在编程之前我们要先实现寄存器映射,有关 寄存器映射的代码都统一写在 stm32f10x.h 文件中,
相关文章:

STM32第一节——初识STM32
1 硬件介绍 1.1 硬件平台 配套硬件:以野火的STM32 F1霸道开发板为平台,若用的是别的开发板,可自己进行移植。 1.2 什么是STM32 STM32是由意法半导体(STMicroelectronics)公司推出的一系列32位的ARM Cortex-M微控制…...

多场景建模:美团HiNet
HiNet: Novel Multi-Scenario & Multi-Task Learning with Hierarchical Information Extraction 背景: 美团的多场景多任务(ctr、ctcvr) 解决方案 通过分层来分别学习多场景多任务 方案详情 点评:在底层Embedding时用…...
第二百九十三回
文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何混合选择多个图片和视频文件"相关的内容,本章回中将介绍如何通过相机获取图片文件.闲话休提,让我们一起Talk Flutter吧。 1. …...

【网络协议分析】使用Wireshark分析UDP协议
一、实验目的 通过使用Wireshark抓取UDP流来分析学习UDP协议,比较TCP与UDP的不同。 二、实验过程 1、使用Wireshark抓取UDP报文流,常见的使用UDP协议的应用有DNS、QQ、在线游戏等。 2、分析抓取到的数据包,比较与TCP协议的异同。 我们选取DN…...

TensorFlow Lite中文本分类在Android上的实践
#1 Tensorflow Lite TensorFlow Lite(后续简称TFL) 是 Google 开发的一个用于移动设备和嵌入式设备的开源库,旨在为移动终端设备提供机器学习推断。它是 TensorFlow 框架的轻量级版本,专门优化了模型的大小和性能,以适应资源受限的移动设备和嵌入式系统。 TFL 提供了一种在移…...

使用vscode查bug
具体操作 修改CMakeList.txt # set(CMAKE_BUILD_TYPE "Release")//注释Release模式 set(CMAKE_BUILD_TYPE "Debug")//设置为Debug模式 # set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g")//注释*这行代码是用来设置 CMake 构建系统中 Release 模式…...

LC 2846. 边权重均等查询
2846. 边权重均等查询 难度: 困难 题目大意: 现有一棵由 n 个节点组成的无向树,节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] [ui, vi, wi] 表示树中存在一条位于节点 …...

RabbitMQ简单模式和工作模式
RabbitMQ 是一个消息队列中间件,用于在分布式系统中进行消息传递。在 RabbitMQ 中,有几种工作模式,其中简单模式和工作模式是其中两种基本的模式之一。 简单模式(Simple Mode): 在简单模式中,有…...

c语言实战之贪吃蛇
文章目录 前言效果展示游戏用到的图片游戏思路一览游戏前准备一、贪吃蛇、食物、障碍物节点坐标的结构体二、枚举游戏状态、和贪吃蛇的方向三、维护运行的结构体 游戏开始前的初始化一、学习图形库相关知识二、设置背景三、欢迎界面四、初始化贪吃蛇五、生成障碍物六、生成食物…...
Midjourney图片生成描述词记录(今天一天)
抄别人的描述词 /imagine prompt:https://(你的图片地址).jpg Super handsome boy IP by pop mart , green suit, no hair, bald head, Scenes in spring , pastel color , mockup , fine luster , clean background ,3D render , Soft focus , oc , bl…...

类和对象 第五部分第四小节:赋值运算符重载
C编译器至少给一个类添加4个函数 1.默认构造函数无参,函数体为空 2.默认析构函数无参,函数体为空 3.默认拷贝沟早函数,对属性进行值拷贝 4.赋值运算符“operator”,对属性进行值拷贝 如果类中有属性指向堆区,做赋值操作…...

Django从入门到精通(一)
目录 一、Django环境搭建与命令 1.1、安装 1.2、命令行 创建项目 编写代码 运行 app概念 1.3、Pycharm创建项目 1.4、虚拟环境 创建虚拟环境 - 命令行 介绍 操作 基本问题 Pycharm 项目虚拟环境 django虚拟环境【安装django最新版本】 django虚拟环境【安装指…...
数据库分表分库的原则
什么是数据库分库分表 数据库分表(Table Sharding) 数据库分表是将一个大表按照某种规则拆分成多个小表存储在不同的物理表中的技术。通常,拆分规则是基于某个列的值进行拆分,例如根据用户ID或日期范围等进行拆分。每个小表只包…...

Java技术栈 —— Docker容器
Java技术栈 —— Docker容器 一、什么是Docker?二、如何安装Docker?三、如何使用Docker? 一、什么是Docker? docker的本意是码头工人。 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个…...

Mysql大数据量分页优化
前言 之前有看过到mysql大数据量分页情况下性能会很差,但是没有探究过它的原因,今天讲一讲mysql大数据量下偏移量很大,性能很差的问题,并附上解决方式。 原因 将原因前我们先做一个试验,我做试验使用的是mysql5.7.2…...

QT tcp与udp网络通信以及定时器的使用 (7)
QT tcp与udp网络通信以及定时器的使用 文章目录 QT tcp与udp网络通信以及定时器的使用1、QT网络与通信简单介绍2、QT TCP通信1、 服务器的流程2、 客户端的流程3、服务器的编写4、客户端的编写 3、QT UDP通信1、客户端流程2、客户端编写3、UDP广播4、UDP组播 4、定时器的用法1、…...
web架构师编辑器内容-添加自动保存的功能
对于频繁改动的应用,自动保存的功能是一个非常有用的功能,可以避免用户在没有保存的情况下丢失自己保存过的数据。 对于自动保存,一般有两种实现,参考语雀和石墨: 语雀采用的是定时保存的方式,大约在3分半…...

【Redis】关于它为什么快?使用场景?以及使用方式?为何引入多线程?
目录 1.既然redis那么快,为什么不用它做主数据库,只用它做缓存? 2.Redis 一般在什么场合下使用? 3.redis为什么这么快? 4.Redis为什么要引入了多线程? 1.既然redis那么快,为什么不用它做主数据…...

SpringBoot之JWT登录
JWT JSON Web Token(JSON Web令牌) 是一个开放标准(rfc7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任,因为它是数字签名的。jwt可以使用秘密〈使用HNAC算法…...

【备战蓝桥杯】——循环结构
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-bFHV3Dz5xMe6d3NB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...