【GD32】05 - PWM 脉冲宽度调制

news2024/11/18 23:51:17

PWM

PWM (Pulse Width Modulation) 是一种模拟信号电平的方法,它通过使用数字信号(通常是方波)来近似地表示模拟信号。在PWM中,信号的占空比(即高电平时间占整个周期的比例)被用来控制平均输出电压或电流。

PWM在许多应用中都非常重要,特别是那些需要精确控制模拟信号的应用,如电机控制、LED亮度调节、音频放大器等。以下是PWM的一些关键特点和优势:

  1. 高效能:PWM允许在开关电源中精确控制能量传输,从而提高效率。
  2. 简单实现:PWM可以通过数字电路或微控制器轻松实现。
  3. 减少功耗:在需要调节功率的应用中,PWM可以确保只有必要的能量被传输,从而减少了不必要的功耗。
  4. 降低噪声:与模拟控制相比,PWM可以减少由模拟电路引起的噪声。
  5. 精确控制:通过改变PWM信号的占空比,可以非常精确地控制输出电压或电流。

在电机控制中,PWM通常用于控制电机的速度和方向。通过改变PWM信号的占空比,可以精确地控制电机的平均电压,从而控制电机的速度和扭矩。

在LED亮度调节中,PWM也被广泛使用。通过改变PWM信号的占空比,可以控制LED的平均电流,从而控制LED的亮度。这种方法比使用模拟电阻来调节亮度更加高效和精确。

总之,PWM是一种非常有用的技术,它允许我们使用数字信号来精确控制模拟信号的电平。

以上介绍来自文心一言。

简而言之,PWM就是我们把定时器的计数器的值拿来和一个数做比较,计数器的值比较大的时候我们就输出高(低)电平,反之输出低(高)电平。

因此PWM离不开定时器,所以一写完上一篇定时器我就写了这PWM。

GD32E230中的PWM

因为我们上一篇是用的通用L4类型的定时器15,因此我们主要来看看这个类型的定时器的PWM。

我们这个类型的定时器是有PWM的,不过只有一个通道。

根据数据手册可以看到定时器15的唯一一个通道是GPIOB的8号引脚。  

知道这个之后就够了,接下来可以看看相关的固件库函数了。 

固件库函数

在固件库使用指南中,没有单独的PWM章节,是和定时器在一起的,我这边就挑我们用的到的说说。

我们可以拿上一篇定时器的代码接着用,配置定时器什么的都可以留着,把中断部分删掉就行,剩下就是配置一个PWM通道输出的就行。

timer_channel_output_config

配置定时器的通道输出,传入的参数有定时器,还有待配置通道,我们通用L4的没得选,只能用通道0,高级定时器的话是有四个通道可以用的。

最后一个参数是结构体变量的指针。

我们来看看这个结构体是怎么样的。

一共六个成员,首先第一个通道输出状态,那必然是要使能的,TIMER_CCX_ENABLE

第二个互补通道输出状态,一样给个使能,TIMER_CCXN_ENABLE

第三第四,通道输出极性和互补通道输出极性,我们都给个高电平,TIMER_OC_POLARITY_HIGHTIMER_OCN_POLARITY_HIGH。表示当输出比较生效的时候我们通道输出高电平。

第五第六个,空闲状态下通道输出,我们和上面非空闲状态来个不一样的低电平,TIMER_OC_IDLE_STATE_LOWTIMER_OCN_IDLE_STATE_LOW。表示当输出比较不生效的时候我们通道输出低电平。

具体这个输出比较的方法,我们后面会再配置。

在我们配置结构体成员之前我们需要先调用一个函数。

timer_channel_output_struct_para_init

就是这个函数,在配置之前先用这个函数进行初始化。

timer_channel_output_mode_config

设置输出比较模式。

我们主要看看模式0和模式1,一般都选模式0。

简单来说模式0是当我们计数器的值小于我们设置的值时,通道输出我们之前设置好的极性(我们上面选了高电平),反之输出空闲状态下的电平(我们上面选了低电平)。

模式1和模式0相反。

timer_primary_output_config

上面的配置完之后(记得还有之前的定时器也要先配置好),我们调用这个函数就可以使能通道输出了。

timer_channel_output_pulse_value_config

设置通道输出的比较值,要注意的是它需要和计数器的值做比较,因此它不要大于计数器的最大值(就是我们配置定时器时的周期值),否则永远都无法触发。

呼吸灯示例代码

因为我们设置的定时器周期值就是计数器达到的最大值,并且是需要和输出比较值做比较的,因此我们最好是选择10的倍数,这样好计算占空比。

#include "gd32e23x.h"
#include "systick.h"

