从51到STM32:PWM平滑迁移方案

引言

对于习惯使用51单片机的开发者而言,转向STM32时可能会面临开发环境和硬件差异的挑战。本文以PWM(脉宽调制)功能为例,分享从51到STM32的平滑迁移方案,帮助开发者快速适应STM32的开发模式。

一、PWM实现原理对比

1.1 51单片机的PWM实现

在51中,通常通过定时器中断+手动翻转IO电平实现PWM:

// 51示例代码(定时器0模式1)
void Timer0_Init() {
    TMOD &= 0xF0;
    TMOD |= 0x01; // 定时器0模式1
    TH0 = 0xFF;   // 重载值
    TL0 = 0xFF;
    ET0 = 1;      // 开启定时器中断
    EA = 1;
    TR0 = 1;
}

void Timer0_ISR() interrupt 1 {
    static uint8_t pwm_count = 0;
    TH0 = 0xFF;   // 重置计时值
    TL0 = 0xFF;
    pwm_count++;
    if(pwm_count == duty_cycle) {
        PWM_PIN = 0; // 拉低电平
    } else if(pwm_count == period) {
        PWM_PIN = 1; // 拉高电平
        pwm_count = 0;
    }
}

1.2 STM32的硬件PWM优势

STM32内置硬件PWM模块,通过定时器自动输出波形,无需CPU干预:

  • 更高精度(16位计数器)

  • 多通道同步输出

  • 支持互补输出(用于电机控制)

  • 自动重载减少中断开销

二、迁移关键步骤

2.1 硬件资源映射

51资源STM32等效资源
定时器0TIM1/TIM2/TIM3等
IO引脚支持复用的TIMx_CHx引脚

2.2 配置步骤对比

51单片机流程:
  1. 配置定时器模式

  2. 设置中断服务程序

  3. 手动控制IO电平

STM32标准库流程:
  1. 启用时钟(TIMx和GPIO)

  2. 配置定时器基本参数

  3. 设置PWM模式

  4. 配置输出比较单元

  5. 启动定时器

三、STM32 PWM配置示例(标准库)

3.1 初始化代码

// 以TIM3_CH2(PA7)为例
void PWM_Init(uint16_t arr, uint16_t psc) {
    GPIO_InitTypeDef GPIO_InitStruct;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct;

    // 1. 开启时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 2. 配置GPIO
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 3. 配置定时器基础
    TIM_TimeBaseStruct.TIM_Period = arr;         // 自动重装载值
    TIM_TimeBaseStruct.TIM_Prescaler = psc;      // 预分频系数
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);

    // 4. 配置PWM模式
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = 0;            // 初始占空比
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM3, &TIM_OCInitStruct);      // 通道2

    // 5. 启动定时器
    TIM_Cmd(TIM3, ENABLE);
}

// 设置占空比
void PWM_SetDuty(uint16_t duty) {
    TIM_SetCompare2(TIM3, duty);
}

3.2 使用HAL库简化开发(CubeMX生成)

// 使用CubeMX配置后自动生成代码
void MX_TIM3_Init(void) {
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 71;         // 72MHz/(71+1)=1MHz
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 999;           // 1MHz/1000=1kHz PWM
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_PWM_Init(&htim3);

    TIM_OC_InitTypeDef sConfigOC;
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 500;             // 初始占空比50%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
}

四、迁移注意事项

  1. 时钟树配置:STM32需明确时钟源和分频系数

  2. 占空比计算:STM32占空比 = (Pulse / (Period+1)) * 100%

  3. 引脚复用功能:必须通过AFIO配置复用模式

  4. 中断优先级:若使用PWM中断,需配置NVIC

  5. 硬件滤波:STM32支持PWM输出滤波(TIMx_CCMRx寄存器)

五、调试技巧

  1. 使用示波器验证波形频率和占空比

  2. 通过STM32CubeMX可视化配置参数

  3. 利用调试器实时修改变量值(如Period/Pulse)

  4. 结合DMA实现无CPU干预的PWM控制

总结

从51到STM32的PWM开发迁移,核心在于从软件模拟转向硬件外设的思维转变。通过合理利用STM32的硬件定时器资源,不仅可以减少CPU开销,还能实现更高精度的PWM控制。建议结合STM32CubeMX工具快速入门,再逐步深入理解寄存器级配置。

如果从来没有用过stm32推荐观看STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

来配置文件。51是配置寄存器,stm32官方有标准库可以调用,开发更加方便。

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

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

相关文章

【OS】AUTOSAR架构下的Interrupt详解(下篇)

目录 3.代码分析 3.1中断配置代码 3.2 OS如何找到中断处理函数 3.3 Os_InitialEnableInterruptSources实现 3.4 Os_EnableInterruptSource 3.5 DisableAllInterrupts 3.5.1Os_IntSuspendCat1 3.5.2 Os_InterruptDisableAllEnter 3.5.3 Disable二类中断 3.5.4 Disable一…

flutter 专题四十七 Flutter 应用启动流程分析

