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

【星闪】Hi2821 | PWM脉宽调制模块 + 呼吸灯例程

1. 简介

        PWM(Pulse Width Modulation),全称脉宽调制,通过对一系列脉冲的宽度进行调制,等效出所需波形。即对模拟信号电平进行数字编码,通过调节频率、占空比的变化来调节信号的变化。

        一个 PWM 周期内由一段高电平和一段低电平区间组成,通过调整高低电平的时间,即占空比,可以等效输出不同的电压。

        比如,周期为 100ms,高电平时间为 50ms,低电平时间为 50ms,即占空比为 50%,VCC 假设为 5V,那么等效输出的电压为 1.15V。

2. 硬件特性

        Hi2821 一共有 12 路 PWM 输出通道;支持PWM分组,一个组可以分配多个通道,同一个通道不能同时位于不同的组里。

3. 例程

3.1 Kconfig

        SDK 是默认打开 PWM 的编译的,配置项不多,基本上也不需要配置。唯一可能要配置的是最后一个“Using PWM PRELOAD”,它的作用是可以预配置一系列占空比,这样 PWM 输出完一个周期后,驱动会自动加载下一个周期的配置。

3.2 代码

#include "soc_osal.h"
#include "app_init.h"
#include "pwm.h"
#include "hal_pwm.h"
#include "pinctrl.h"#include <string.h>
#include <stdint.h>#define PWM_GROUP_ID 0static uint8_t pwm_chn = 0;
static pwm_config_t pwm_cfg = {1000,0,0,100,false
};static errcode_t pwm_callback(uint8_t channel)
{static uint8_t dir = 0;if (dir) {pwm_cfg.low_time++;pwm_cfg.high_time--;} else {pwm_cfg.low_time--;pwm_cfg.high_time++;}/* 更新占空比 */hal_pwm_funcs_t *func = hal_pwm_get_funcs();func->set_time(PWM_SET_LOW_TIME, (pwm_channel_t)channel, pwm_cfg.low_time);func->set_time(PWM_SET_HIGH_TIME, (pwm_channel_t)channel, pwm_cfg.high_time);func->set_action(PWM_GROUP_ID, PWM_ACTION_START);osal_printk("duty cycle, high: %u, low: %u\r\n", pwm_cfg.high_time, pwm_cfg.low_time);if (pwm_cfg.low_time == 0) {dir = 1;} else if (pwm_cfg.low_time == 1000) {dir = 0;}return 0;
}void app_main(void *unused)
{(void)(unused);int ret = 0;/* 初始化管脚 */uapi_pin_set_mode(31, HAL_PIO_PWM0);/* 初始化PWM */uapi_pwm_deinit();uapi_pwm_init();ret = uapi_pwm_open(pwm_chn, &pwm_cfg);if (ret) {osal_printk("PWM init failed, err: %X");return;}uapi_pwm_register_interrupt(pwm_chn, pwm_callback);osal_printk("\r\nPWM freq: %d Hz\r\n", uapi_pwm_get_frequency(pwm_chn));uapi_pwm_set_group(PWM_GROUP_ID, &pwm_chn, 1);uapi_pwm_start_group(PWM_GROUP_ID);
}

1. 初始化管脚

        我使用的是开发板上自带的 LED 灯,对应 31 号管脚,只需要调用 uapi_pin_set_mode 函数配置复用到对应的 PWM 通道即可。

2. 初始化 PWM

        先调用 uapi_pwm_init 初始化驱动;接着调用 uapi_pwm_open 配置通道运行参数,参数一为通道号,参数二为运行参数,定义如下:

typedef struct pwm_config {uint32_t low_time;               /*!< @if Eng PWM working clock cycle count low level part,PWM work frequency @ref uapi_pwm_get_frequency().If the PWM operating cycle is Tus,the actual low-level time = low_time * Tus.@else   PWM工作时钟周期计数个数低电平部分,频率参考 @ref uapi_pwm_get_frequency()。如果PWM工作周期为Tus, 实际低电平时间 = low_time * Tus @endif */uint32_t high_time;              /*!< @if Eng PWM working clock cycle count high level part,PWM work frequency @ref uapi_pwm_get_frequency().If the PWM operating cycle is Tus,the actual high-level time = high_time * Tus.@else   PWM工作时钟周期计数个数高电平部分,频率参考 @ref uapi_pwm_get_frequency()。如果PWM工作周期为Tus, 实际高电平时间 = high_time * Tus @endif */uint32_t offset_time;            /*!< @if Eng PWM offset time.@else   PWM相位。  @endif */uint16_t cycles;                 /*!< @if Eng PWM cycles, range:0~32767 (15bit).@else   PWM重复周期,范围:0~32767 (15bit)。  @endif */bool repeat;                     /*!< @if Eng Flag to indicate PWM should output continuously.@else   指示PWM应连续输出的标志。  @endif */
} pwm_config_t;
  • low_time:低电平时间;
  • high_time:高电平时间;
  • offset_time:相位偏移;
  • cycles:重复周期;
  • repeat:是否连续周期。

        PWM 的时钟默认是 32MHz,也可以调 uapi_pwm_get_frequency 去获取。low_time 和 high_time 的值是 PWM 时钟的周期数,那么可以得出一个 PWM 周期的时间为:(low\_time+high\_time)\times \frac{1}{32000000}

        cycles 和 repeat 是互斥的,如果设置了 repeat,那么驱动会忽略 cycles 的值。

        然后调用 uapi_pwm_register_interrupt 注册中断回调,当 PWM 完成了一个输出任务时,这个回调就会调用。

