18-HW_PWM(硬件改变 PWM 占空比)

news/2024/12/22 18:40:15/

ESP32-S3的HW_PWM详解

引言

硬件脉冲宽度调制(HW_PWM)是ESP32-S3的一个重要特性,它可以用于控制LED的亮度、电机的速度等。硬件脉冲宽度调制与软件改变 PWM 占空比实验的驱动一致

软件改变 PWM 占空比

硬件脉冲宽度调制和软件脉冲宽度调制有什么区别

硬件脉冲宽度调制(HW_PWM)和软件脉冲宽度调制(SW_PWM)都是实现脉冲宽度调制的方法,但它们在实现方式和应用场景上有所不同:

  • 硬件脉冲宽度调制(HW_PWM):硬件PWM是通过微控制器的硬件定时器/计数器来生成PWM信号。硬件PWM的优点是精度高,可以实现高速、高精度的脉冲宽度调制,同时可以实现多路同步脉宽调制。

  • 软件脉冲宽度调制(SW_PWM):软件PWM是通过编程控制微控制器的通用输入/输出(GPIO)引脚来生成PWM信号。软件PWM的优点是成本低,可以根据需要随时调整频率和占空比,实现起来比较简单。

使用硬件改变 PWM 占空比

LEDPWM 控 制 器 硬 件 可 逐 渐 改 变 占 空 比 的 数 值 。 要 使 用 此 功 能 , 需 用 函 数
ledc_fade_func_install()使能渐变,之后用下列可用渐变函数之一配置:

  • ledc_set_fade_with_time()
  • ledc_set_fade_with_step()
  • ledc_set_fade()

最后需要调用 ledc_fade_start()开启渐变。渐变可以在阻塞或非阻塞模式下运行,具体区别请查看 ledc_fade_mode_t。需要特别注意的是,不管在哪种模式下,下一次渐变或是单次占空比配置的指令生效都必须等到前一次渐变完成或被中止。中止一个正在运行中的渐变需要调用函数 ledc_fade_stop()。如不需要渐变和渐变中断,可用函数 ledc_fade_func_uninstall()关闭。

使用硬件改变 PWM达到LDE呼吸灯效果

pwm.h

// 文件: pwm.h
// 作者: 宁子希 (1589326497@qq.com)
// 简介: PWM驱动代码
// 版本: 0.1
// 日期: 2024-04-24
// 版权所有 (c) 2024#ifndef __PWM_H_
#define __PWM_H_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"        // 这个头文件包含了FreeRTOS中信号量的相关函数和宏定义
#include "driver/ledc.h"
#include "driver/gpio.h"// 引脚以及重要参数定义
#define LEDC_PWM_TIMER          LEDC_TIMER_0        // 使用定时器0
#define LEDC_PWM_MODE           LEDC_LOW_SPEED_MODE // 模式设定必须使用LEDC低速模式
#define LEDC_PWM_CH0_GPIO       GPIO_NUM_10          // LED控制器通道对应GPIO
#define LEDC_PWM_CH0_CHANNEL    LEDC_CHANNEL_0      // LED控制器通道号
#define LEDC_PWM_DUTY           8000                // 渐变的变大最终目标占空比
#define LEDC_PWM_FADE_TIME      3000                // 变化时长// 函数声明
void pwm_init(uint8_t resolution, uint16_t freq);   // 初始化PWM
void pwm_set_duty(uint16_t duty);                   // PWM占空比设置#endif

pwm.c

