STM32主从定时器输出个数、频率可调的脉冲

STM32中发出脉冲一般有两种方式:

1)利用定时中断输出脉冲,但是间隔的延时会影响其他主程序的进程,当控制多个电机的时候就非常不可取;

2)利用PWM脉宽调制,并通过主从定时器进行设定,好处是不占用主程序时钟,且能精准控制;

 下面以定时器1为主,定时器2为从进行配置:

PWM.c文件

#include "stm32f10x.h"   // Device header

/***定时器1主模式,定时器2从模式***/
void TIM1_config(u16 Cycle)
{
    GPIO_InitTypeDef GPIO_InitStructure; //GPIO设置,创建结构体
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定时器设置结构体
    TIM_OCInitTypeDef  TIM_OCInitStructure; //pwm波对应设置结构体
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_TIM1 , ENABLE); //开启时钟
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    TIM_TimeBaseStructure.TIM_Period = Cycle-1;                                                   
    TIM_TimeBaseStructure.TIM_Prescaler =71;                    //设置用来作为TIMx时钟频率除数的预分频值                                                     
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //设置时钟分割:TDTS= Tck_tim            
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            //重复计数,一定要=0!!!
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);               //装载                        
 
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;          //选择定时器模式:TIM脉冲宽度调制模式1       
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_Pulse = Cycle/2-1;                    //设置待装入捕获寄存器的脉冲值                                   
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;      //输出极性       
 
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);     //装载通道1,PA8 

 
    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
    //设置或者重置 TIMx 主/从模式
    //TIMx: x 可以是 2, 3 或者 4,来选择 TIM 外设
    //TIM_MasterSlaveMode:定时器主/从模式,TIM 主/从模式使能
    
    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
    //选择 TIMx 触发输出模式
    //TIMx: x 可以是 2, 3 或者 4,来选择 TIM 外设
    //TIM_TRGOSource:触发输出模式
    //TIM_TRGOSource_Update:使用更新事件作为触发输出(TRGO)
    
 
//    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能或者失能 TIMx 在 CCR3 上的预装载寄存器

    TIM_ARRPreloadConfig(TIM1, ENABLE);  // 使能或者失能 TIMx 在 ARR 上的预装载寄存器 
    //允许或禁止在定时器工作时向ARR的缓冲器中写入新值,以便在更新事件发生时载入覆盖以前的值
}
 
/***定时器2从模式***/
void TIM2_config(u16 PulseNum)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; //对应结构体声明
    NVIC_InitTypeDef NVIC_InitStructure;  //NVIC 对应结构体声明
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
    TIM_TimeBaseStructure.TIM_Period = PulseNum-1;   
    TIM_TimeBaseStructure.TIM_Prescaler =0;    
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  
 
    TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);//选择 TIMx 输入触发源,TIM 内部触发 0      
    TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_External1 );// 等同 TIM2->SMCR|=0x07 //设置从模式寄存器 
    //   TIM2->SMCR|=0x07;                                  //设置从模式寄存器       
    TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE); //
 
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;        
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);
}
 
//入口设定函数
void Pulse_output(u16 Cycle,u16 PulseNum)
{
    TIM1_config(Cycle); //装载   
    TIM_Cmd(TIM1, ENABLE);//使能
    TIM_CtrlPWMOutputs(TIM1, ENABLE);   //高级定时器一定要加上,主输出使能

    TIM2_config(PulseNum);//装载
    TIM_Cmd(TIM2, ENABLE);//使能
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIMx 的中断待处理位
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能或者失能指定的 TIMx 中断
}
  
//中断处理函数
void TIM2_IRQHandler(void) 
{ 
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)     // TIM_IT_CC1
    { 
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位 
        TIM_CtrlPWMOutputs(TIM1, DISABLE);  //主输出使能
        TIM_Cmd(TIM1, DISABLE); // 关闭定时器 
        TIM_Cmd(TIM2, DISABLE); // 关闭定时器 
        TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);         
    } 
} 

PWM.h文件

#ifndef __PWM_H
#define __PWM_H

void Pulse_output(u16 Cycle,u16 PulseNum);//入口函数
 
void TIM1_config(u16 Cycle);//1为主模式
void TIM2_config(u16 PulseNum);//2为从模式

#endif 

主函数调用:

Pulse_output(1000,8000);//1KHZ,8000个脉冲

其中/TIM_SelectInputTrigger(TIM1, TIM_TS_ITR2);中的参数需要注意,参考手册查对应的可用连接,如下:

 问题:

ARR的值最高只能是65535,所以这种方法最多只能输出65535个脉冲。有待改进。

解决方法:(2024.10.26)

