STM32 PWM基本知识及配置过程

2023-11-02

 

STM32——PWM基本知识及配置过程

将通用定时器分为四个部分:
      1,选择时钟
      2,时基电路
      3,输入捕获
      4,输出比较

本节定时器PWM输出主要涉及到定时器框图右下方部分,即输出比较部分

输出比较部分框图

和上一讲相同,时基时钟来源于内部默认时钟

对此有疑问请参考 : 定时器中断实验 中 定时器时钟选择部分 和 定时器时钟来源部分


什么是PWM

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

PWM工作过程

每个定时器有四个通道,每一个通道都有一个捕获比较寄存器, 
将寄存器值和计数器值比较,通过比较结果输出高低电平,实现PWM信号

先简单说明一下: 
PWM简单说明

如图为向上计数:
     定时器重装载值为ARR,比较值CCRx
     t时刻对计数器值和比较值进行比较
     如果计数器值小于CCRx值,输出低电平
     如果计数器值大于CCRx值,输出高电平

PWM的一个周期
    定时器从0开始向上计数
    当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
    t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
    当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程
    至此一个PWM周期完成

影响因素
    ARR : 决定PWM周期(在时钟频率一定的情况下,当前为默认内部时钟CK_INT)
    CCRx : 决定PWM占空比(高低电平所占整个周期比例)

PWM工作过程(以通道1为例)

PWM工作过程

1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器
    110:PWM模式1
    111:PWM模式2

2,计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平
    OC1REF=0 无效电平
    OC1REF=1 无效电平

3,通过输出模式控制器产生的信号
TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性
    0:高电平有效
    1:低电平有效

4,TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚
    0:关闭
    1:开启

PWM如何输出高低电平

计数器值TIMx_CNT与捕获比较寄存器值CCRx比较后,最终输出高电平还是低电平, 
由TIMx_CCMR1:OC1M位和TIMx_CCER:CC1P位共同决定

1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置PWM模式1或模式2

CCMR1

通过设置模式1或模式2,决定了比较结果输出有效或无效电平


2,TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性

CCER

通过设置输出极性,确定有效或无效电平为最终输出的高电平或低电平

总结:
     模式1:
          CNT<CCR为有效电平 //(OC1REF = 1)
          CNT>CCR为无效电平 //(OC1REF = 0)
     模式2:
          CNT<CCR为无效电平 //(OC1REF = 0)
          CNT>CCR为有效电平 //(OC1REF = 1)
     CC1P:
          0:高电平有效
          1:低电平有效

PWM模式总结


PWM模式配置

PWM模式配置

TIM_OC1PreloadConfig函数:
     作用:TIM_CCMRx寄存器OCxPE位使能相应的预装在寄存器
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

TIM_ARRPreloadConfig函数:
     作用:操作TIMx_CR1寄存器ARPE位,使能自动重装载的预装载寄存器
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

ARPE的使能-ARR变更生效配置

ARPE=1

ARPE=0

ARPE=1,ARR立即生效
ARPE=0,ARR下周期生效

定时器3输出通道引脚

定时器3的4个通道对应的引脚及重映射

定时器3输出通道引脚


PWM输出库函数

1,定时器通道初始化-TIM_OC1Init

经过上面的讲解,我们知道了要想使用PWM需要配置

配置参数对应框图位置如下:

定时器通道初始化

1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器
2,TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性
3,TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚

初始化定时器输出比较通道

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
  • 1

TIM_OCInitTypeDef结构体

typedef struct
{
  uint16_t TIM_OCMode;         // PWM模式1或者模式2
  uint16_t TIM_OutputState;    // 输出使能 OR失能
  uint16_t TIM_OutputNState;   // PWM输出不需要
  uint16_t TIM_Pulse;          // 比较值,写CCRx,可以有次函数void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);写入,这里暂时不设置。 
 uint16_t TIM_OCPolarity; // 比较输出极性 
  uint16_t TIM_OCNPolarity; // PWM输出不需要 
  uint16_t TIM_OCIdleState; // PWM输出不需要 
  uint16_t TIM_OCNIdleState; // PWM输出不需要
 } TIM_OCInitTypeDef;

 


