普冉(PUYA)单片机开发笔记(5): 配置定时器PWM输出

news2024/11/17 10:33:12

概述

定时器的输出通道作为 PWM 驱动是 MCU 的常用功能。

PY32F003 有一个高级定时器 TIM1 和一个通用定时器 TIM3,这两个定时器都可以驱动4个输出通道。现在我们就利用 TIM1 的某一个通道实现可控占空比的 PWM 输出。

原理简介

看数据手册,简单摘录如下。

关于 TIM1 的描述,厂家的《Reference_manual v1.1.pdf》中很详细了,内容很多,这里不再详述了。不说废话,上代码吧。

实现代码

使用 SystemClock_Config 函数选择 HSE

/********************************************************************************************************
**函数信息 :void SystemClock_Config(void)
**功能描述 :系统时钟配置
**输入参数 :
**输出参数 :
**    备注 :
********************************************************************************************************/
HAL_StatusTypeDef SystemClock_Config(void)
{
    HAL_StatusTypeDef conf_res= HAL_OK;
    
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE |
                                       RCC_OSCILLATORTYPE_HSI | 
                                       RCC_OSCILLATORTYPE_LSI;              // 配置时钟源HSE/HSI/LSE/LSI
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;                                // 开启HSI
    RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;                                // 不分频
    //RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_8MHz;      // 配置HSI输出时钟为8MHz
    //RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz;      // 配置HSI输出时钟为4MHz
    //RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz;     // 配置HSI输出时钟为16MHz
    //RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_22p12MHz;  // 配置HSI输出时钟为22.12MHz
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz;       // 配置HSI输出时钟为24MHz
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;                                // 开启 HSE
    RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz;                           // HSE工作频率范围16M~32M
    RCC_OscInitStruct.LSIState = RCC_LSI_OFF;                               // 关闭 LSI
    conf_res = HAL_RCC_OscConfig(&RCC_OscInitStruct);                       // 初始化RCC振荡器
    if (conf_res != HAL_OK)                                                 
        return conf_res;


    //初始化CPU,AHB,APB总线时钟
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | 
                                  RCC_CLOCKTYPE_SYSCLK | 
                                  RCC_CLOCKTYPE_PCLK1;      // RCC系统时钟类型
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;  // SYSCLK的源选择为HSE
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;      // APH时钟不分频
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;       // APB时钟不分频
    conf_res = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); // 初始化RCC系统时钟
                                                                         // (FLASH_LATENCY_0=24M以下;
                                                                         // FLASH_LATENCY_1=48M)
    if (conf_res != HAL_OK)  
        return conf_res;
    
    return HAL_OK;
}

和先前开发笔记中的相同,选用 HSE 作为 TIM 子系统的时钟。重要的语句是

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE; 
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

这三句,设置TIM 子系统的总线频率和 HSE 相同(24MHz)。

SystemClock_Config 函数存放在 Application/User 组的 app.c 文件中。

main.h 声明 TIM1_PWM 相关的几个函数

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "py32f0xx_hal.h"
#include "py32f003xx_Start_Kit.h"
#include <stdbool.h>

/* Exported functions prototypes ---------------------------------------------*/
HAL_StatusTypeDef SystemClock_Config(void);
HAL_StatusTypeDef GPIO_Config(void);
HAL_StatusTypeDef USART_Config(void);
HAL_StatusTypeDef DBG_UART_Start(void);
HAL_StatusTypeDef TIM16_Config(void);
HAL_StatusTypeDef TIM16_Start(void);

/**
 * ------------------------------------------------------
 * Added for TIM1 and PWM output.
 * Marked by HardCoder_LLuo@2023-12-07
 */
HAL_StatusTypeDef TIM1_PWM_Config(void);
HAL_StatusTypeDef TIM1_PWM_Start(uint32_t duty);
HAL_StatusTypeDef TIM1_PWM_Stop(void);
void TIM1_PWM_Output(const uint8_t duty_percent);
/* ------------------------------------------------------
*/

void Debug_Info(const char* msg);

......
......

在 app_pwm.c 中编写代码

在 Application/User 组加入 app_pwm.c 文件,编写在 main.h 中声明的函数。

