通过TIM+DMA Burst 实现STM32输出变频且不同脉冲数量的PWM波形

Burst介绍:

DMA控制器可以生成单次传输或增量突发传输,传输的节拍数为4、8或16。

为了确保数据一致性,构成突发传输的每组传输都是不可分割的:AHB传输被锁定,AHB总线矩阵的仲裁器在突发传输序列期间不会撤销DMA主设备的授权。

作用:

可以通过Burst进行多个寄存器的同时修改,在M2P时同时配置多个定时器。

burst会占用总线直到数据发完为止,此期间CPU打断不了,但是不连续的节拍之间CPU依然可以打断

问题剖析:

需要STM32输出变频且不同脉冲数量的PWM波形,具体要求如下:

交替输出两组参数:

参数组1:频率较高(ARR=1000),输出3个脉冲(RCR=2)。

参数组2:频率较低(ARR=5000),输出2个脉冲(RCR=1)。

实现方式:通过DMA Burst功能,在一次定时器事件中批量修改多个寄存器(ARR、RCR、CCR),无需CPU干预。

STM32的TIM模块支持DMA Burst功能,允许通过单次定时器事件触发多次DMA传输,从而批量更新多个寄存器。其核心硬件模块如下:

(1) 关键寄存器

TIMx_DCR(DMA控制寄存器):

DBSS (DMA Burst Source Selection):选择触发DMA Burst的事件源(如定时器更新事件)。

DBL (DMA Burst Length):设置一次DMA Burst传输的数据个数(例如3次传输,对应修改ARR、RCR、CCR)。

DBA (DMA Burst Address):设置DMA传输的起始寄存器地址偏移(例如ARR寄存器的地址偏移为0x2C)。

TIMx_DMAR(DMA地址寄存器):

DMA通过访问此寄存器,将数据写入目标寄存器(如ARR、RCR、CCR)。

(2) 工作原理

触发事件:定时器产生指定事件(如更新事件TIM_UPDATE)。

DMA请求:事件触发DMA Burst传输,DMA控制器根据TIMx_DCR配置的传输次数(DBL)和起始地址(DBA),将内存中的数据连续写入多个寄存器。

自动更新参数:寄存器值被修改后,定时器立即使用新参数生成PWM波形。

理解关键参数:

Burst Size与传输次数的关系

在STM32的DMA Burst模式中,Burst Size 表示 单次突发传输(Burst)中连续传输的数据单元个数,而 传输总次数 由以下两个参数共同决定:

Burst Size(突发传输单元数):例如设置为4,表示一次突发传输4个数据单元。

Data Width(数据宽度):每个数据单元的大小(字节、半字或字)。

NDTR(Number of Data):DMA传输的总数据单元数(需在代码中动态设置)。

公式:

总传输次数 = NDTR / Burst Size

例如:若NDTR=12,Burst Size=4,则总传输次数为3次(每次突发传输4个单元)。

这里我们让DMA Burst输出一次,一次传四个数据单元的值(实际上只用三个,但是mx中只可以配4increment,第四个数据传0即可),输出的脉冲个数通过传入的四个单元值中RCR 的值决定;

PWM参数定义

ARR (Auto-Reload Register):决定PWM频率。

频率公式:PWM频率 = 定时器时钟 / (ARR + 1)

示例:

pulse1[0] = 1000 → 频率 = 100MHz / 1001 ≈ 99.9 kHz

pulse2[0] = 5000 → 频率 = 100MHz / 5001 ≈ 20 kHz

RCR (Repetition Counter Register):控制脉冲个数。

脉冲个数公式:脉冲数 = RCR + 1

示例:

pulse1[1] = 2 → 输出3个脉冲

pulse2[1] = 1 → 输出2个脉冲

CCR (Capture/Compare Register):决定占空比。

占空比公式:占空比 = CCR / (ARR + 1)

示例:

pulse1[2] = 500 → 占空比 ≈ 50%

pulse2[2] = 2500 → 占空比 ≈ 50%

参数结构:

uint32_t pulse1[3] = {1000, 2, 500};  // ARR=1000, RCR=2, CCR=500
uint32_t pulse2[3] = {5000, 1, 2500}; // ARR=5000, RCR=1, CCR=2500

CubeMX设置:

在CubeMX中配置Burst Size

打开DMA Settings标签页,选择对应的DMA通道。

设置 Burst Size 为 4 Increment(根据需求选择1/4/8/16)。

设置 Data Width 为 Word(32位,与TIM寄存器位宽一致)。

勾选 Increment Address(内存地址递增)。

选择 Mode 为 Normal 或 Circular。(若需持续传输,选择Circular模式并且设置足够大的NDTR)

每次DMA Burst需传输3个寄存器值(ARR、RCR、CCR)。

