STM32(六):定时器PWM呼吸灯 (标准库函数)

前言

上一篇文章已经介绍了如何用STM32单片机中的TIMER定时器来控制LED灯的交替闪烁,实现了点灯的第五种方式。这篇文章我们来介绍一下如何用STM32单片机中的定时器的PWM波来实现LED的“呼吸”。

一、实验原理

关于定时器这边就不多加赘述,详细请看上一篇文章,链接放在下面了

STM32(五):TIMER定时器 (标准库函数)

这边我们介绍一下PWM

1.PWM的介绍

PWM的全称是脉冲宽度调制(Pulse-width modulation),是指在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效的地获得所需要的模拟参量,常应用于电机控速等领域。在STM32微控制器的应用中,PWM技术也非常重要,因为它能够提供精确的信号控制,从而达到对设备行为的精确管理。

  • 频率:一秒钟内从高电平时间在到低电平时间,再从低电平跳到高电平的瞬间次数,也就是一秒钟内有多少个PWM的周期,f = 1/Ts。
  • 周期:一秒钟内从高电平时间在到低电平时间,Ts= 1/f。
  • PWM信号产生:用于控制电机速度、灯光亮度等。
  • 占空比:一个周期内高电平时间和总时间的比值,Ton/Ts。
  • 分辨率:占空比变化步距。

2.PWM参数计算公式

PWM主要参数计算公式如下所示:

  • PWM频率 Freq=CK_PSC/[(PSC+1) (ARR+1)], CK_PSC=72M
  • PWM占空比=CCR/(ARR+1)
  • PWM分辨率=1/(ARR+1)

3.PWM工作原理

以下是PWM输入模式时序工作原理图,以下对其符号进行简单的解释说明

  1. T1:PWM信号的波形,显示了信号的高电平和低电平状态。
  2. TIMx_CNT :定时器的计数器(Counter),它的值会在定时器时钟的脉冲下从0开始增加,直到达到自动重载寄存器(ARR)的值后归零,循环开始新的周期。
  3. TIMx_CCR1TIMx_CCR2 :捕捉/比较寄存器(Capture/Compare Register),用于设置PWM的高电平宽度。它们的值决定了在计数器达到这些值时输出比较匹配事件,影响PWM输出信号的占空比。
  • TIMx_CCR1 设置为 0004,代表在计数器计数到4时,第一个通道的PWM输出从高电平跳变到低电平。
  • TIMx_CCR2 设置为 0002,代表在计数器计数到2时,第二个通道的PWM输出从高电平跳变到低电平。

 接下来简单介绍一下PWM信号的一个典型的边缘对齐模式,

  • ARR = 8:设置了定时器的计数上限,决定了PWM周期的长度,计数器会从0计数到8,然后重置为0,开始新的周期。
  • CCRx = 4:决定了PWM信号从高电平变为低电平的切换点,当计数器计数到4时,输出信号从高电平切换到低电平。
  • 红线(有效电平):PWM输出从高电平切换到低电平的时刻,即在计数器值等于CCR值时,输出发生变化。
  • 蓝线(无效电平):PWM输出在一个完整的周期结束时仍然是低电平。
  • CCxIF:捕捉/比较中断标志,当定时器的计数器值与CCR寄存器的预设值相匹配时,该标志被设置。

  • OCxREF:输出比较引用信号,通常与PWM的实际输出相对应,反映了PWM信号的状态更改。

二、实验步骤

1.引脚设置

这边在h文件的宏定义中定义即可

static void GENERAL_TIMx_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;

	/* 使能定时器始终:设置TIM3CLK 为 72MHZ */
	GENERAL_TIM_APBxClock_FUN (GENERAL_TIM_CLK, ENABLE);

  /* 使能定时器通道引脚GPIO时钟 */
  GENERAL_TIM_GPIO_APBxClock_FUN(GENERAL_TIM_GPIO_CLK1|GENERAL_TIM_GPIO_CLK1, ENABLE); 

  /* 配置定时器通道3输出引脚模式:复用推挽输出模式 */
  GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_PIN1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GENERAL_TIM_PORT1, &GPIO_InitStructure);
}

2.时钟中断