/**
 ******************************************************************************
 * @file    app_pwm.c
 * @brief   Application level PWM codes.
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2023 CuteModem Intelligence.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
 
#include "main.h"

#define PWM_PERIOD 1200

TIM_HandleTypeDef  htim1;
TIM_OC_InitTypeDef cfg_tim1;

HAL_StatusTypeDef TIM1_PWM_Config(void)
{
    HAL_StatusTypeDef cfg_res = HAL_OK;
    
    htim1.Instance = TIM1;                                                  // 选择TIM1
    htim1.Init.Period            = PWM_PERIOD - 1;                                // 自动重装载值,和Prescaler可确定PWM的频率
    htim1.Init.Prescaler         = 1 - 1;                                   // 预分频为1-1
    htim1.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;                  // 时钟不分频
    htim1.Init.CounterMode       = TIM_COUNTERMODE_UP;                      // 向上计数
    htim1.Init.RepetitionCounter = 1 - 1;                                   // 不重复计数
    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;          // 自动重装载寄存器无缓冲
    cfg_res = HAL_TIM_Base_Init(&htim1);                                    // 初始化
    if (cfg_res != HAL_OK)              
    {
        return cfg_res;
    }
    
    cfg_tim1.OCMode       = TIM_OCMODE_PWM1;                                // 输出配置为模式1
    cfg_tim1.OCPolarity   = TIM_OCPOLARITY_HIGH;                            // OC通道输出高电平有效
    cfg_tim1.OCFastMode   = TIM_OCFAST_DISABLE;                             // 输出快速使能关闭
    cfg_tim1.OCNPolarity  = TIM_OCNPOLARITY_HIGH;                           // OCN通道输出高电平有效
    cfg_tim1.OCNIdleState = TIM_OCNIDLESTATE_RESET;                         // 空闲状态OC1N输出低电平
    cfg_tim1.OCIdleState  = TIM_OCIDLESTATE_RESET;                          // 空闲状态OC1输出低电平
    cfg_tim1.Pulse        = 0;                                              // CC1值为0,相当于复位PWM输出
    cfg_res = HAL_TIM_OC_ConfigChannel(&htim1, &cfg_tim1, TIM_CHANNEL_1);   // OC1配置通道
    if (cfg_res != HAL_OK) return cfg_res;
        
    cfg_res = HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);                      // OC1通道开始输出
    if ( cfg_res != HAL_OK) return cfg_res;
    
    return cfg_res;
}

HAL_StatusTypeDef TIM1_PWM_Start(uint32_t duty)
{
    HAL_StatusTypeDef cfg_res = HAL_OK;
    
    cfg_tim1.Pulse = duty - 1;                                              // CC1值为duty,PWM平均=duty/period
    cfg_res = HAL_TIM_OC_ConfigChannel(&htim1, &cfg_tim1, TIM_CHANNEL_1);   // OC1配置通道
    if (cfg_res != HAL_OK) return cfg_res;
    
    cfg_res = HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);                      // OC1通道开始输出
    if ( cfg_res != HAL_OK) return cfg_res;
    
    return cfg_res;
}

HAL_StatusTypeDef TIM1_PWM_Stop(void)
{
    return HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
}

void TIM1_PWM_Output(const uint8_t duty_percent)
{
    uint8_t  tmp_duty = 0;
    uint32_t duty     = 0;
    
    tmp_duty = duty_percent;
    if(duty_percent > 100) tmp_duty = 100;
    duty = (uint32_t)(tmp_duty * PWM_PERIOD / 100.0F + 0.5F) + 1;
    TIM1_PWM_Start(duty);
}

在 py32_f0xx_hal_msp.c 中增加对复用管脚的初始化

/**
  ******************************************************************************
  * @file    py32f0xx_hal_msp.c
  * @author  MCU Application Team
  * @Version V1.0.0
  * @Date    2020-10-19
  * @brief   This file provides code for the MSP Initialization
  *          and de-Initialization codes.
  ******************************************************************************
  */


/* Includes ------------------------------------------------------------------*/
#include "main.h"


/**
  * Initializes the Global MSP.
  */

void HAL_MspInit(void)
{
    BSP_LED_Init(LED_GREEN);
    BSP_PB_Init(BUTTON_USER,BUTTON_MODE_GPIO);
}