如果设置了 repeat 这个中断就永远不会调用,因为输出的任务永远不会结束。

另外,中断回调注册一定要放在 uapi_pwm_open 之前,因为后者会使用驱动默认的中断回调去覆盖回调函数。

        调用 uapi_pwm_set_group 设置 PWM 组,最多可设置 6 个组;参数一为组号,参数二为通道号列表,参数三为通道数。最后调用 uapi_pwm_start_group 去使能对应组的输出任务。

3. 中断回调函数

        在中断回调函数里面去调整占空比,目前的 SDK 比较 low,还没有移植调整占空比的函数,所以只能调用 HAL 层的函数接口去调整。

        调用 hal_pwm_get_funcs 函数可以获取 PWM 底层的操作函数,调用 set_time 函数可以调整 low_time 和 high_time 的值,调整完成后需要调用 set_action 去使能 PWM 输出任务,参数一为组号,参数二填 PWM_ACTION_START。

3.3 测试

        编译并烧录固件,此时就能看到呼吸灯的效果了,下面为部分系统 log。


文章转载自:

http://1CLZko8m.dchpg.cn
http://MwYxCsdU.dchpg.cn
http://C51ygioE.dchpg.cn
http://ewZku4rJ.dchpg.cn
http://oNFIMHMo.dchpg.cn
http://3gm0LWoH.dchpg.cn
http://gffvvsbX.dchpg.cn
http://e667OJ8S.dchpg.cn
http://szAixlhL.dchpg.cn
http://l9LW2ozX.dchpg.cn
http://ZJsMLhc3.dchpg.cn
http://1232V9bE.dchpg.cn
http://uOAuf30D.dchpg.cn
http://y064Dlra.dchpg.cn
http://VsOnio07.dchpg.cn
http://HDviweFI.dchpg.cn
http://yRwEl1ZK.dchpg.cn
http://WCadF631.dchpg.cn
http://SpNuhNiQ.dchpg.cn
http://Mmeo1Dk2.dchpg.cn
http://sI5lbn2J.dchpg.cn
http://MOw9em2O.dchpg.cn
http://DgFc6Rai.dchpg.cn
http://orSfphgG.dchpg.cn
http://poa1Axy5.dchpg.cn
http://0D8Du9ff.dchpg.cn
http://7uBjpnR0.dchpg.cn
http://rhPNRUqp.dchpg.cn
http://6uLpLbTN.dchpg.cn
http://TIhNEDNm.dchpg.cn
http://www.dtcms.com/a/369975.html

相关文章:

  • 具身智能模拟器:解决机器人实机训练场景局限与成本问题的创新方案
  • 【嵌入式】【科普】AUTOSAR学习路径
  • 大麦APP抢票-核心
  • Linux笔记---TCP套接字编程
  • SQL面试题及详细答案150道(81-100) --- 子查询篇
  • CentOS系统停服,系统迁移Ubuntu LTS
  • 基于Spring Boot的幼儿园管理系统
  • 《sklearn机器学习——聚类性能指标》Fowlkes-Mallows 得分
  • STAR-CCM+|雷诺数回顾
  • 设计整体 的 序分(三“释”)、正宗分(双“门”)和流通分(统一的通行表达式) 之3 “自明性”(腾讯元宝 之2)
  • MySQL集群高可用架构之组复制 (MGR)
  • GPT-5发布:统一智能体时代的开启——从“工具”到“协作者”的范式跃迁
  • 【iOS】push 和 present
  • 大数据毕业设计选题推荐-基于大数据的宫颈癌风险因素分析与可视化系统-Spark-Hadoop-Bigdata
  • 【xss基本介绍】
  • 无需公网IP,电脑随时与异地飞牛同步互联保持数据一致性
  • HTML 列表类型
  • 怎么用 tauri 创建一个桌面应用程序(Electron)
  • Redis《RedisSerializer》
  • 云原生的12个要素是什么?
  • uni-app倒计时公共组件 封装,倒计时组件
  • AI驱动的软件测试:革命性的自动化、缺陷检测与实验优化
  • 打包 Uniapp
  • Vue 项目性能优化实战
  • C++ Lambda 表达式完整指南
  • PlantSimulation 在汽车总装车间配送物流仿真中的应用
  • 浅谈前端框架
  • 深蓝汽车人事调整:邓承浩升任董事长,姜海荣出任首席执行官
  • github上传步骤
  • 详解flink性能优化