时钟中断函数void NVIC_Config_PWM(void),这边是对中断来源以及优先级的配置,前面在Systick中有所介绍,可以看一下之前的连接:STM32(四):Systick (标准库函数)-CSDN博客

static void NVIC_Config_PWM(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* 选择中断优先级配置组为2个抢占式优先级和2个子优先级,可以参考misc.h文件了解相关设置 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  /* 配置TIM3_IRQ中断为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIMx_IRQn;
	/* 设置抢占式优先级为0 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	/* 设置子优先级为3 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	/* 使能外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

但到这里我们的中断配置还没结束!!重点!!易踩坑!!

我们还需要在stm32f10x_it.c的文件里面加上新的中断服务函数 GENERAL_TIMx_IRQHandler (),记得加上头文件,例如:

#include "bsp/GeneralTIM/bsp_GeneralTIM.h"
extern uint8_t indexWave[];

void GENERAL_TIMx_IRQHandler(void)
{	
	static uint8_t pwm_index = 0;			/* 用于PWM查表 */
	static uint8_t period_cnt = 0;		/* 用于计算周期数 */
	
  /* 定时器更新中断 */
	if (TIM_GetITStatus(GENERAL_TIMx, TIM_IT_Update) != RESET)	
 	{			
    period_cnt++;
    /* 若输出的周期数大于20,输出下一种脉冲宽的PWM波 */
    if(period_cnt >= 20)										
    {
      /* 根据PWM表修改定时器的比较寄存器值 */
      GENERAL_TIMx->GENERAL_TIM_CCRx = indexWave[pwm_index];	
		 
      /* 标志PWM表的下一个元素 */
      pwm_index++;												
      /* 若PWM脉冲表已经输出完成一遍,重置PWM查表标志 */
      if( pwm_index >=  40)								
      {
        pwm_index=0;								
      }
      /* 重置周期计数标志 */
      period_cnt=0;												
		}
    /* 必须要清除中断标志位 */
		TIM_ClearITPendingBit (GENERAL_TIMx, TIM_IT_Update);	
	}
}

3.定时器配置

定时周期和预分频需要根据实际需要进行调整,而这边TIM_Pulse=0是因为我们给了一个脉冲配置的数组indexWave[],若不用,调整这个大小会改变“呼吸”的速率。

static void GENERAL_TIMx_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
		 
  /* 当定时器从0计数到255,即为256次,为一个定时周期 */
  TIM_TimeBaseStructure.TIM_Period = 255; 
  /* 设置预分频:不预分频,即为72MHz,输出脉冲频率:72MHz/(1999+1)/(255+1) */
  TIM_TimeBaseStructure.TIM_Prescaler = 1999;
  /* 设置时钟分频系数:不分频(这里用不到) */
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
  /* 向上计数模式 */
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(GENERAL_TIMx, &TIM_TimeBaseStructure);

  /* 模式配置:PWM模式1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  /* 输出状态设置:使能输出 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	
  /* 设置跳变值,当计数器计数到这个值时,电平发生跳变 */
  TIM_OCInitStructure.TIM_Pulse = 0;
  
  /* 当定时器计数值小于CCR1_Val时为低电平 */
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  /* 初始化定时器通道1输出PWM */
  GENERAL_TIM_OCxInit(GENERAL_TIMx, &TIM_OCInitStructure);
  /* 定时器比较输出通道1预装载配置:使能预装载 */
  GENERAL_TIM_OCxPreloadConfig(GENERAL_TIMx, TIM_OCPreload_Enable);  
  /* 使能定时器重载寄存器ARR */
  TIM_ARRPreloadConfig(GENERAL_TIMx, ENABLE);
  /* 使能定时器 */
  TIM_Cmd(GENERAL_TIMx, ENABLE);  
  /* 配置NVIC */
  NVIC_Config_PWM();
  /* 定时器更新中断 */
  TIM_ITConfig(GENERAL_TIMx, TIM_IT_Update, ENABLE);
								
}

4.PWM信号初始化


void GENERAL_TIMx_PWM_Init(void)
{
	GENERAL_TIMx_GPIO_Config();
	GENERAL_TIMx_Configuration();	
}

三、实操代码

程序分为3个文件:bsp_GeneralTIM.c、bsp_GeneralTIM.h、main.c