/**
 * -----------------------------------------------------------------------
 * @name   : void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
 * @brief  : 功能描述 :初始化TIM相关MSP
 * @param  : [in] htim, TIM handler pointer
 * @retval : void
 * @remark :
 * -----------------------------------------------------------------------
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM16)
    {
        __HAL_RCC_TIM16_CLK_ENABLE();           //使能TIM16时钟
        HAL_NVIC_SetPriority(TIM16_IRQn, 0, 8); //设置中断优先级
        HAL_NVIC_EnableIRQ(TIM16_IRQn);         //使能TIM1中断
        
        return;
    }
    
    if(htim->Instance == TIM1)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        
        __HAL_RCC_TIM1_CLK_ENABLE();                  // TIM1 时钟使能
        __HAL_RCC_GPIOA_CLK_ENABLE();                 // GPIOA 时钟使能
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;       // 复用
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;         // 下拉
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
        GPIO_InitStruct.Pin = GPIO_PIN_3;             // PA3 初始化成 TIM1_CH1
        GPIO_InitStruct.Alternate = GPIO_AF13_TIM1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}

在 py32_f0xx_hal_it.c 中增加对中断服务程序的重定向

extern TIM_HandleTypeDef  htim16;
extern TIM_HandleTypeDef  htim1;

...
...

// Override. For TIM1_PWM service
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim1);
}

...
...

void TIM16_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim16);
}

在 main.c 中添加对这些功能的调用

/**
* -------------------------------------------------------------------------
* @file   : int main(void)
* @brief  : main函数
* @param  : 无
* @retval : 无限循环,无返回值
* @remark : 
* -------------------------------------------------------------------------
*/
int main(void)
{
    HAL_Init();             // systick初始化
    SystemClock_Config();   // 配置系统时钟
    
    if(USART_Config() != HAL_OK) Error_Handler();         
    printf("[SYS_INIT] Debug port initilaized.\r\n");
    
    if(GPIO_Config() != HAL_OK) Error_Handler();          
    printf("[SYS_INIT] Board LED initilaized.\r\n");
    
    if(TIM16_Config() != HAL_OK) Error_Handler();
    printf("[SYS_INIT] Timer initialized.\r\n");
    
    if (TIM16_Start() != HAL_OK) Error_Handler();
    printf("[SYS_INIT] Timer started.\r\n");
    
    /**
     *   Added for TIM1 PWM output
     *   By HardCoder_LLuo@2023-12-07
     */
    if(TIM1_PWM_Config() != HAL_OK) Error_Handler();
    printf("[SYS_INIT] PWM initialized.\r\n");
    
    printf("\r\n+---------------------------------------+"
           "\r\n|        PY32F003 MCU is ready.         |"
           "\r\n+---------------------------------------+"
           "\r\n");

    if (DBG_UART_Start() != HAL_OK) Error_Handler();
    
    TIM1_PWM_Output(0);
        
//    while(BSP_PB_GetState(BUTTON_USER) != 0){}
//    TIM1_PWM_Output(20);
        
    while(BSP_PB_GetState(BUTTON_USER) != 0){}
    TIM1_PWM_Output(50);
//        
//    while(BSP_PB_GetState(BUTTON_USER) != 0){}
//    TIM1_PWM_Output(60);
//        
//    while(BSP_PB_GetState(BUTTON_USER) != 0){}
//    TIM1_PWM_Output(80);
//        
//    while(BSP_PB_GetState(BUTTON_USER) != 0){}
//    TIM1_PWM_Output(100);
        
    while (1)
    {
        /**
         *  For testing GPIO output
         *  2023-11-24
         *  Hard coder Luoyuan
        */
#if(0)
        // Toggle LED3 in TIM16 IT service procedure instead.
        HAL_Delay(1000);
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
#endif
    }
}

代码新增部分实现对 TIM1_PWM 的初始化,然后将 TIM1 的 CHANNEL_1 拉低,等待按压一下开发板上的按钮,设置不同的 PWM 占空比,在示波器上观察这个输出通道的波形。

先前开发的功能仍然在使用,设置不同的中断优先级,避免中断之间的冲突。

实验结果

  • 启动后,在 XCOM 的显示如下图。

  • 启动信息显示正常,连续发送字符串,MCU 回显正常。
  • 板载的 LED 以 1Hz 的频率在翻转,说明原有的 TIM16 中断运行正常。
  • 查看按钮按下后,测量 GND 和 PA3 的波形如下,按顺序分别是占空比为 20%, 50%, 60%, 80% 和 100% 时的输出波形。

总结

利用 PY32F003 实现PWM输出的步骤:

  1. 选择时钟
  2. 设置端口复用
  3. 初始化高级定时器 TIM1
  4. 为 TIM1 的 OCx(x取值0,1,2,3) 通道设定占空比的值
  5. 启动(重启)这个通道

