_STM32关于CPU超频的参考_HAL
MCU: STM32F407VET6
官方最高稳定频率:168MHz
工具:STM32CubeMX
本篇仅仅只是提供超频(默认指的是主频)的简单方法,并未涉及STM32超频极限等问题。原理很简单,通过设置锁相环的倍频系数达到不同的频率,从而实现超频。需要注意的是,运行时切换频率不能直接修改,因为此时用的HSE时钟是经由锁相环产生的,直接修改锁相环会出现问题。解决办法是,切换为HSI并关闭锁相环,然后重新配置锁相环,最后再重新切换HSE。
最后切记,超频有风险!!
一、时钟配置
使用STM32CubeMX可以很方便地配置时钟树,配置时钟树时需要先知道开发板所用的外部晶振频率。从下图可知晓,使用的外部晶振为12MHz
然后经由STM32CubeMX自动配置时钟树,从这里可以看到锁相环里能看到M、N、P三个参数,其中N是倍频系数,最高可达432。这里我们目标是配置为168MHz,即官方标称频率
使用STM32CubeMX生成代码后,我们可以在Core/Src目录下找到main.c中的SystemClock_Config函数。从代码中可以轻易看到,PLLM、PLLN、PLLP就是前面看到的M、N、P三个参数。同时由于外部晶振频率为12MHz,自动配置过程中,M和P分频系数分别为6和2恰好可以把12MHz分频为1MHz,使得倍频系数即为主频频率(MHz)。
后面超频时,利用的就是下面代码。
void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 6;RCC_OscInitStruct.PLL.PLLN = 168;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();} }
二、超频
根据前面所言,运行时直接修改所用的时钟会发生错误,所以需要切换时钟源后再修改。下面两个函数用于切换时钟源
void SystemClock_SwitchToHSI(void) {// 将系统时钟切换到 HSI__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSI);// 等待时钟切换完成while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) {} }void SystemClock_SwitchToPLL(void) {// 将系统时钟切换到 PLL__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);// 等待时钟切换完成while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {} }
接下来,在系统时钟配置函数的基础上,修改代码。在配置PLL前,先禁用全局中断,防止时钟中断等影响配置过程,然后切换时钟源为HSI并禁用锁相环
// 禁用全局中断__disable_irq();// 切换到 HSISystemClock_SwitchToHSI();// 禁用 PLL__HAL_RCC_PLL_DISABLE();
然后是配置PLL过程,此时参考系统时钟初始化代码,其中plln是传入的形参变量(锁相环倍频系数)。需要注意的是主频频率提高后,Flash的等待周期要相应延长,原为FLASH_LATENCY_5,这里简单判断了一下,如果大于168MHz,就延长为FLASH_LATENCY_7
// 配置 PLLRCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 6; // HSE 分频系数RCC_OscInitStruct.PLL.PLLN = plln; // PLL 倍频系数RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLP 分频系数RCC_OscInitStruct.PLL.PLLQ = 4; // PLLQ 分频系数if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}// 配置系统时钟RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;// 设置 Flash 等待周期uint32_t flash_latency = (plln <= 168) ? FLASH_LATENCY_5 : FLASH_LATENCY_7;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, flash_latency) != HAL_OK){Error_Handler();}
最后是切换为PLL,并重新启用全局中断
// 切换到 PLLSystemClock_SwitchToPLL();// 重新启用全局中断__enable_irq();
完整代码如下,再次提醒,此代码是以外部晶振为12MHz的前提下有STM32CubeMX生成的,使用时需根据自身情况修改
/*** @brief 设置系统时钟频率* @param plln 锁相环倍频* @details 基于外部晶振为12MHz的配置*/ void SystemClock_SetFrequency(uint32_t plln) {// 禁用全局中断__disable_irq();// 切换到 HSISystemClock_SwitchToHSI();// 禁用 PLL__HAL_RCC_PLL_DISABLE();// 配置 PLLRCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 6; // HSE 分频系数RCC_OscInitStruct.PLL.PLLN = plln; // PLL 倍频系数RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // PLLP 分频系数RCC_OscInitStruct.PLL.PLLQ = 4; // PLLQ 分频系数if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}// 配置系统时钟RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;// 设置 Flash 等待周期uint32_t flash_latency = (plln <= 168) ? FLASH_LATENCY_5 : FLASH_LATENCY_7;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, flash_latency) != HAL_OK){Error_Handler();}// 切换到 PLLSystemClock_SwitchToPLL();// 重新启用全局中断__enable_irq(); }
此时可另写两个函数,其一为默认配置,以便能从超频状态返回标准状态;其二为超频状态,建议不要设太高,推荐200~216MHz。提高主频后,也会提高其他时钟线,进而会对外设产生影响。此时需要注意一些如USB、以太网等对频率要求很高的外设,需要重新设置参数。
/*** @brief 超频* @param 无* @retval 无* @details 通过超频可以提升至 200MHz~216MHz,这里默认使用216MHz*/void SystemClock_Overclock() {SystemClock_SetFrequency(216); }
/*** @brief 默认系统时钟初始化* @details 最高稳定频率为168MHz*/ void SystemClock_DefaultConfig() {SystemClock_SetFrequency(168); }
HAL中,对定时器的频率设置是依赖于全局变量SystemCoreClock,由HAL_RCC_ClockConfig来更新,使用HAL_RCC_GetPCLK1Freq等函数可以实现自动纠正频率,下面代码可以作为参考
#include "stm32f4xx_hal.h"/*** @brief 设置定时器频率* @param htim: 定时器句柄(如 &htim2)* @param target_freq: 目标频率(单位:Hz)* @retval HAL_StatusTypeDef: 成功返回 HAL_OK,失败返回 HAL_ERROR*/ HAL_StatusTypeDef Timer_SetFrequency(TIM_HandleTypeDef *htim, uint32_t target_freq) {uint32_t timer_clock_freq; // 定时器时钟源频率uint32_t psc_value; // 预分频器值// 获取 APB 总线时钟频率if (htim->Instance == TIM2 || htim->Instance == TIM3 || htim->Instance == TIM4 || htim->Instance == TIM5 ||htim->Instance == TIM9 || htim->Instance == TIM10 || htim->Instance == TIM11){// APB1 定时器timer_clock_freq = HAL_RCC_GetPCLK1Freq();if (RCC->CFGR & RCC_CFGR_PPRE1_2) // 检查 APB1 预分频器{timer_clock_freq *= 2; // 如果预分频器不为 1,时钟频率乘以 2}}else{// APB2 定时器timer_clock_freq = HAL_RCC_GetPCLK2Freq();if (RCC->CFGR & RCC_CFGR_PPRE2_2) // 检查 APB2 预分频器{timer_clock_freq *= 2; // 如果预分频器不为 1,时钟频率乘以 2}}// 检查目标频率是否有效if (target_freq == 0 || target_freq > timer_clock_freq){return HAL_ERROR; // 目标频率无效}// 计算预分频器值psc_value = (timer_clock_freq / target_freq) - 1;// 检查预分频器值是否超出范围if (psc_value > 0xFFFF){return HAL_ERROR; // 预分频器值超出 16 位范围}// 设置定时器预分频器__HAL_TIM_SET_PRESCALER(htim, psc_value);return HAL_OK; }
其参考的是STM32CubeMX生成的“系统”定时器(这里使用的是TIM7)的初始化代码
/*用于配置供HAL使用基础时钟,频率为1KHz*/ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {RCC_ClkInitTypeDef clkconfig;uint32_t uwTimclock, uwAPB1Prescaler = 0U;uint32_t uwPrescalerValue = 0U;uint32_t pFLatency;HAL_StatusTypeDef status;/* Enable TIM7 clock */__HAL_RCC_TIM7_CLK_ENABLE();/* Get clock configuration */HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);/* Get APB1 prescaler */uwAPB1Prescaler = clkconfig.APB1CLKDivider;/* Compute TIM7 clock */if (uwAPB1Prescaler == RCC_HCLK_DIV1){uwTimclock = HAL_RCC_GetPCLK1Freq();} else{uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();}/* Compute the prescaler value to have TIM7 counter clock equal to 1MHz */uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);/* Initialize TIM7 */htim7.Instance = TIM7;/* Initialize TIMx peripheral as follow:+ Period = [(TIM7CLK/1000) - 1]. to have a (1/1000) s time base.+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.+ ClockDivision = 0+ Counter direction = Up*/htim7.Init.Period = (1000000U / 1000U) - 1U;htim7.Init.Prescaler = uwPrescalerValue;htim7.Init.ClockDivision = 0;htim7.Init.CounterMode = TIM_COUNTERMODE_UP;htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 考虑到LVGL初始化会死循环status = HAL_TIM_Base_Init(&htim7);if (status == HAL_OK){/* Start the TIM time Base generation in interrupt mode */status = HAL_TIM_Base_Start_IT(&htim7);if (status == HAL_OK){/* Enable the TIM7 global Interrupt */HAL_NVIC_EnableIRQ(TIM7_IRQn);/* Configure the SysTick IRQ priority */if (TickPriority < (1UL << __NVIC_PRIO_BITS)){/* Configure the TIM IRQ priority */HAL_NVIC_SetPriority(TIM7_IRQn, TickPriority, 0U);uwTickPrio = TickPriority;} else{status = HAL_ERROR;}}}/* Return function status */return status; }
相关文章:

_STM32关于CPU超频的参考_HAL
MCU: STM32F407VET6 官方最高稳定频率:168MHz 工具:STM32CubeMX 本篇仅仅只是提供超频(默认指的是主频)的简单方法,并未涉及STM32超频极限等问题。原理很简单,通过设置锁相环的倍频系数达到不同的频率&am…...

C#,图论与图算法,任意一对节点之间最短距离的弗洛伊德·沃肖尔(Floyd Warshall)算法与源程序
一、弗洛伊德沃肖尔算法 Floyd-Warshall算法是图的最短路径算法。与Bellman-Ford算法或Dijkstra算法一样,它计算图中的最短路径。然而,Bellman Ford和Dijkstra都是单源最短路径算法。这意味着他们只计算来自单个源的最短路径。另一方面,Floy…...

AWS云计算概览(自用留存,整理中)
目录 一、云概念概览 (1)云计算简介 (2)云计算6大优势 (3)web服务 (4)AWS云采用框架(AWS CAF) 二、云经济学 & 账单 (1)定…...
1. npm 常用命令详解
npm 常用命令详解 npm(Node Package Manager)是 Node.js 的包管理工具,用于安装和管理 Node.js 应用中的依赖库。下面是 npm 的一些常用命令及其详细解释和示例代码。 镜像源 # 查询当前使用的镜像源 npm get registry# 设置为淘宝镜像源 …...
js:根据后端返回数据的最大值进行计算然后设置这个最大值为百分之百,其他的值除这个最大值
问: 现在tabData.value 接收到了后端返回的数据, [{text:人力,percentage:‘90’},{text:物品,percentage:‘20’},{text:物理,percentage:‘50’},{text:服务,percentageÿ…...

【Spring】@Size 无法拦截null的原因
问题复现 在构建 Web 服务时,我们一般都会对一个 HTTP 请求的 Body 内容进行校验,例如我们来看这样一个案例及对应代码。当开发一个学籍管理系统时,我们会提供了一个 API 接口去添加学生的相关信息,其对象定义参考下面的代码&…...

【Block总结】掩码窗口自注意力 (M-WSA)
摘要 论文链接:https://arxiv.org/pdf/2404.07846 论文标题:Transformer-Based Blind-Spot Network for Self-Supervised Image Denoising Masked Window-Based Self-Attention (M-WSA) 是一种新颖的自注意力机制,旨在解决传统自注意力方法在…...
用 HTML5 Canvas 和 JavaScript 实现雪花飘落特效
这篇文章将带您深入解析使用 HTML5 Canvas 和 JavaScript 实现动态雪花特效的代码原理。 1,效果展示 该效果模拟了雪花从天而降的动态场景,具有以下特点: 雪花数量、大小、透明度和下落速度随机。雪花会在屏幕底部重置到顶部,形成循环效果。随窗口大小动态调整,始终覆盖…...
【cocos creator】【ts】事件派发系统
触发使用: EventTool.emit(“onClick”) 需要监听的地方,onload调用: EventTool.on(“onClick”, this.onClickEvent, this) /**事件派发*/class EventTool {protected static _instance: EventTool null;public static get Instance(): Eve…...
《探索鸿蒙Next上开发人工智能游戏应用的技术难点》
在科技飞速发展的当下,鸿蒙Next系统为应用开发带来了新的机遇与挑战,开发一款运行在鸿蒙Next上的人工智能游戏应用更是备受关注。以下是在开发过程中可能会遇到的一些技术难点: 鸿蒙Next系统适配性 多设备协同:鸿蒙Next的一大特色…...

CSS | CSS实现两栏布局(左边定宽 右边自适应,左右成比自适应)
目录 一、左边定宽 右边自适应 1.浮动 2.利用浮动margin 3.定位margin 4.flex布局 5.table 布局 二、左右成比自适应 1:1 1flex布局 table布局 1:2 flex布局 <div class"father"><div class"left">左边自适应</div><div class"r…...
acwing_3195_有趣的数
acwing_3195_有趣的数 // // Created by HUAWEI on 2024/11/17. // #include<iostream> #include<cstring> #include<algorithm>#define int long longusing namespace std;const int N 1000 50; const int MOD 1e9 7; int C[N][N]; //组合数signed mai…...
Liunx-搭建安装VSOMEIP环境教程 执行 运行VSOMEIP示例demo
本文安装环境为Liunx,搭建安装VSOMEIP环境并运行基础例子。 1. 安装基础环境 使用apt-get来安装基础环境,受网络影响可以分开多次安装。环境好的也可以一次性执行。 sudo apt-get install gcc g sudo apt-get install cmake sudo apt-get install lib…...
Git | git revert命令详解
关注:CodingTechWork 引言 Git 是一个强大的版本控制工具,广泛应用于现代软件开发中。它为开发人员提供了多种功能来管理代码、协作开发和版本控制。在 Git 中,有时我们需要撤销或回退某些提交,而git revert 是一个非常有用的命令…...
ASP.NET Core 中,Cookie 认证在集群环境下的应用
在 ASP.NET Core 中,Cookie 认证在集群环境下的应用通常会遇到一些挑战。主要的问题是 Cookie 存储在客户端的浏览器中,而认证信息(比如 Session 或身份令牌)通常是保存在 Cookie 中,多个应用实例需要共享这些 Cookie …...

Flyte工作流平台调研(五)——扩展集成
系列文章: Flyte工作流平台调研(一)——整体架构 Flyte工作流平台调研(二)——核心概念说明 Flyte工作流平台调研(三)——核心组件原理 Flyte工作流平台调研(四)——…...

【AUTOSAR 基础软件】软件组件的建立与使用(“代理”SWC)
基础软件往往需要建立一些“代理”SWC来完成一些驱动的抽象工作(Complex_Device_Driver_Sw或者Ecu_Abstraction_Sw等),或建立Application Sw Component来补齐基础软件需要提供的功能实现。当面对具体的项目时,基础软件开发人员还可…...
java通过ocr实现识别pdf中的文字
需求:识别pdf文件中的中文 根据github项目mymonstercat 改造,先将pdf文件转为png文件存于临时文件夹,然后通过RapidOcr转为文字,最后删除临时文件夹 1、引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId&g…...

Git 命令代码管理详解
一、Git 初相识:版本控制的神器 在当今的软件开发领域,版本控制如同基石般重要,而 Git 无疑是其中最耀眼的明珠。它由 Linus Torvalds 在 2005 年创造,最初是为了更好地管理 Linux 内核源代码。随着时间的推移,Git 凭借…...
Docker的安装和使用
容器技术 容器与虚拟机的区别 虚拟机 (VM) VM包含完整的操作系统,并在虚拟化层之上运行多个操作系统实例。 VM需要更多的系统资源(CPU、内存、存储)来管理这些操作系统实例。 容器 (Container) 容器共享主机操作系统的内核,具…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...