int main(void){
    systick_config();
        
    rcu_periph_clock_enable(RCU_TIMER15);                   //开启定时器时钟  
    rcu_periph_clock_enable(RCU_GPIOB);   
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_8);  
    gpio_output_options_set(GPIOB,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);    
    gpio_af_set(GPIOB,GPIO_AF_2,GPIO_PIN_8);
    
    timer_parameter_struct timer_initpara;                  
    timer_initpara.prescaler = 72 - 1;                      //预分频
    timer_initpara.alignedmode = TIMER_COUNTER_EDGE;        //边缘对齐
    timer_initpara.counterdirection = TIMER_COUNTER_UP;     //向上计数
    timer_initpara.period = 1000 - 1;                       //周期    最好是10的倍数,这样好计算占空比
    timer_init(TIMER15,&timer_initpara);                    //初始化定时器
    
    timer_prescaler_config(TIMER15, 1, TIMER_PSC_RELOAD_NOW);//设置预分频器为立即加载模式
    
    timer_enable(TIMER15);                                  //使能定时器
   
    timer_oc_parameter_struct timer_ocinitpara;
    timer_channel_output_struct_para_init(&timer_ocinitpara);  //先初始化一下配置结构体

    timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;           //使能
    timer_ocinitpara.outputnstate = TIMER_CCXN_ENABLE;
    timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;     //高电平
    timer_ocinitpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;    //低电平
    timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    
    timer_channel_output_config(TIMER15,TIMER_CH_0, &timer_ocinitpara); //配置通道输出
    
    timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_PWM0);// 配置定时器通道输出比较模式
    
    timer_primary_output_config(TIMER15, ENABLE);       //使能输出比较
    
    while(1){
        for(uint16_t i=0;i<1000;++i){
            timer_channel_output_pulse_value_config(TIMER15,TIMER_CH_0,i);
            delay_ms(1);
        }
    }
}

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

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

相关文章

IDEA一键启动多个微服务

我们在做微服务项目开发的时候&#xff0c;每次刚打开IDEA&#xff0c;就需要把各个服务一个个依次启动&#xff0c;特别是服务比较多时&#xff0c;逐个点击不仅麻烦还费时。下面来说一下如何一键启动多个微服务。 操作步骤 点击Edit Configurations 2.点击“”&#xff0c;…

BSD盲区检测系统性能要求及试验方法

相关术语 盲区检测(bsd,blind spot detection)试验车辆(subject vehicle)目标车辆(target vehicle)横向距离(lateral distance):试验车车身最外缘(不包含外后视镜)与目标车辆车身最外缘(不包含外后视镜)之间的横向距离。 纵向距离(longitudinal distance):试验…

用windows server backup备份文件夹到网络共享文件夹并恢复

一、备份 开始 运行windows server backup,在右边的窗格中点击“备份计划” 选择备份配置 因为我们要备份的是一个文件夹&#xff0c;所以&#xff0c;选“自定义”&#xff0c;卷即为磁盘分区。 选择要备份的项 点击添加项目&#xff0c;可依次添加多个备份项目。 勾选需要…

职场思考-阅读专业与技能同步增长(12)

我们可以发现一个人“逆袭”的关键就是先要改变自己的思想&#xff0c;而机遇、资源都是外部条件。 改变思想无非也就几个途径&#xff1a; 一是阅读换脑&#xff0c;二是遇贵人点拨&#xff0c;三是社会“碰壁”后的反思并改正 对于职场进阶而言&#xff0c;阅读更是必要手段 …

知名专业定制线缆知名智造品牌推荐-精工电联:解决水下机器人线缆行业痛点的领航者

在科技日新月异的今天&#xff0c;精工电联作为高科技智能化产品及自动化设备专用连接线束和连接器配套服务商&#xff0c;致力于为高科技行业提供高品质、高性能的集成线缆和连接器定制服务。我们不仅是高品质定制线缆供应商&#xff0c;更是水下机器人线缆行业痛点的有效解决…

Dynamics CRM 修改新建记录的CreatedOn字段值

CRM在创建新记录时&#xff0c;一些系统属性例如创建者、创建时间是取当前创建记录的人以及当前的时间&#xff0c;而有时这些属性需要更改&#xff0c;例如创建时间&#xff0c;这个场景更多的用在数据迁移的时候&#xff0c;老数据有他的原始创建时间&#xff0c;不能因为迁移…

Linux网络-使用Tcp协议进行网络通信并通过网络接口实现远端翻译