注意事项

  • 在 HAL_TIM_Base_MspInit 函数中,定义输出通道对应的 IO 管脚时,应根据外部硬件电路是否有上拉或者下拉来设置 GPIO_InitStructure.Pull 属性的值。在这里的实验当中,PWM输出的初始状态是全低电平(PWM关断的状态),并且这个 IO 管脚外部没有上拉电阻,那么这个 GPIO_InitStructure.Pull 属性就应该设置成 PULLDOWN,如果设置成了 PULLUP(默认值)就会在 PWM 通道进行初始化前产生一个高电平脉冲。在示波器上观察,这个高电平脉冲的宽度大约有 50us,如果是驱动一个灵敏的外部设备,例如一盏 LED 灯的话,足以让这盏灯突然闪亮一下了(有网友取名为“零点爆闪”现象,如果做到产品中,那是很 LOW 的哦)。相反,如果外部有上拉电阻,并且是使用 PWM2 模式输出的话,就应该将其初始化成 PULLUP。
  • 想要使 PWM 输出变成零,设置 PWM CCx 输出为0 和 PWM_PERIOD,都可以。这是因为比较器比较 0 和比较 PWM_PERIOD,两者之差一拍,就都能产生 Elapsed 的结果。
  • 和通用定时器相同,TIM1 的Period 和 Prescaler 决定了 PWM 波形的频率。零输出和满输出时,PWM 频率体现不出来。
  • TIM1 可以同时驱动 4 个通道的 PWM 输出,这里只列出了一个。

谬误之处,欢迎指正。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【文件上传系列】No.2 秒传(原生前端 + Node 后端)

上一篇文章 【文件上传系列】No.1 大文件分片、进度图展示&#xff08;原生前端 Node 后端 & Koa&#xff09; 秒传效果展示 秒传思路 整理的思路是&#xff1a;根据文件的二进制内容生成 Hash 值&#xff0c;然后去服务器里找&#xff0c;如果找到了&#xff0c;说明已经…

AI模型平台Hugging Face存在API令牌漏洞;大型语言模型与任务模型

&#x1f989; AI新闻 &#x1f680; AI模型平台Hugging Face存在API令牌漏洞&#xff0c;黑客可窃取、修改模型 摘要&#xff1a;安全公司Lasso Security发现AI模型平台Hugging Face上存在API令牌漏洞&#xff0c;黑客可获取微软、谷歌等公司的令牌&#xff0c;并能够访问模…

若依框架启动过程中遇到的控制台使用npm i下载相关依赖报错的问题以及前端启动遇到的问题

目录 报错截图问题解决其他问题 npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。问题解决更改环境变量新建系统变量 其他问题 错误解决Error: error:0…

外贸建站要国外服务器吗?海外服务器推荐?

外贸建站如何选国外服务器&#xff1f;海洋建站用什么服务器好&#xff1f; 外贸建站已经成为企业拓展国际市场的一项重要举措。然而&#xff0c;一个关键问题摆在许多企业面前&#xff1a;外贸建站是否需要选择国外服务器呢&#xff1f;这个问题涉及到多方面的考虑因素&#…

idea开发环境配置

idea重新安装后&#xff0c;配置的东西还挺多的&#xff0c;这里简单记录一下。 1、基础配置 1.1、主题、背景、主题字体大小 1.2、默认字体设置 控制台默认编码设置&#xff1a; 全局文件默认编码设置&#xff1a; 2、构建、编译、部署配置 说明&#xff1a;本地装了JD…

10 大 Mac 数据恢复软件深度评测

对于任何依赖计算机获取重要文件&#xff08;无论是个人照片还是重要商业文档&#xff09;的人来说&#xff0c;数据丢失可能是一场噩梦。值得庆幸的是&#xff0c;有多种专门为 Mac 用户提供的数据恢复工具&#xff0c;可以帮助检索丢失或意外删除的文件。在本文中&#xff0c…

文心一言API(高级版)使用

文心一言API高级版使用 一、百度文心一言API(高级版)二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、百度文心一言API(高级版) 基于百度文心一言语言大模型的智能文本对话AI机器…

冒泡排序和直接选择排序(C/C++实现)