/*** @file pwm.c* @author 宁子希 (1589326497@qq.com)* @brief PWM驱动代码* @version 0.1* @date 2024-04-24* * @copyright Copyright (c) 2024* */
#include "pwm.h"
/*** @brief       初始化PWM* @param       resolution:PWM占空比分辨率*              freq: PWM信号频率* @retval      无*/
void pwm_init(uint8_t resolution, uint16_t freq){ledc_timer_config_t ledc_timer;                 // LEDC定时器句柄ledc_channel_config_t ledc_channel;             // LEDC通道配置句柄// 配置LEDC定时器ledc_timer.duty_resolution = resolution;        // PWM占空比分辨率ledc_timer.freq_hz = freq;                      // PWM信号频率ledc_timer.speed_mode = LEDC_PWM_MODE;          // 定时器模式ledc_timer.timer_num = LEDC_PWM_TIMER;          // 定时器序号ledc_timer.clk_cfg = LEDC_AUTO_CLK;             // LEDC时钟源ledc_timer_config(&ledc_timer);                 // 配置定时器// 配置LEDC通道ledc_channel.gpio_num = LEDC_PWM_CH0_GPIO;      // LED控制器通道对应引脚ledc_channel.speed_mode = LEDC_PWM_MODE;        // LEDC高速模式ledc_channel.channel = LEDC_PWM_CH0_CHANNEL;    // LEDC控制器通道号ledc_channel.intr_type = LEDC_INTR_DISABLE;     // LEDC失能中断ledc_channel.timer_sel = LEDC_PWM_TIMER;        // 定时器序号ledc_channel.duty = 0;                          // 占空比值ledc_channel_config(&ledc_channel);             // 配置LEDC通道ledc_fade_func_install(0);                      // 使能渐变(该函数不可或缺)}/*** @brief       PWM占空比设置* @param       duty:PWM占空比* @retval      无*/
void pwm_set_duty(uint16_t duty){ledc_set_fade_with_time(LEDC_PWM_MODE, LEDC_PWM_CH0_CHANNEL, duty, LEDC_PWM_FADE_TIME);   // 设置占空比以及渐变时长ledc_fade_start(LEDC_PWM_MODE, LEDC_PWM_CH0_CHANNEL, LEDC_FADE_NO_WAIT);                  // 开始渐变ledc_set_fade_with_time(LEDC_PWM_MODE, LEDC_PWM_CH0_CHANNEL, 0, LEDC_PWM_FADE_TIME);      // 设置占空比以及渐变时长ledc_fade_start(LEDC_PWM_MODE, LEDC_PWM_CH0_CHANNEL, LEDC_FADE_NO_WAIT);                  // 开始渐变
}

main.c

/*** @file main.c* @author 宁子希 (1589326497@qq.com)* @brief PWM驱动代码* @version 0.1* @date 2024-04-24* * @copyright Copyright (c) 2024* */#include "nvs_flash.h"
#include "pwm.h"void app_main(void){//初始化NVSesp_err_t ret;ret = nvs_flash_init();             if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}pwm_init(13, 5000);                 //初始化PWMfor(;;) {vTaskDelay(10/portTICK_PERIOD_MS);pwm_set_duty(LEDC_PWM_DUTY);    //设置占空比}   }

参考资料

LED PWM 控制器


http://www.ppmy.cn/news/1433678.html

相关文章

使用linux,c++,创作一个简单的五子棋游戏

#include <iostream> #include <vector> #include <unordered_map> using namespace std; // 棋盘大小 const int BOARD_SIZE 15; // 棋子类型 enum ChessType { EMPTY, BLACK, WHITE }; // 棋盘类 class ChessBoard { private: vect…

QML中使用正则表达式

我想在TextField控件中使用正则表达式&#xff0c;然后GPT4给出的回答是这样的&#xff1a; TextField {id: versionInputplaceholderText: qsTr("输入版本号")validator: RegExpValidator { regExp: /^[a-zA-Z0-9]*$/ } // 仅允许字母和数字width: 120 // 设置合…

MapReduce排序机制(Hadoop)

在MapReduce中&#xff0c;排序的目的是为了方便Reduce阶段的处理&#xff0c;通常是为了将相同键的键值对聚合在一起&#xff0c;以便进行聚合操作或其他处理。 1. Map阶段的局部排序&#xff08;Local Sorting&#xff09;&#xff1a; 对于MapTask&#xff0c;它会将处理的…

nvm使用指定镜像安装node和npm包

场景 使用nvm时&#xff0c;默认的安装源经常碰到找不到可用版本的问题&#xff0c;这时就需要指定镜像源。比如如果你在学习鸿蒙ArkTs项目的开发&#xff0c;就需要指定从华为官方镜像上安装指定版本的node和npm包 命令 以windows为例&#xff0c;以管理员身份运行cmd工具&…

Android UI底层绘制原理

自定义View继承自View类&#xff0c;需要重写onDraw方法&#xff0c;通过canvas和paint进行绘制 Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawLine();} public void drawLine(float startX, float startY, float stopX, float stopY,NonN…

C++ | Leetcode C++题解之第45题跳跃游戏II

题目&#xff1a; 题解&#xff1a; class Solution { public:int jump(vector<int>& nums) {int maxPos 0, n nums.size(), end 0, step 0;for (int i 0; i < n - 1; i) {if (maxPos > i) {maxPos max(maxPos, i nums[i]);if (i end) {end maxPos;s…

flutter release 报错 Error: SocketException: Failed host lookup:

flutter 的 debug 模式没有任何问题 &#xff0c;打了release 包后一直报下面的错&#xff0c;查了一下是 因为没有网络权限 Error: SocketException: Failed host lookup: yomi-test-aws-sg.yomigame.games (OS Error: No address associated with hostname, errno 7) 按照下…

大模型的实践应用22-谷歌Gemma AI大模型的架构原理,以及Gemma模型的部署安装本地教程

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用22-谷歌Gemma AI大模型的架构原理,以及Gemma模型的部署安装本地教程。谷歌Gemma AI大模型是由Google AI团队开发并开源。Gemma模型采用Transformer编码器-解码器架构,并加入了一些改进,例如使用稀疏注意力机制来提高推…