1.bsp_GeneralTIM.c

#include "bsp/GeneralTIM/bsp_GeneralTIM.h" 
uint8_t indexWave[] = {1,1,2,2,3,4,6,8,10,14,19,25,33,44,59,80,107,143,191,255,
                       255,191,143,107,80,59,44,33,25,19,14,10,8,6,4,3,2,2,1,1};

/**
  * 函数功能: 配置TIMx复用输出PWM时用到的I/O
  */
static void GENERAL_TIMx_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;

	/* 使能定时器始终:设置TIM3CLK 为 72MHZ */
	GENERAL_TIM_APBxClock_FUN (GENERAL_TIM_CLK, ENABLE);

  /* 使能定时器通道引脚GPIO时钟 */
  GENERAL_TIM_GPIO_APBxClock_FUN(GENERAL_TIM_GPIO_CLK1|GENERAL_TIM_GPIO_CLK1, ENABLE); 

  /* 配置定时器通道3输出引脚模式:复用推挽输出模式 */
  GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM_PIN1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GENERAL_TIM_PORT1, &GPIO_InitStructure);
	
}

/**
  * 函数功能: 配置嵌套向量中断控制器NVIC
  */
static void NVIC_Config_PWM(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* 选择中断优先级配置组为2个抢占式优先级和2个子优先级,可以参考misc.h文件了解相关设置 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  /* 配置TIM3_IRQ中断为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = GENERAL_TIMx_IRQn;
	/* 设置抢占式优先级为0 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	/* 设置子优先级为3 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	/* 使能外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * 函数功能: 配置TIMx输出的PWM信号的模式,如周期、极性、占空比
  */

static void GENERAL_TIMx_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

  /* 定时器基本参数始终 */		 
  /* 当定时器从0计数到255,即为256次,为一个定时周期 */
  TIM_TimeBaseStructure.TIM_Period = 255; 
  /* 设置预分频:不预分频,即为72MHz,输出脉冲频率:72MHz/(1999+1)/(255+1) */
  TIM_TimeBaseStructure.TIM_Prescaler = 1999;
  /* 设置时钟分频系数:不分频(这里用不到) */
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
  /* 向上计数模式 */
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(GENERAL_TIMx, &TIM_TimeBaseStructure);

  /* 定时器输出通道1模式配置 */
  /* 模式配置:PWM模式1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  /* 输出状态设置:使能输出 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	
  /* 设置跳变值,当计数器计数到这个值时,电平发生跳变 */
  TIM_OCInitStructure.TIM_Pulse = 0;
  
  /* 当定时器计数值小于CCR1_Val时为低电平 */
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  /* 初始化定时器通道1输出PWM */
  GENERAL_TIM_OCxInit(GENERAL_TIMx, &TIM_OCInitStructure);
  /* 定时器比较输出通道1预装载配置:使能预装载 */
  GENERAL_TIM_OCxPreloadConfig(GENERAL_TIMx, TIM_OCPreload_Enable);  
  /* 使能定时器重载寄存器ARR */
  TIM_ARRPreloadConfig(GENERAL_TIMx, ENABLE);
  /* 使能定时器 */
  TIM_Cmd(GENERAL_TIMx, ENABLE);  
  /* 配置NVIC */
  NVIC_Config_PWM();
  /* 定时器更新中断 */
  TIM_ITConfig(GENERAL_TIMx, TIM_IT_Update, ENABLE);
								
}

/**
  * 函数功能: TIMx输出PWM信号初始化
  * 说    明:只要调用这个函数TIMx的通道就会有PWM信号输出
  */
void GENERAL_TIMx_PWM_Init(void)
{
	GENERAL_TIMx_GPIO_Config();
	GENERAL_TIMx_Configuration();	
}

2.bsp_GeneralTIM.h

#ifndef __GENERAL_TIM_H__
#define __GENERAL_TIM_H__

/* 包含头文件 ----------------------------------------------------------------*/
#include <stm32f10x.h>

/* 类型定义 ------------------------------------------------------------------*/
/* 宏定义 --------------------------------------------------------------------*/