文章目录 冒泡排序(交换排序&#xff09;基本思想特性总结代码实现 直接选择排序基本思想特性总结代码实现&#xff08;优化&#xff0c;每次循环同时选择最小和最大的数&#xff09; 冒泡排序(交换排序&#xff09; 基本思想 基本思想&#xff1a;所谓交换&#xff0c;就是根…

以pycharm为例,生成Python项目所需要的依赖库/包文档:requirements.txt

平时我们在编写或者使用别人的Python项目时&#xff0c;往往会看到一个文档requirements.txt&#xff0c;该文档是描述一个Python项目中的第三方库的名称以及版本。本文介绍导出python当前项目依赖包requirements.txt的操作步骤。 方法一&#xff1a;如果每个项目有对应的虚拟…

飞天使-linux操作的一些技巧与知识点3

http工作原理 http1.0 协议 使用的是短连接&#xff0c;建立一次tcp连接&#xff0c;发起一次http的请求&#xff0c;结束&#xff0c;tcp断开 http1.1 协议使用的是长连接&#xff0c;建立一次tcp的连接&#xff0c;发起多次http的请求&#xff0c;结束&#xff0c;tcp断开ngi…

阿里云(云服务器)上搭建项目部署环境

目录 安装docker docker安装MySQL5.7.37 安装MySQL 方式一&#xff1a;docker中MySQL时区调整 方式二&#xff1a;docker中MySQL时区调整 docker安装MySQL8.0.27 docker安装redis5.0.14 云服务器上安装jdk1.8 安装docker 1、先卸载docker&#xff0c;因为有一些服务器…

docker学习(七、搭建mysql8.2主从)

一、主库搭建 1.构建主库镜像 # 运行mysql镜像&#xff0c;配置端口3307为主库 docker run -p 3307:3306 --name mysql-master --privilegedtrue -v /mydata/mysql-master/log:/var/log/mysql -v /mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc…

C语言有哪些预处理操作?

C语言的预处理是在编译之前对源代码进行处理的阶段&#xff0c;它主要由预处理器完成。预处理器是一个独立的程序&#xff0c;它负责对源代码进行一些文本替换和处理&#xff0c;生成经过预处理的代码。以下是C语言预处理的一些重要特性&#xff1a; 1&#xff0c;头文件包含 #…

ArchLinux安装详细步骤

下载&#xff08;略&#xff09;安装VirtualBox&#xff08;略&#xff09;新建虚拟机&#xff08;略&#xff09;启动 进入提示符 进入安装设置界面 archinstall出现界面&#xff1a; 逐项设置。 Disk我选择了ext4 在Profile中 我选择了KDE作为桌面&#xff08;选择后按回车…

全面高压化与全面超快充,破解新能源汽车的时代难题

是什么让新能源车主感到疲惫与焦虑&#xff1f;是什么阻挡更多消费者选择新能源汽车&#xff1f;我们在身边进行一个简单的调查就会发现&#xff0c;问题的答案非常一致&#xff1a;充电。 充电难&#xff0c;充电慢的难题&#xff0c;始终是困扰新能源汽车产业发展&#xff0c…

玩转大数据12:大数据安全与隐私保护策略

1. 引言 大数据的快速发展&#xff0c;为各行各业带来了巨大的变革&#xff0c;也带来了新的安全和隐私挑战。大数据系统通常处理大量敏感数据&#xff0c;包括个人身份信息、财务信息、健康信息等。如果这些数据被泄露或滥用&#xff0c;可能会对个人、企业和社会造成严重的损…

『 MySQL数据库 』聚合统计

文章目录 前言 &#x1f951;&#x1f95d; 聚合函数&#x1f353; COUNT( ) 查询数据数量&#x1f353; SUM( ) 查询数据总和&#x1f353; AVG( ) 查询数据平均值&#x1f353; MAX( ) 查询数据最大值&#x1f353; MIN( ) 查询数据最小值 &#x1f95d; 数据分组GROUP BY子句…

拆分降采样与归一化(LN和BN)

拆分降采样&#xff1a;在ConvNeXt网络中使用一个步长为2的 22 卷积插入到不同的步骤之间&#xff0c;而且在降采样前后各加入了一个LN(一种归一化设计&#xff0c;这些归一化用来保持模型的稳定性) 为什么要进行归一化呢&#xff1f; 我们以BN为例 &#xff08;1&#xff0…

uniapp如何制作一个收缩通讯录(布局篇)

html&#xff1a; <view class"search"><view class"search_padding"><u-search change"search" placeholder"请输入成员名称" v-model"keyword"></u-search></view></view> <view…

【win10用vim开发stm32】二、vimspector的单片机调试

▲ 我的vim配置仓库: gitee&#xff0c;vim相关优先在gitee更新&#xff0c;博客vim专栏作为部分补充和使用说明 ▲ 本文提供vimspector调试的一个示例&#xff0c;和keil的调试功能比当然还是有很大差距&#xff0c;不过简单的调试功能如单步、复位、运行这些都跑通了&#xf…