文章目录 Tcp协议Tcp协议常见API接口1. int socket(int domain, int type, int protocol);2. int bind(int socket, const struct sockaddr *address, socklen_t address_len);struct sockaddr 3. int listen(int socket, int backlog);4. int accept(int socket, struct socka…

【设计模式】结构型-门面模式

前言 在软件开发中&#xff0c;设计模式是解决特定问题的经验总结&#xff0c;为开发者提供了一种可复用的解决方案。其中&#xff0c;门面模式&#xff08;Facade Pattern&#xff09;是一种结构型模式&#xff0c;旨在为复杂系统提供简化的接口&#xff0c;使客户端与系统之…

Java(十一)---String类型

文章目录 前言1.String类的重要性2.常用方法2.1.字符串的创建2.2.字符串的比较2.2.1.比较是否引用同一个对象2.2.2.boolean equals(Object anObject) 方法&#xff1a;2.2.3.int CompareTo(String s)2.2.4.int compareToIgnoreCase(String str) 方法&#xff1a; 2.3.字符串的查…

算法(十四)动态规划

算法概念 动态规划&#xff08;Dynamic Programming&#xff09;是一种分阶段求解的算法思想&#xff0c;通过拆分问题&#xff0c;定义问题状态和状态之间的关系&#xff0c;使得问题能够以递推&#xff08;分治&#xff09;的方式去解决。动态规划中有三个重点概念&#xff…

C 基础 - 预处理命令和基本语法详解

#include <stdio.h> //预处理指令int main() //函数 {printf("Hello, World!"); //输出语句return 0; //返回语句 } 目录 一.预处理指令 1.#define #ifdef #ifndef #if #else #elif #endif 2.#inlcude a.新增一个文件 b.#include c.运行结果 d.扩…

AI炒股-批量爬取网易财经的要闻板块

工作任务和目标&#xff1a;批量爬取网易财经的要闻板块 在class"tab_body current"的div标签中&#xff1b; 标题和链接在&#xff1a;<a href"https://www.163.com/dy/article/J2UIO5DD051188EA.html">华为急需找到“松弛感”</a> 第一步&…

【原创教程】MES服务器与成品打标机控制说明

1 实现的功能及应用的场合 MES即制造执行系统(manufacturing execution system,简称MES),即在加强MRP计划的执行功能,把MRP计划同车间作业现场控制,通过执行系统联系起来。 MES是一个生产管理智能化的一个系统,是用于生产时记录数据、产量等信息的智能管理系统。 该项…

WebGL画粗线

目录 前言 基本思路 求左右端点 实现 组织数据 顶点着色器计算端点坐标 效果 前言 WebGL绘制模式有点、线、面三种&#xff1b;通过点的绘制可以实现粒子系统等&#xff0c;通过线可以绘制一些连线关系&#xff1b;面就强大了&#xff0c;通过面&#xff0c;我们可以…

材质技术在AI去衣中的作用

随着人工智能技术的飞速发展&#xff0c;越来越多的应用场景开始涌现。其中&#xff0c;AI去衣技术作为一种新兴的图像处理技术&#xff0c;已经在很多领域得到了广泛的应用。而在AI去衣技术中&#xff0c;材质技术起到了至关重要的作用。本文将详细介绍材质技术在AI去衣中的作…

【前缀和 记忆化搜索】LeetCode1444. 切披萨的方案数

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 记忆化搜索 LeetCode1444. 切披萨的方案数 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; ‘A’ &#xff…

生成式AI,在云端的绽放与盛开

编辑&#xff1a;阿冒 设计&#xff1a;沐由 毫无疑问&#xff0c;生成式AI已然成为当今技术发展和应用创新的重要引擎之一。 过去的一年多时间里&#xff0c;我们每个人都在目睹和见证着生成式AI是如何以移山倒海的力量&#xff0c;为诸多行业带来革命性乃至颠覆性的变革&…

Python3位运算符

前言 本文介绍的是位运算符&#xff0c;位运算可以理解成对二进制数字上的每一个位进行操作的运算&#xff0c;位运算分为 布尔位运算符 和 移位位运算符。 文章目录 前言一、位运算概览1、布尔位运算符1&#xff09;按位与运算符 ( & )2&#xff09;按位或运算符 ( | )3…

输入输出安全防护指南

输入输出安全防护指南 在现代网络应用程序中&#xff0c;输入输出的安全性是至关重要的。未经验证的输入和未编码的输出可能导致严重的安全漏洞&#xff0c;如SQL注入、跨站脚本攻击&#xff08;XSS&#xff09;等。本文将详细讨论如何通过输入验证和输出编码来确保应用程序的…

9. C++通过epoll+fork的方式实现高性能网络服务器

epollfork 实现高性能网络服务器 一般在服务器上&#xff0c;CPU是多核的&#xff0c;上述epoll实现方式只使用了其中的一个核&#xff0c;造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…