将需要发送的脉冲数拆分为高16位和低16位,没进入中断前将低16位装载到从定时器的ARR,第一次进入中断再将高16位装载到从定时器ARR,第二次进入中断关闭脉冲输出和定时器。

 完整代码:

#include "stm32f10x.h"   // 包含STM32F10x系列的设备头文件

// 定义全局变量
volatile u16 PulseNum_High = 0;  // 高16位脉冲计数
volatile u16 PulseNum_Low = 0;   // 低16位脉冲计数
volatile int pulseStage = 0;     // 脉冲阶段标志

/**
 * @brief 配置TIM1定时器
 */
void TIM1_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;  // 定义GPIO初始化结构体
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  // 定义TIM1时间基础初始化结构体
    TIM_OCInitTypeDef  TIM_OCInitStructure;  // 定义TIM1输出比较初始化结构体

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  // 使能TIM1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 使能GPIOA时钟

    // 配置GPIOA的Pin8为复用推挽输出模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置TIM1时间基础
    TIM_TimeBaseStructure.TIM_Period = 100-1;  // 定时周期为99,即100个计数周期
    TIM_TimeBaseStructure.TIM_Prescaler = 720-1;  // 预分频器为719,即720分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分频为1
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;  // 重复计数器为0
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);  // 初始化TIM1时间基础

    // 配置TIM1输出比较模式
    TIM_OCStructInit(&TIM_OCInitStructure);  // 初始化输出比较结构体
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  // PWM模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  // 输出使能
    TIM_OCInitStructure.TIM_Pulse = 50;  // 比较值为50
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  // 输出极性为高
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);  // 初始化TIM1通道1的输出比较模式

    TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);  // 使能主从模式
    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);  // 选择触发输出源为更新事件
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  // 使能通道1的CCR预装载

    TIM_ARRPreloadConfig(TIM1, ENABLE);  // 使能自动重装载寄存器预装载

    TIM_CtrlPWMOutputs(TIM1, DISABLE);  // 关闭TIM1的PWM输出
    TIM_Cmd(TIM1, DISABLE);  // 关闭TIM1
}

/**
 * @brief 配置TIM2定时器
 */
void TIM2_config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  // 定义TIM2时间基础初始化结构体
    NVIC_InitTypeDef NVIC_InitStructure;  // 定义NVIC初始化结构体

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // 使能TIM2时钟

    // 配置TIM2时间基础
    TIM_TimeBaseStructure.TIM_Period = 65535;  // 定时周期为65535
    TIM_TimeBaseStructure.TIM_Prescaler = 0;  // 预分频器为0
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分频为1
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  // 初始化TIM2时间基础

    TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);  // 选择输入触发源为内部触发器0
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);  // 选择从模式为外部触发模式1

    TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);  // 禁用TIM2更新中断
    TIM_ARRPreloadConfig(TIM2, ENABLE);  // 使能自动重装载寄存器预装载

    // 配置NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 配置优先级分组为2
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  // 中断通道为TIM2
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  // 抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  // 子优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);  // 初始化NVIC

    TIM_Cmd(TIM2, DISABLE);  // 关闭TIM2
}

/**
 * @brief 输出指定周期和数量的脉冲
 * @param Cycle 周期值,对应TIM1的ARR
 * @param PulseNum 脉冲数量,最大为65535
 */
void Pulse_output(u16 Cycle, u32 PulseNum)
{
    // 如果脉冲数量大于65535,则需要使用高位和低位计数
    if(PulseNum >= 65536)
    {
        PulseNum_High = (PulseNum >> 16) * 65536 - 1;  // 计算高16位计数值
        PulseNum_Low = (PulseNum & 0xFFFF) - 1;  // 计算低16位计数值
        pulseStage = 0;  // 设置脉冲阶段为高16位
    }
    else
    {
        PulseNum_High = 0;  // 高16位计数值为0
        PulseNum_Low = (PulseNum & 0xFFFF) - 1;  // 计算低16位计数值
        pulseStage = 1;  // 设置脉冲阶段为低16位
    }

    TIM1_config();  // 配置TIM1
    TIM2_config();  // 配置TIM2

    TIM_Cmd(TIM2, DISABLE);  // 关闭TIM2
    TIM_SetAutoreload(TIM2, PulseNum_Low);  // 设置TIM2的自动重装载寄存器为低16位计数值
    TIM_GenerateEvent(TIM2, TIM_EventSource_Update);  // 触发TIM2更新事件以更新ARR
    TIM_Cmd(TIM2, ENABLE);  // 开启TIM2
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除TIM2更新中断标志

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // 使能TIM2更新中断
    TIM_SetAutoreload(TIM1, Cycle);  // 设置TIM1的自动重装载寄存器为周期值
    TIM_GenerateEvent(TIM1, TIM_EventSource_Update);  // 触发TIM1更新事件以更新ARR
    TIM_SetCompare1(TIM1, Cycle / 2);  // 设置TIM1的比较值为周期值的一半,以生成50%占空比的PWM
    TIM_GenerateEvent(TIM1, TIM_EventSource_CC1);  // 触发TIM1捕获/比较事件
    TIM_CtrlPWMOutputs(TIM1, ENABLE);  // 开启TIM1的PWM输出
    TIM_Cmd(TIM1, ENABLE);  // 开启TIM1
}