每个寄存器为32位(4字节),共需传输12字节。

Burst Size = 4 Increment(每次传输4个数据单元,但实际仅用3个,最后一个填充0)。

Data Width = Word(32位)。

NDTR = 3(传输3个数据单元)。

HAL_DMA_Start_IT()函数原型:

HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)

 代码实现:

uint32_t pulse_data[4] = {1000, 2, 500, 0}; // 第4个数据填充0
HAL_DMA_Start_IT(&hdma_tim1, (uint32_t)pulse_data, (uint32_t)&TIM1->DMAR, 3);// NDTR=3

交替输出的实现

(1) 中断切换模式

第一次传输:DMA传输pulse1到TIM寄存器。

传输完成中断:在中断回调函数中重新配置DMA,传输pulse2。

循环触发:重复上述过程,实现交替输出。

(2) 双缓冲模式

配置双缓冲:使能DMA双缓冲,设置两组内存地址(pulse1和pulse2)。

自动切换:DMA传输完当前缓冲区后,自动切换到下一组参数,无需CPU干预。

关键代码片段(基于HAL库)

// 1. DMA传输完成中断回调函数
void HAL_TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma) {// 切换参数组static uint8_t is_pulse1 = 0;if (is_pulse1) {HAL_DMA_Start_IT(&hdma_tim1, (uint32_t)pulse1, (uint32_t)&TIM1->DMAR, 3);} else {HAL_DMA_Start_IT(&hdma_tim1, (uint32_t)pulse2, (uint32_t)&TIM1->DMAR, 3);}is_pulse1 = !is_pulse1;
}// 2. 主函数初始化
int main(void) {// 初始化定时器和DMAHAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);HAL_DMA_Start_IT(&hdma_tim1, (uint32_t)pulse1, (uint32_t)&TIM1->DMAR, 3);while (1) {// 其他任务}
}

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

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

相关文章

鸿蒙学习手册(HarmonyOSNext_API16)_数据持久化③:关系型数据库

概述 关系型数据库:像“Excel表格联合作战”的管家 关系型数据库就像一个超级智能的表格管理系统,专门处理数据之间有复杂关联的情况。比如学生和成绩、订单和商品、用户和评论——这些数据像蜘蛛网一样相互连接,用键值数据库的“独立抽屉”…

Windows 11 VS Code C/C++ 开发环境搭建——一种尽量“绿色”的方法

我的电脑是Windows 11 系统,安装了Visual Studio Code,在上面搭建C/C开发环境,当然,这需要用到MinGW之流了。作为一个绿色爱好者(帽子除外),我也尽量绿色地架设这样一个环境…… 第一步&#x…

mysql-分区和性能

mysql自身只支持表的横向分区。 常听到开发人员说“”对表做个分区“,然后数据的查询就会快了。这是真的吗?实际上可能跟根本感觉不到查询速度的提升,甚至会发现查询速度急剧下降。因此,在合理使用分区之前,必须了解分…

DeepSeek协助优化-GTX750Ti文物显卡0.65秒卷完400MB float 音频512阶时域FIR

文章目录 1. 学习目的2. 阶段成果2.1 NVVP 性能探查2.2 测试编译环境2.3 测试样例 3 学习过程3.1 提问DeepSeek3.2 最终代码 4. 体会 1. 学习目的 最近在学习cuda,准备给我的taskBus SDR添加CUDA的模块支持,以便可以用PC机压榨山寨 B210那56M的带宽。 因…

RabbitMQ高级特性--TTL和死信队列

目录 1.TTL 1.1设置消息的TTL 1.1.1配置交换机&队列 1.1.2发送消息 1.1.3运行程序观察结果 1.2设置队列的TTL 1.2.1配置队列和交换机的绑定关系 1.2.2发送消息 1.2.3运行程序观察结果 1.3两者区别 2.死信队列 2.1 声名队列和交换机 2.2正常队列绑定死信交换机 …

【JavaEE】UDP数据报套接字编程

目录 网络编程基础 基本概念 发送端和接收端 请求和响应 客户端和服务端 常见的客户端服务端模型 Socket套接字 TCP/UDP特点 Java数据报套接字通信模型(UDP通信) UDP数据报套接字编程 DatagramSocket 1.类定义 2.构造方法 3.核心方法 4.特性说明 DatagramPacke…

Spring Boot 3.4.3 基于 SpringDoc 2 和 Swagger 3 实现项目接口文档管理

在现代企业级应用开发中,前后端分离已成为主流模式,前端负责界面呈现,后端专注提供 RESTful API 接口。然而,接口文档的编写和维护往往是开发过程中的痛点。Spring Boot 3.4.3 结合 SpringDoc 2 和 Swagger 3,为开发者…