#define GENERAL_TIMx                        TIM3
#define GENERAL_TIM_APBxClock_FUN           RCC_APB1PeriphClockCmd
#define GENERAL_TIM_CLK                     RCC_APB1Periph_TIM3
#define GENERAL_TIM_GPIO_APBxClock_FUN      RCC_APB2PeriphClockCmd
#define GENERAL_TIM_GPIO_CLK1               RCC_APB2Periph_GPIOA
#define GENERAL_TIM_PORT1                   GPIOA
#define GENERAL_TIM_PIN1                    GPIO_Pin_11
#define GENERAL_TIM_OCxInit                 TIM_OC3Init
#define GENERAL_TIM_OCxPreloadConfig        TIM_OC3PreloadConfig
#define GENERAL_TIM_CCRx                    CCR3
#define GENERAL_TIMx_IRQn                   TIM3_IRQn              //中断
#define GENERAL_TIMx_IRQHandler             TIM3_IRQHandler


/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/

void GENERAL_TIMx_PWM_Init(void);

#endif	/* __GENERAL_TIM_H__ */

3.main.c


/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "bsp/key/bsp_key.h"
#include "bsp/delay/delay.h"
#include "bsp/systick/bsp_SysTick.h"
#include "bsp/GeneralTIM/bsp_GeneralTIM.h" 
/* 函数体 --------------------------------------------------------------------*/

/**
  * 函数功能: 主函数.
  */
int main(void)
{

/* 初始化定时器PWM输出 */
  GENERAL_TIMx_PWM_Init();  
  while (1)
  {
  //空
    }
}


四、实验效果

呼吸灯

结束语

本文以STM32VET6为例讲解了用STM32单片机中用定时器的PWM波来实现LED的“呼吸”,并指出其中的易坑点。希望对大家有所帮助!如果还有什么问题,欢迎评论区留言,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/601620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【吊打面试官系列】Java高并发篇 - 如何让正在运行的线程暂停一段时间?

大家好&#xff0c;我是锋哥。今天分享关于 【如何让正在运行的线程暂停一段时间&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 如何让正在运行的线程暂停一段时间&#xff1f; 我们可以使用 Thread 类的 Sleep()方法让线程暂停一段时间。需要注意的是&#x…

ROS1集成NanoSDK(mqtt over quic)库遇到的问题

集成方式&#xff0c;demo见附件 问题记录 ROS集成构建问题&#xff1a;如下图&#xff0c;少了依赖库导致未定义的符号

AMD优化策略

FPGA&#xff0c;英文全称是 Field Programmable Gate Array&#xff0c;中文意思是现场可编程门阵列。基本架构&#xff1a;可配置逻辑模块&#xff08;CLB&#xff1a; Configurable Logic Block&#xff09;、开关矩阵&#xff08;Switch Matrix&#xff0c;也称为 Switch B…

kraken2 最新版安装,极简模式

kraken2 git clone https://github.com/DerrickWood/kraken2.gitcd kraken2./install_kraken2.sh /opt/krakenvim .bashrc ---------------- # Kraken export PATH"/opt/kraken:$PATH" ----------------source .bashrc Note: 不晓得是不是我设置了清华源&#xff0c…

【Django学习笔记(十)】Django的创建与运行

Django的创建与运行 前言正文1、安装Django2、创建项目2.1 基于终端创建项目2.2 基于Pycharm创建项目2.3 两种方式对比 3、默认项目文件介绍4、APP5、启动运行Django5.1 激活App5.2 编写URL和视图函数对应关系5.3 启动Django项目5.3.1 命令行启动5.3.2 Pycharm启动5.3.3 views.…

Web3智能物联网:科技连接的未来世界

在当今科技飞速发展的时代&#xff0c;Web3智能物联网正逐渐成为人们关注的焦点。随着区块链技术的不断成熟和普及&#xff0c;以及物联网的普及和应用&#xff0c;Web3智能物联网作为二者的结合&#xff0c;将为未来的数字世界带来革命性的变化。本文将深入探讨Web3智能物联网…

【JavaEE 初阶(三)】多线程代码案例

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多线程知识 目录 1.前言2.单例模式2.1饿汉方式2.2饿汉方式 3.阻塞队列3.1概念3.2实现 4.定时器4.1概念4.…

Linux常用名命令