2,设置比较值函数-TIM_SetCompare1

作用:外部改变TIM_Pulse值,即改变CCR的值

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
  • 1

3,使能输出比较预装载-TIM_OC1PreloadConfig

作用:TIM_CCMRx寄存器OCxPE位使能相应的预装在寄存器

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
  • 1

4,使能自动重装载的预装载寄存器允许位-TIM_ARRPreloadConfig

作用:操作TIMx_CR1寄存器ARPE位,使能自动重装载的预装载寄存器

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
  •  

5,修改通道极性

作用:操作TIMx_CCER的CC1P位,修改通道极性

void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
  • 1

PWM输出实验

使用定时器3初始PWM信号,输出占空比可变的PWM波驱动LED(PB5引脚),实现LED亮度变换

LED:低电平点亮,高电平熄灭,占空比越大,一个周期中高电平持续时间越长,亮度越大,反之越暗.

查找手册PB5引脚为定时器3的通道2,需要部分重映射

TIM3引脚重映射


PWM输出实验步骤

1,使能定时器3和相关IO时钟(LED-PB5)
    使能定时器3时钟:RCC_APB1PeriphClockCmd();
    使能GPIOB时钟:RCC_APB2PeriphClockCmd();

2,初始化IO口为复用功能输出 GPIO_Init();
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

3,PB5输出PWM(定时器3通道2),需要部分冲突映射
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟设置
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射

4,初始化定时器 (重装载值ARR,与分频系数PSC等)
    TIM_TimeBaseInit();//决定PWM周期

5,初始化输出比较参数:
    TIM_OC2Init();//通道2输出比较初始化

6,使能预装载寄存器
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//定时器3 通道2

7,使能定时器
    TIM_Cmd();

8,不断改变比较值CCRx,达到不同的占空比效果
    TIM_SetCompare2(); //通道2,改变比较值CCRx

代码实现

基于 定时器中断实验 代码进行编写

timer.h添加PWM初始化函数定义 void TIM3_PWM_Init(u16 arr,u16 psc);

 

#ifndef  __TIMER_H
#define  __TIMER_H
#include "sys.h"

void TIM3_PWM_Init(u16 arr,u16 psc);

#endif

 

 

timer.c 实现定时器PWM初始化函数

 

#include "timer.h"

//TIM3 PWM初始化
//arr   重装载值
//psc   预分频系数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
    GPIO_InitTypeDef     GPIO_InitStrue;
    TIM_OCInitTypeDef     TIM_OCInitStrue;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);        //使能TIM3和相关GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB时钟(LED在BP5引脚),使能AFIO时钟(定时器3通道2需要重映射到BP5引脚)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_5;     // TIM_CH2
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 复用推挽
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置最大输出速度
    GPIO_Init(GPIOB,&GPIO_InitStrue);                //GPIO端口初始化设置
    
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
    
    TIM_TimeBaseInitStrue.TIM_Period=arr;    //设置自动重装载值
    TIM_TimeBaseInitStrue.TIM_Prescaler=psc;        //预分频系数
    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //计数器向上溢出
    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);        //TIM3初始化设置(设置PWM的周期)
    
    TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2;        // PWM模式2:CNT>CCR时输出有效
    TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_High;// 设置极性-有效为高电平
    TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能
    TIM_OC2Init(TIM3,&TIM_OCInitStrue);        //TIM3的通道2PWM 模式设置

    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);        //使能预装载寄存器
    
    TIM_Cmd(TIM3,ENABLE);        //使能TIM3
    
}

主程序的设计:

进行pwm的设置

  TIM_SetCompare2(TIM3,led0pwmval);        //改变比较值TIM3->CCR2达到调节占空比的效果

 