构建大语言模型应用:数据准备(第二部分)

本专栏通过检索增强生成(RAG)应用的视角来学习大语言模型(LLM)。 本系列文章 简介数据准备(本文)句子转换器向量数据库搜索与检索大语言模型开源检索增强生成评估大语言模型服务高级检索增强生成 RAG 如上…

Linux 随机数据生成

目录 一. /dev/urandom1.1 dd 命令1.2 head命令1.3 随机字母 二. openssl 命令三. yes命令 一. /dev/urandom ⏹/dev/urandom 是 Linux 和 Unix 系统中的一个特殊文件,它是一个伪随机数生成器,用于提供高吞吐量的随机数据。 1.1 dd 命令 bs1M count10…

项目如何安装本地tgz包并配置局部registry

一、判断包来源是否正确 1. 检查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步骤&#xff1a; 1. 全局配置 如果你希望对所有项目生效&#xff0c;可以将这行配置添加到全局.npmr…

QCustomPlot入门

QCustomPlot 是一个基于 Qt 的 C++ 绘图库,专注于高效、美观的 2D 数据可视化。进入QCustomPlot下载页,下载最新的完整包(包含:源码、文档、示例)。 一、核心架构设计 1. 分层架构模型 层级主要组件职责说明用户接口层QCustomPlot 类提供顶层API,管理所有子组件逻辑控制…

C语言快速入门-C语言基础知识

这个c语言入门&#xff0c;目标人群是有代码基础的&#xff0c;例如你之前学过javaSE&#xff0c;看此文章可能是更有帮助&#xff0c;会让你快速掌握他们之间的差异&#xff0c;文章内容大部分都是泛谈&#xff0c;详细的部分我会在之后时间发布&#xff0c;我也在慢慢学习&am…

【商城实战(91)】安全审计与日志管理:为电商平台筑牢安全防线

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想…

信息安全工程师第 1 章

《信息安全工程师教程(第2版)》第一章 一、网络信息安全基本概念与重要性 网络信息安全定义 狭义:保障信息系统的机密性(C)、完整性(I)、可用性(A)——CIA三性。广义:涵盖国家安全、经济安全、社会安全等的“大安全”。法律依据:《网络安全法》定义网络安全为防范攻…

为什么视频文件需要压缩?怎样压缩视频体积即小又清晰?

在日常生活中&#xff0c;无论是为了节省存储空间、便于分享还是提升上传速度&#xff0c;我们常常会遇到需要压缩视频的情况。本文将介绍为什么视频需要压缩&#xff0c;压缩视频的好处与坏处&#xff0c;并教你如何使用简鹿视频格式转换器轻松完成MP4视频文件的压缩。 为什么…

网络空间安全(45)PHP入门学习

一、PHP文件与结构 PHP文件扩展名&#xff1a;PHP文件通常以.php作为扩展名&#xff0c;例如index.php。 PHP代码嵌入&#xff1a;PHP代码可以嵌入到HTML文件中&#xff0c;通常使用<?php ... ?>标签包围PHP代码。短标签<? ... ?>在某些配置下也可以使用&…

深入 OpenPDF:高级 PDF 生成与操作技巧

1 引言 1.1 项目背景 在许多企业级应用中,生成和操作 PDF 文档是一个常见的需求。PDF(Portable Document Format)因其格式统一、易于打印和分发而被广泛使用。本文将介绍如何使用 OpenPDF 库在 Java 项目中生成和操作 PDF 文档。 1.2 技术选型理由 OpenPDF:OpenPDF 是一…

力扣hot100——最长连续序列(哈希unordered_set)

题目链接&#xff1a;最长连续序列 1、错解&#xff1a;数组做哈希表&#xff08;内存超出限制&#xff09; int longestConsecutive(vector<int>& nums) {vector<bool> hash(20000000010, false);for(int i0; i<nums.size();i){hash[1000000000nums[i]]t…

Qt中信号带参传值

在我们的Qt信号中是可以进行参数的传递的&#xff0c;不过格式上与写普通函数不同。 这是头文件中定义一个含参信号和一个含参槽函数 我们再来看它们两个的绑定 。第一行的clicked()和on_btn_clicked()就是普通无参信号和槽的绑定&#xff1b;第二行就是上图中两个带参信号和槽…

CSS3学习教程,从入门到精通, CSS3 列表控制详解语法知识点及案例代码(24)

CSS3 列表控制详解 CSS 列表控制的语法知识点及案例代码的详细说明&#xff0c;包括 list-style-type、list-style-image、list-style-position 和 list-style 的用法。 1. list-style-type 属性 list-style-type 属性用于设置列表项标记的类型。 语法 list-style-type: v…