/**
 * @brief TIM2中断服务函数
 */
void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  // 检查是否为TIM2更新中断
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除TIM2更新中断标志

        if (pulseStage == 0)  // 如果处于高16位计数阶段
        {
            pulseStage = 1;  // 切换到低16位计数阶段
            TIM_Cmd(TIM2, DISABLE);  // 关闭TIM2
            TIM_SetAutoreload(TIM2, PulseNum_High);  // 设置TIM2的自动重装载寄存器为高16位计数值
            TIM_GenerateEvent(TIM2, TIM_EventSource_Update);  // 触发TIM2更新事件以更新ARR
            TIM_Cmd(TIM2, ENABLE);  // 开启TIM2
            TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  // 清除TIM2更新中断标志
            TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // 使能TIM2更新中断
        }
        else  // 如果处于低16位计数阶段
        {
            // 脉冲输出完成,停止定时器
            TIM_CtrlPWMOutputs(TIM1, DISABLE);  // 关闭TIM1的PWM输出
            TIM_Cmd(TIM1, DISABLE);  // 关闭TIM1
            TIM_Cmd(TIM2, DISABLE);  // 关闭TIM2
            TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);  // 禁用TIM2更新中断
        }
    }
}

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

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

相关文章

研发效能度量核心三问:看什么、怎么看、怎么说服团队

问题 1:研发效能度量指标应该看什么? 在探讨研发效能度量时,首要步骤是广泛了解并学习业界认可的成熟指标及其指向性。明确指标的指向性后,面对众多度量项,应采用 GQM(Goal-Question-Metric)方…

java多线程父子参数传递失败问题

java在一个父线程中启动了一个子线程 但是运行过程中父线程的参数没有传递到子线程 原因&#xff1a;threadLocal不支持父子线程传递 解决&#xff1a;使用TransmittableThreadLocal --有问题的代码 private static final ThreadLocal<EventRuntimeContext> FLOW_CO…

TIFS-2024 细粒度表示和重组在换衣行人重识别中的应用

总体结论 本文提出了一种新的细粒度表示与重构&#xff08;FIRe2&#xff09;框架&#xff0c;用于解决布变人重识别问题。通过细粒度特征挖掘和属性重构&#xff0c;FIRe2在不依赖任何辅助信息的情况下&#xff0c;实现了最先进的性能。该方法在多个基准数据集上取得了显著的…

PostgreSQL的前世今生

PostgreSQL的起源可以追溯到1977年的加州大学伯克利分校&#xff08;UC Berkeley&#xff09;的Ingres项目。该项目由著名的数据库科学家Michael Stonebraker领导&#xff0c;他是2015年图灵奖的获得者。以下是PostgreSQL起源的详细概述&#xff1a; 一、早期发展 Ingres项目…

DAY43 ||322.零钱兑换 |279.完全平方数 |139.单词拆分

322.零钱兑换 题目&#xff1a;322. 零钱兑换 - 力扣&#xff08;LeetCode&#xff09; 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬…

WebGL进阶(五)-可视域

理论基础&#xff1a; 顶点着色器 Vertex Shader 主要是负责处理顶点位置、顶点颜色、顶点向量等顶点的数据&#xff1b;处理一些顶点的变换&#xff1a;例如在进行视图变换和投影变换时MVP矩阵会改变顶点的位置信息。 输入&#xff1a; 顶点着色器输入部分主要是声明&…

gin入门教程(10):实现jwt认证

使用 github.com/golang-jwt/jwt 实现 JWT&#xff08;JSON Web Token&#xff09;可以有效地进行用户身份验证,这个功能往往在接口前后端分离的应用中经常用到。以下是一个基本的示例&#xff0c;演示如何在 Gin 框架中实现 JWT 认证。 目录结构 /hello-gin │ ├── cmd/ …

三星瞄准2026年推出400层垂直NAND技术,2030年前剑指1000层NAND闪存

