当前位置: 首页 > news >正文

从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模式1TH0 = 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. 配置GPIOGPIO_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)=1MHzhtim3.Init.CounterMode = TIM_COUNTERMODE_UP;htim3.Init.Period = 999;           // 1MHz/1000=1kHz PWMhtim3.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官方有标准库可以调用,开发更加方便。

相关文章:

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

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

openCV中如何实现滤波

图像滤波用于去除噪声和图像平滑,OpenCV 提供了多种滤波器: 1.1. 均值滤波: import cv2# 读取图像 image cv2.imread("example.jpg")# 均值滤波 blurred_image cv2.blur(image, (5, 5)) # (5, 5) 是滤波核的大小 滤波核大小的…...

BGP配置华为——路由汇总

实验拓扑 实验要求 1.R1,R2,R3间运行BGP,搭建EBGP邻居 2.R3一段的网络实现自动聚合,R1一端的网络实现手动路由聚合 3.启用as-set防环 实验配置 配置相关IP 过程省略,结果如图 R1 R2 R3 配置EBGP [R1]bgp 100 [R1-bgp]router 10.10.1…...

机器学习核心算法解析

机器学习核心算法解析 机器学习是人工智能的核心技术之一,它通过从数据中学习模式并做出预测或决策。本文将深入解析机器学习的核心算法,包括监督学习、无监督学习和强化学习,并通过具体案例和代码示例帮助读者理解这些算法的实际应用。 1. …...

【C++学习篇】C++11

目录 ​编辑 1. 初始化列表{} 1.1 C98中的{} 1.2 C11中的{} 2. C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期 3.4 左值和右值的参数匹配 3.5 右值引⽤和移动语义的使⽤场景 3.5.1 左值引⽤…...

SQLite 数据库:优点、语法与快速入门指南

文章目录 一、引言二、SQLite 的优点 💯三、SQLite 的基本语法3.1 创建数据库3.2 创建表3.3 插入数据3.4 查询数据3.5 更新数据3.6 删除数据3.7 删除表 四、快速入门指南4.1 安装 SQLite4.2 创建数据库4.3 创建表4.4 插入数据4.5 查询数据4.6 更新数据4.7 删除数据4…...

数据结构——二叉树(2025.2.12)

目录 一、树 1.定义 (1)树的构成 (2)度 2.二叉树 (1)定义 (2)二叉树的遍历 (3)遍历特性 二、练习 1.二叉树 (1)创建二叉树…...

图神经网络简介

一、说明 本文介绍了GNN网络一些要素,其中与CNN进行过一些对比,并且对GNN的一些统计原理进行介绍。 二、介绍 对于不同类型的训练数据集,卷积神经网络 (CNN) 擅长处理方形或网格状或欧几里得结构化数据,…...

小程序报错The JavaScript function Pointer_stringify(ptrToSomeCString)

小程序报错The JavaScript function Pointer _stringify(ptrToSomeCString) 介绍修改地址总结 介绍 这个报错是我在打包小程序在手机上运行时报的错,这个地方问题是个小问题,其实就是Pointer_stringify(ptrToSomeCString) 函数过时…...

DeepSeek 与网络安全:AI 驱动的智能防御

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 随着人工智能(AI)的快速发展,深度学习技术正渗透到多个领域,从医疗诊断到…...

Redission看门狗

在 Redisson 中,lock.tryLock() 和 lock.lock() 是两种不同的加锁方式,它们的行为有所不同: lock.lock():这是阻塞方法,当调用时,如果锁当前不可用,线程将被阻塞,直到获取到锁。如果…...

LeetCode 热题 100_组合总和(58_39_中等_C++)(递归(回溯))

LeetCode 热题 100_组合总和(58_39) 题目描述:输入输出样例:题解:解题思路:思路一(递归(回溯)): 代码实现代码实现(思路一&#xff08…...

使用PHP爬虫获取1688商品分类:实战案例指南

在电商领域,商品分类信息是商家进行市场调研、选品分析和竞争情报收集的重要基础。1688作为国内领先的B2B电商平台,提供了丰富且详细的商品分类数据。通过PHP爬虫技术,我们可以高效地获取这些分类信息,为商业决策提供有力支持。 …...

Nginx location 和 proxy_pass 配置详解

概述 Nginx 配置中 location 和 proxy_pass 指令的不同组合方式及其对请求转发路径的影响。 配置效果 1. location 和 proxy_pass 都带斜杠 / location /api/ {proxy_pass http://127.0.0.1:8080/; }访问地址:www.hw.com/api/upload转发地址:http://…...

云创智城充电系统:基于 SpringCloud 的高可用、可扩展架构详解-多租户、多协议兼容、分账与互联互通功能实现

在新能源汽车越来越普及的今天,充电基础设施的管理和运营变得越来越重要。云创智城充电系统,就像一个超级智能管家,为新能源充电带来了全新的解决方案,让充电这件事变得更方便、更高效、更安全。 一、厉害的技术架构,让…...

AIP-143 标准代号

编号143原文链接AIP-143: Standardized codes状态批准创建日期2019-07-24更新日期2019-07-24 许多常见的概念,如语言、国家、货币等,都有用于数据通信和处理的通用代号(通常由国际标准化组织正式定义)。这些代号解决了在书面语言…...

机器视觉--数字图像格式

图像格式 在数字图像的世界里,不同的图像格式有着各自的特点和适用场景。了解这些图像格式,对于我们在处理图像时选择合适的存储和传输方式至关重要。下面就让我们来详细探讨一下常见的几种数字图像格式。 一、BMP 文件(Bitmap)…...

Kotlin 2.1.0 入门教程(十七)接口

接口 接口可以包含抽象方法的声明,也可以包含方法的实现。 接口与抽象类的不同之处在于,接口无法存储状态。接口可以拥有属性,但这些属性要么必须是抽象的,要么就得提供访问器的实现。 接口使用 interface 关键字来定义&#x…...

渗透测试工具:SQLmap安装教程及使用

在渗透测试的世界里,SQL注入攻击无疑是最常见且最具威胁的安全漏洞之一。幸运的是,SQLmap 这个强大的自动化工具,能够帮助我们快速识别和利用这些漏洞。如果你也想了解如何用 SQLmap 进行渗透测试,那么这篇文章就是为你准备的&…...

4.SpringSecurity在分布式环境下的使用

参考 来源于黑马程序员: 手把手教你精通新版SpringSecurity 分布式认证概念说明 分布式认证,即我们常说的单点登录,简称SSO,指的是在多应用系统的项目中,用户只需要登录一次,就可以访 问所有互相信任的应…...

OpenLayers 可视化之热力图

注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...