众所周知,任何应用程序的启动都是从main()函数开始的,Flutter也不例外,main.dart文件的main函数开始的,代码如下。 void main() > runApp(MyApp());main函数则调用的是runApp函数,源码如下。 void runApp(Widget …

html中的表格属性以及合并操作

表格用table定义,标签标题用caption标签定义;用tr定义表格的若干行;用td定义若干个单元格;(当单元格是表头时,用th标签定义)(th标签会略粗于td标签) table的整体外观取决…

大语言模型轻量化:知识蒸馏的范式迁移与工程实践

大语言模型轻量化:知识蒸馏的范式迁移与工程实践 🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 摘要 在大型语言模型&#xff…

Go语言的转义字符

文章目录 1. Go语言的转义字符(escapechar)2. 小结和提示 1. Go语言的转义字符(escapechar) 说明:常用的转义字符有如下: \t : 表示一个制表符,通常使用它可以排版\n :换行符\\ :一个\\" :一个"\r :一个回…

Docker深度解析:容器与容器局域网

DockerFile 解析: DockerFile 描述出镜像文件需要的一些依赖配置和环境变量执行命令 docker build,将我们的 dockerfile 文件打包成一个镜像文件直接使用我们的容器运行到该镜像文件 CentOS 镜像: 运行镜像: docker run -it cent…

360手机刷机 360手机解Bootloader 360手机ROOT

360手机刷机 360手机解Bootloader 360手机ROOT 问:360手机已停产,现在和以后,能刷机吗? 答:360手机,是肯定能刷机的 360手机资源下载网站 360手机-360手机刷机RootTwrp 360os.top 360rom.github.io 一、…

C++输入输出(上)

cin和cout cin是C中提供的标准输入流对象,一般针对的是键盘,也就是从键盘上输入的字符流,使用 cin来进行数据的提取,cin一般是和 >> (流提取运算符) 配合使用的。 cin的功能和scanf是类似的 cout是C中提供的标准输出流对象,一般针对的是控制台的窗口,也就是将数据以字符…

【沐风老师】3DMAX混沌破碎插件ChaosFracture使用方法

3DMAX混沌破碎插件ChaosFracture,只需一键操作,即可轻松实现物体的破碎效果,同时确保外表面与内部断裂部分保持原有的材质ID和UVs信息,真实呈现细腻的破碎场景。 【适用版本】 3DMax9及更高版本(建议使用3DMax2018以上…

e2studio开发RA2E1(8)----GPT定时器频率与占空比的设置

e2studio开发RA2E1.8--GPT定时器频率与占空比的设置 概述视频教学样品申请硬件准备参考程序源码下载选择计时器时钟源PWM(脉冲宽度调制)R_GPT_PeriodSet()函数说明R_GPT_DutyCycleSet()函数说明R_GPT_Reset()函数说明R_GPT_Close() 函数说明主程序波形情况 概述 GPT&#xff0…

7.PPT:“中国梦”学习实践活动【20】

目录 NO1234​ NO5678​ NO9\10\11 NO1234 考生文件夹下创建一个名为“PPT.pptx”的新演示文稿Word素材文档的文字:复制/挪动→“PPT.pptx”的新演示文稿(蓝色、黑色、红色) 视图→幻灯片母版→重命名:“中国梦母版1”→背景样…

基于Flask的大模型岗位招聘可视化分析系统的设计与实现

【FLask】基于Flask的大模型岗位招聘可视化分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言,结合Echarts可视化库&#xff0…

AlwaysOn 可用性组副本所在服务器以及该副本上数据库的各项状态信息

目录标题 语句代码解释:1. `sys.dm_hadr_database_replica_states` 视图字段详细解释及官网链接官网链接字段解释2. `sys.availability_replicas` 视图字段详细解释及官网链接官网链接字段解释查看视图的创建语句方法一:使用 SQL Server Management Studio (SSMS)方法二:使用…

windows版的docker如何使用宿主机的GPU

windows版的docker使用宿主机的GPU的命令 命令如下 docker run -it --nethost --gpus all --name 容器名 -e NVIDIA_DRIVER_CAPABILITIEScompute,utility -e NVIDIA_VISIBLE_DEVICESall 镜像名效果 (transformer) rootdocker-desktop:/# python Python 3.9.0 (default, Nov 15 …

知识蒸馏教程 Knowledge Distillation Tutorial

来自于:Knowledge Distillation Tutorial 将大模型蒸馏为小模型,可以节省计算资源,加快推理过程,更高效的运行。 使用CIFAR-10数据集 import torch import torch.nn as nn import torch.optim as optim import torchvision.tran…

K8S集群部署--亲测好用

最近在自学K8S,花了三天最后终于成功部署一套K8S Cluster集群(masternode1node2) 在这里先分享一下具体的步骤,后续再更新其他的内容:例如部署期间遇到的问题及其解决办法。 部署步骤是英文写的,最近想练…

【Unity2D 2022:UI】创建滚动视图

一、创建Scroll View游戏对象 在Canvas画布下新建Scroll View游戏对象 二、为Content游戏对象添加Grid Layout Group(网格布局组)组件 选中Content游戏物体,点击Add Competent添加组件,搜索Grid Layout Group组件 三、调整Grid La…

c++:list

1.list的使用 1.1构造 1.2迭代器遍历 (1)迭代器是算法和容器链接起来的桥梁 容器就是链表,顺序表等数据结构,他们有各自的特点,所以底层结构是不同的。在不用迭代器的前提下,如果我们的算法要作用在容器上…

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1:如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」,deepseek便爆火 爆火以后便应了“人红是非多”那句话,不但遭受各种大规模攻击,即便…

游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文

Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…