据报道&#xff0c;三星计划在2026年前推出400层的垂直NAND闪存&#xff0c;并且目标是在2030年前实现1000层的NAND技术。随着人工智能&#xff08;AI&#xff09;浪潮的到来&#xff0c;高带宽内存&#xff08;HBM&#xff09;已经成为存储巨头之间的关键战场&#xff0c;而同…

端口号和ip地址一样吗?区别是什么

在网络通信的世界里&#xff0c;端口号和IP地址是两个不可或缺的概念&#xff0c;它们各自扮演着独特的角色&#xff0c;共同维系着数据在网络中的有序传输。然而&#xff0c;对于许多初学者而言&#xff0c;这两者往往容易被混淆&#xff0c;认为它们是同一事物的不同表述。那…

前端自学资料(笔记八股)分享—CSS(4)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

JavaScript字符串不可变性与ES6 新增字符串方法详解

非 VIP 用户可前往公众号“前端基地”进行免费阅读,文章链接如下: JavaScript字符串不可变性与ES6 新增字符串方法详解本文介绍了 JavaScript 中字符串的不可变性以及 ES6 新增的字符串方法。包括判断是否包含、以指定字符串开头或结尾,还有重复指定次数等方法,并结合案例…

鸿蒙开发:arkTS FolderStack容器组件

ArkTS(也称为Ark TypeScript)是鸿蒙生态的应用开发语言&#xff0c;它在TypeScript(简称TS)的基础上进行了优化和定制&#xff0c;以满足鸿蒙系统的开发需求。今天给大家分享arkTS FolderStack容器组件技术知识&#xff0c;如果有所帮助&#xff0c;大家点点关注支持一下&#…

SSL/TLS 密码套件漏洞分析以及修复方法

1. 前言 在当今数字化时代&#xff0c;网络安全至关重要。SSL/TLS 协议作为保障网络通信安全的重要手段&#xff0c;广泛应用于各类网络应用中。然而&#xff0c;如同任何技术一样&#xff0c;SSL/TLS 也并非绝对安全&#xff0c;存在着一些可能被攻击者利用的漏洞。本文将深入…

如何加密电脑磁盘?电脑本地磁盘加密方法介绍

随着信息技术的不断发展&#xff0c;电脑磁盘加密已经成为保护个人隐私和数据安全的重要手段。本文将介绍几种常见的电脑本地磁盘加密方法&#xff0c;帮助用户保护自己的数据安全。 文件夹只读加密专家 文件夹只读加密专家不仅可以加密电脑中的文件夹&#xff0c;还可以加密保…

已解决Navicat 选择Mysql表 报错unkonow internal error: Access violation - no RTTI data

已解决Navicat 选择Mysql表 报错unkonow internal error&#xff1a; Access violation - no RTTI data 报错信息截图&#xff1a; 使用Navicat Premium15 选择sql server表时 出现大量弹窗报错&#xff0c;导致sql文件执行不了&#xff0c;右键数据库执行外部文件也失败了。弹…

【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用

目录 &#x1f354; XGBoost 原理 1.1 目标函数确定和树的复杂度介绍 1.2 XGBoost目标函数的推导 1.3 泰勒公式展开 1.4 化简目标函数 1.5 问题再次转换 1.6 对叶子结点求导 1.7 XGBoost的回归树构建方法 &#x1f354; XGBoost API 2.1 通用参数 2.2 Booster 参数 …

基于vue框架的的高校学习资源共享系统5ym3y(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,学校信息,课程分类,班课信息,班课申请,学习资源,班课评价,班课投诉,投诉学生,教师,班级 开题报告内容 基于Vue框架的高校学习资源共享系统开题报告 一、项目背景与意义 随着信息技术的飞速发展和教育改革的深入推进&#xff0c;…

Hadoop生态圈框架部署(二)- 配置IP地址映射为主机名及免密登录

文章目录 前言一、配置IP地址映射为主机名1. 虚拟机hadoop1配置主机名与 IP 地址的映射关系2. 虚拟机hadoop2配置主机名与 IP 地址的映射关系3. 虚拟机hadoop3配置主机名与 IP 地址的映射关系 二、配置免密登录1. 配置虚拟机hadoop1免密登录到hadoop1、hadoop2和hadoop32. 配置…

基于JSP的篮球系列网上商城系统【附源码】

基于JSP的篮球系列网上商城系统 效果如下&#xff1a; 系统首页界面 商品信息界面 购物车界面 购物车界面 管理员登录界面 管理员功能界面 用户注册界面 我的收藏界面 研究背景 21世纪&#xff0c;我国早在上世纪就已普及互联网信息&#xff0c;互联网对人们生活中带来了无限…

力扣题86~90

题86&#xff08;中等&#xff09;&#xff1a; python代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def partition(self, head: Optional[Li…