int main(void)
 {    
    u8 i=1;         // 设置方向 0:变暗 1:变亮
    u16 led0pwmval;        // 设置CCR值
    delay_init();             // 延时函数初始化
    LED_Init();                // LED初始化
    TIM3_PWM_Init(899,0); //设置频率为80KHz,公式为:溢出时间Tout=(arr+1)(psc+1)/Tclk
                                                //Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
                                                //PWM时钟频率=72000000/(899+1) = 80KHZ,设置自动装载值899,预分频系数0(不分频)
    while(1)
    {    
        delay_ms(10);            
        if(i)led0pwmval++;        // 由暗变亮
            else led0pwmval--;        // 由亮变暗
        
        if(led0pwmval==0)i=1;        // 已达到最亮,开始变暗
        if(led0pwmval>100)i=0;    // 已达到最暗,开始变亮
        
        TIM_SetCompare2(TIM3,led0pwmval);        //改变比较值TIM3->CCR2达到调节占空比的效果
        
    }
 }
//此处led0pwmval值最大可以设置到899,输出pwm波基本全为1,大小随意设定。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 PWM基本知识及配置过程 的相关文章

  • 在地址“0xXXXXXX”处中断,没有可用的调试信息,或在程序代码之外

    配置 使用 Nucleo L476RG 使用 GNU ARM Eclipse 我从 STM32CubeMX 生成了一个极简代码 我已经在我的板载 ST Link 中刷新了 J link 驱动程序 一直在尝试为我的代码运行调试器 但我的程序计
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • GCC - 如何停止链接 malloc?

    我正在努力将我的代码缩减到最小的骨架大小 我使用的是只有 32k 闪存的 STM32F0 需要很大一部分闪存用于数据存储 我的代码已经有大约 20k 闪存大小 其中一些是由于使用了 STM32 HAL 函数 我可以在以后需要时对其进行解释和
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • STM32超声波——HC_SR04

    文章目录 一 超声波图片 二 时序图 三 超声波流程 四 单位换算 五 取余计算 六 换算距离 七 超声波代码 一 超声波图片 测量距离 2cm 400cm 二 时序图 1 以下时序图要先提供一个至少10us的脉冲触发信号 告诉单片机我准备
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐

  • Linux用户环境变量、系统环境变量和PATH变量

    目录 一 用户环境变量 二 系统环境变量 三 PATH变量 1 修改PATH环境变量 一 用户环境变量 PS 修改文件执行权限案例 1 在文本编辑器中新建一个shell脚本 直接执行这个文件会发现权限不够 以详细模式查看这个文件的权限 发现
  • OpenCV——Sobel边缘检测

    目录 一 Sobel算法 1 算法概述 2 主要函数 二 C 代码 三 python代码 四 结果展示 1 灰度图 2 X方向一阶边缘 2 Y方向一阶边缘 3 整幅图像的一阶边缘 五 相关链接 一 Sobel算法 1 算法概述 Sobel边
  • matplotlib库使用教程:这一篇就够了

    一 导入库 import matplotlib pyplot as plt 二 显示图片 plt imshow imge 负责对图像进行处理 imge类型
  • Zotero安装教程(非常详细)从零基础入门到精通,看完这一篇就够了

    Zotero安装及简单配置 1 引言 Zotero是目前最符合我对文献管理软件需求的一款 在这里简单介绍下其安装教程及我在使用的插件 2 安装及同步设置 2 1 下载 前往官网https www zotero org 点击Download按
  • J2EE&反射

    文章目录 什么是反射 类类 反射实例化 反射动态方法调用 反射读写属性 源代码 什么是反射 Java语言的一种机制 通过这种机制可以动态的实例化对象 读写属性 调用方法 类类 类类 描述类的类 不是官方定义的语言 Class forName
  • Flutter开发篇 TextField和TextFromField

    TextFiled和TextFromField都是用来输入的 但是也是有区别的 尤其是方法有很大的区别 大家可以分别查看源码文档 在资料比较少的情况下那是最快的学习方法 TextEditingController controller Te
  • git创建本地分支,远程分支

    一 本地分支 创建本地分支 然后切换到dev分支 git checkout b dev git checkout命令加上 b参数表示创建并切换 相当于以下两条命令 git branch dev git checkout dev 然后 用gi
  • word自动编号设置方法

    需求是使用word时自动生成如下类型的自动编号 第一章 项目详细设计 1 1 视频监控系统 1 1 1 前端子系统 1 1 1 1 球机 第二章 案例介绍 2 1 某某区平安城市介绍 实现方法 1 首先点击 多级列表 定义新的多级列表 2
  • python爬虫-数据可视化-气温排行榜

    本文的文字及图片来源于网络 仅供学习 交流使用 不具有任何商业用途 版权归原作者所有 如有问题请及时联系我们以作处理 以下文章来源于腾讯云 作者 py3study 想要学习Python Python学习交流群 1039649593 满足你的
  • vulnhub靶机Brainpan

    主机发现 arp scan l 端口扫描 nmap min rate 10000 p 192 168 21 156 服务扫描 nmap sV sT O p9999 10000 192 168 21 156 这个地方感到了有点不对劲 pyth
  • 粒子滤波(Particle filter)算法简介及MATLAB实现

    粒子滤波是以贝叶斯推理 点击打开链接 和重要性采样为基本框架的 因此 想要掌握粒子滤波 对于上述两个基本内容必须有一个初步的了解 重要性采样呢 其实就是根据对粒子的信任程度添加不同的权重 添加权重的规则就是 对于我们信任度高的粒子 给它们添
  • 解决pip安装numpy问题:ERROR: Failed building wheel for numpy/ERROR: numpy-1.22.4+mkl-cp38-cp38-win_amd64.wh

    出现过问题 ERROR Failed building wheel for numpy 下载了whl文件后报错ERROR numpy 1 22 4 mkl cp38 cp38 win amd64 whl is not a supported
  • java怎么关闭fxml窗口,如何关闭窗口关闭JavaFX应用程序?

    In Swing you can simply use setDefaultCloseOperation to shut down the entire application when the window is closed Howev
  • 因果推理(八):工具变量(Intrusmental Variables)

    关于因果关系的识别 前面介绍了一些方法 随机对照试验 后门调整 前门调整 do 演算 今天介绍另一种进行因果效应识别的另一种方法 工具变量 1 什么是工具变量 上面的因果图中 Z Z Z就是一个工具变量 可以利用它在 U U U观测不到的情
  • Java贪心算法: 田忌赛马

    import java util Scanner import java util List import java util ArrayList import java util Collections public class Main
  • TensorFlow2.0简介和线性回归

    简介 废弃清除了1 0版本的多数API 使用了高级核心API tf Keras Eager模式 代码直接运行 直观调试 tf GradientTape 求解梯度 自定义训练逻辑 tf data 加载图片数据和结构化数据 tf fuction
  • 构建一个react项目_用React构建一个简单的计数器

    构建一个react项目 In this short tutorial we ll build a very simple example of a counter in React applying many of the concepts
  • 第十三届蓝桥杯C B组 J:砍竹子

    思路 首先看数据范围 2e5 比较大 而且有一个不变的是 我们每次都从最高的竹子区间开始砍 那么每进行一次砍操作 接着还得再找出最高的竹子区间 代表要有多次排序 所以自然而然想到了一个数据结构 堆 想到 堆 思路就打开了 可以用pair存高
  • 【数学建模】2023数学建模国赛C题完整思路和代码解析

    C题第一问代码和求解结果已完成 第一问数据量有点大 经过编程整理出来了单品销售额的汇总数据 将附件2中的单品编码替换为分类编码 整理出了蔬菜各品类随着时间变化的销售量 并做出了这些疏菜品类的皮尔森相关系数的热力图 代码和数据处理结果下载见文
  • STM32 PWM基本知识及配置过程

    STM32 PWM基本知识及配置过程 将通用定时器分为四个部分 1 选择时钟 2 时基电路 3 输入捕获 4 输出比较 本节定时器PWM输出主要涉及到定时器框图右下方部分 即输出比较部分 和上一讲相同 时基时钟来源于内部默认时钟 对此有疑问