Linux是一款免费的操作系统&#xff0c;用户可以通过网络或其他途径免费获得&#xff0c;并可以任意修改源代码&#xff0c;这是其他操作系统做不到的&#xff0c;Ubuntu&#xff0c;Centos。 linux中&#xff0c;一切皆文件。 一些重要的目录 / 根目录&#xff0c;所有文件都放…

2024-05-08 精神分析-对损失和挫败的强烈易感性-分析

摘要: 对损失的强烈的易感性&#xff0c;会在遭受损失或者挫败的时候&#xff0c;表现的极其敏感&#xff0c;这个过程主要是在创业的过程中更加强烈的表现并带来巨大的影响。必须要对其进行彻底的分析&#xff0c;并保持对此行为的长期的警惕。 所谓前事不忘后事之师&#x…

JAVA IO/NIO 知识点总结

一、常见 IO 模型简介 1. 阻塞IO模型 最传统的一种IO模型&#xff0c;即在读写数据过程中会发生阻塞现象。当用户线程发出IO请求之后&#xff0c;内核会去查看数据是否就绪&#xff0c;如果没有就绪就会等待数据就绪&#xff0c;而用户线程就会处于阻塞状态&#xff0c;用户线…

WIFI模块UDP电脑端调试

一&#xff0c;两端都是电脑端 1&#xff0c;电脑本机的IP地址 192.168.137.1 2&#xff0c;新建两个不同的连接&#xff0c;注意端口 二&#xff0c;WIFI 模块和电脑端连接 1&#xff0c;设置模块端目标IP和端口&#xff0c;电脑端只接收数据的话&#xff0c;IP、端口可随…

effective python学习笔记_pythonic思维

优缺点 书的好处是很多新特性提高了可读性代码性等各方面性能&#xff0c;缺点是新特性和py老版本不兼容&#xff0c;老版本可能没有这些新特性&#xff0c;如果用了py早期版本&#xff0c;需要考虑替代方案 查py版本 import sys sys.version sys.version_info 遵循PEP8 …

python turtle

名字动画 #SquareSpiral1.py import turtle t turtle.Pen() turtle.bgcolor("black")my_nameturtle.textinput("输入你的姓名","你的名字&#xff1f;") colors["red","yellow","purple","blue"] for…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑热动态的综合能源系统碳排放流建模与分析》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

浅谈智能电气火灾监控系统的设计及应用

摘要&#xff1a;致电气火灾的原因是多方面的&#xff0c;主要成因包括漏电、绝缘层老化、短路、电火花密集、接地发生故障、电气设备自然、接触不良和电流超负荷等。文章分析电气火灾的成因&#xff0c;并探索电气火灾监控系统的设计方案与注意事项。 关键词&#xff1a;电气…

【数据结构】闲谈A股实时交易的数据结构-队列

今天有点忙&#xff0c;特意早起&#xff0c;要不先写点什么。看到个股的红红绿绿&#xff0c; 突然兴起&#xff0c;要不写篇文章分析下A股交易的简易版数据结构。 在A股实时股票交易系统中&#xff0c;按照个人理解&#xff0c;大致会用队列来完成整个交易。队列&#xff08;…

WordPress原创插件:当日24小时发布文章标题变红

WordPress原创插件&#xff1a;当日24小时发布文章标题变红 <?php// 添加自定义样式 function title_red_plugin_styles() {$current_time time();$post_time get_the_time(U);$time_difference $current_time - $post_time;if ($time_difference < 86400) {echo&l…

SSH的魅力:为何它成为远程访问的首选

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、SSH简介 2、SSH的历史与发展 3、SSH的主要用…

每日OJ题_贪心算法三③_力扣45. 跳跃游戏 II(dp解法+贪心解法)

目录 力扣45. 跳跃游戏 II 解析代码1_动态规划 解析代码2_贪心 力扣45. 跳跃游戏 II 45. 跳跃游戏 II 难度 中等 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 num…

课程作业管理系统,基于 SpringBoot+Vue+MySQL 开发的前后端分离的课程作业管理系统设计实现

目录 一. 前言 二. 功能模块 2.1. 管理员功能模块 2.2. 教师功能模块 2.3. 学生功能模块 三. 部分代码实现 四. 源码下载 一. 前言 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势…
最新文章