普冉(PUYA)单片机开发笔记(6): 呼吸灯

概述

上一篇的实验中,分别正确地配置了 TIM16 和 TIM1,TIM16 的中断服务程序中每隔 500ms 翻转板载 LED 一次;TIM1 的 CHANNEL_1 用于输出一个固定占空比的 PWM 信号。这一次我们进一小步:使用 TIM16 的中断设置 TIM1 CHANNEL_1 的 PWM 输出呈现从小到大,再从大到小的循环,即实现呼吸灯效果。

为此,PWM 输出改用千分之一精度的调节,TIM16 的定时周期设置为 8 毫秒,PWM 从 0% 到 100%,耗时 8秒。

对于 TIM1,PWM_PERIOD 定义为 2400,PWM 调节步长设置为 2.4F,和 1000 步调节到位相对应。PWM_PERIOD 参数用于 TIM1 的 ARR 装填,PWM 输出频率为 10KHz。

实现代码

修改 main.h 文件

将 PWM 分频参数 PWM_PERIOD 搬到 mian.h 中

新增一个千分之一 PWM 输出的函数:

void TIM1_PWM_Output_Permill(const uint16_t duty_permill);

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H#ifdef __cplusplus
extern "C"
{
#endif#ifndef PWM_PERIOD
#define PWM_PERIOD 2400
#endif/* Includes ------------------------------------------------------------------*/
#include "py32f0xx_hal.h"
#include "py32f003xx_Start_Kit.h"
#include <stdbool.h>/* Exported functions prototypes ---------------------------------------------*/
HAL_StatusTypeDef SystemClock_Config(void);
HAL_StatusTypeDef GPIO_Config(void);
HAL_StatusTypeDef USART_Config(void);
HAL_StatusTypeDef DBG_UART_Start(void);
HAL_StatusTypeDef TIM16_Config(void);
HAL_StatusTypeDef TIM16_Start(void);HAL_StatusTypeDef TIM1_PWM_Config(void);
HAL_StatusTypeDef TIM1_PWM_Start(uint32_t duty);
HAL_StatusTypeDef TIM1_PWM_Stop(void);
void TIM1_PWM_Output(const uint8_t duty_percent);
void TIM1_PWM_Output_Permill(const uint16_t duty_permill);void Debug_Info(const char* msg);...
...

在 app_pwm.c 中实现 TIM1_PWM_Output_Permill 函数

void TIM1_PWM_Output_Permill(const uint16_t duty_permill)
{uint16_t tmp_duty = 0;uint32_t duty     = 0;tmp_duty = duty_permill;if(duty_permill > 1000) tmp_duty = 999;duty = (uint32_t)(tmp_duty * PWM_PERIOD / 1000.0F + 0.5F) + 1;TIM1_PWM_Start(duty);
}

计算 duty 时,加的那个 0.5F 是处理四舍五入用的。

修改 app_timer.c 文件

在原有代码上增加三个全局变量

#include "main.h"TIM_HandleTypeDef htim16;#define  gPwmStep            2.4F
uint16_t gCurrentDutyPermill = 0;
int8_t   gPwmDir             = 1;...
...

初始化代码修改如下,Period 和 Prescaler 的设定值使 TIM16 的定时周期为 0.008s ,即8毫秒。

HAL_StatusTypeDef TIM16_Config(void)
{HAL_StatusTypeDef conf_res = HAL_OK;htim16.Instance = TIM16;                                       // 选择 TIM16htim16.Init.Period            = 12000 - 1;                     // 自动重装载值 500ushtim16.Init.Prescaler         = 16 - 1;                        // 预分频为 2-1,两者确定定时器中断周期为1mshtim16.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;        // 时钟不分频htim16.Init.CounterMode       = TIM_COUNTERMODE_UP;            // 向上计数htim16.Init.RepetitionCounter = 1 - 1;                         // 不重复计数htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // TIMx ARR 缓冲conf_res = HAL_TIM_Base_Init(&htim16);                         // TIMx 初始化if ( conf_res != HAL_OK)                         return conf_res;return HAL_OK;
}

在 HAL_TIM_PeriodElapsedCallback 函数中计算出呼吸灯的调节量,并调用 TIM1_PWM_Output_Permill 函数执行 PWM 输出。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance != TIM16) return;TIM1_PWM_Output_Permill(gCurrentDutyPermill);gCurrentDutyPermill = (uint16_t)(gCurrentDutyPermill + gPwmDir * gPwmStep);if(gPwmDir == 1){if(gCurrentDutyPermill >= 1000){gPwmDir = -1;gCurrentDutyPermill = 1000;}}else {if(gCurrentDutyPermill <= (uint16_t)(gPwmStep + 0.5)){gPwmDir = 1;gCurrentDutyPermill = 0;}}
}

代码中原有的翻转 LED 灯的那一句去掉了:闪烁频率太高,看着不舒服了。

稍微修改一下 main() 函数

注意要将 TIM16 的初始化函数放到 TIM1_PWM 初始化函数前面。

int main(void)
{HAL_Init();             // systick初始化SystemClock_Config();   // 配置系统时钟if(USART_Config() != HAL_OK) Error_Handler();         printf("[SYS_INIT] Debug port initilaized.\r\n");if(GPIO_Config() != HAL_OK) Error_Handler();          printf("[SYS_INIT] Board LED initilaized.\r\n");if(TIM16_Config() != HAL_OK) Error_Handler();printf("[SYS_INIT] Timer initialized.\r\n");if(TIM1_PWM_Config() != HAL_OK) Error_Handler();printf("[SYS_INIT] PWM initialized.\r\n");if (TIM16_Start() != HAL_OK) Error_Handler();printf("[SYS_INIT] Timer started.\r\n");printf("\r\n+---------------------------------------+""\r\n|        PY32F003 MCU is ready.         |""\r\n+---------------------------------------+""\r\n");if (DBG_UART_Start() != HAL_OK) Error_Handler();// TIM1_PWM_Output_Permill(250);while (1) { }
}

总结

示波器的输出波形已通过视频上传,达到设计预期。

视频链接:PY32F003 的呼吸灯效果-CSDN直播

要点:

  • 根据 PWM 输出精度的要求设置 TIM1 对应通道 PWM 的频率,例如,要实现千分之一的逐级调节,PWM_PERIOD 就要设置得大于1000才好。
  • 根据 PWM 调节时长限制确定 TIM16 的定时周期,例如,要实现 8秒完成一轮调节,每一轮调节需要 1000 次递增/递减,则需要将 TIM16 的定时周期设置为 8 毫秒。
  • TIM16 的初始化和启动应放在 TIM1 的初始化之后。
  • 在 TIM16 的中断服务程序中,以最少的时间代价完成 TIM1 PWM 通道的输出。

问题点:在 PWM 波形变化过程中,会出现少许凹陷的毛刺,还没有找到原因。

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

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

相关文章

MyBatis进阶之分页和延迟加载

文章目录 分页1. RowBounds 分页2. PageHelper 分页3. PageInfo 对象属性描述 延迟加载立即加载激进式延迟加载真-延迟加载 分页 Mybatis 中实现分页功能有 3 种途径&#xff1a; RowBounds 分页&#xff08;不建议使用&#xff09;Example 分页&#xff08;简单情况可用)Pag…

关于对向量检索研究的一些学习资料整理

官方学习资料 主要是的学习资料是&#xff0c; 官方文档 和官方博客。相关文章还是挺多 挺不错的 他们更新也比较及时。有最新的东西 都会更新出来。es scdn官方博客 这里简单列一些&#xff0c;还有一些其他的&#xff0c;大家自己感兴趣去看。 什么是向量数据库 Elasticse…

文件加密软件哪个最好用 好用的文件加密软件推荐

一说到文件加密软件&#xff0c;可能大家都会去搜一些不知名的软件来&#xff0c;但是选择这种加密软件&#xff0c;最好还是要看一些资质的。 资质不好的&#xff0c;可能加密过后你自己也打不开文件&#xff0c;&#xff08;ps&#xff1a;我自己就遇到过这种情况&#xff09…

【华为OD机试python】分苹果【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 A、B两个人把苹果分为两堆,A希望按照他的计算规则等分苹果, 他的计算规则是按照二进制加法计算,并且不计算进位 12+5=9(1100 + 0101 = 9), B的计算规则是十进制加法,包括正常进位,…

基于Java SSM框架高校校园点餐订餐系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架高校校园点餐订餐系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&a…

(一)Java 基础语法

目录 一. 前言 二. Hello World 三. Java 语法 3.1. 基本语法 3.2. Java 标识符 3.3. Java 修饰符 3.4. Java 变量 3.5. Java 数组 3.6. Java 枚举 3.7. Java 关键字 3.8. Java 注释 3.9. Java 空行 3.10. Java 继承 3.11. Java 接口&#xff08;interface&#…

Oracle(2-14)User-Managed Incomplete Recovery

文章目录 一、基础知识1、Incomplete Recovery Overview 不完全恢复概述2、Situations Requiring IR 需要不完全恢复的情况3、Types of IR 不完全恢复的类型4、IR Guidelines 不完全恢复指南5、User-Managed Procedures 用户管理程序6、RECOVER Command Overview 恢复命令概述7…

算法训练营Day8(字符串)

344.反转字符串 344. 反转字符串 - 力扣&#xff08;LeetCode&#xff09; class Solution {public void reverseString(char[] s) {for(int i 0,j s.length-1;i< s.length/2 ; i,j--){swap(s,i,j);}}public void swap(char[] s,int i,int j ){char temp s[i];s[i] s[j]…

Python数据科学视频讲解:Python注释

2.3 Python注释 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.3节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据科学应用和…

20231210原始编译NanoPC-T4(RK3399)开发板的Android10的SDK

20231210原始编译NanoPC-T4(RK3399)开发板的Android10的SDK 2023/12/10 17:27 rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ mkdir nanopc-t4 rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ cd nanopc-t4/ …

python4E 之 Dict 找到两个不同索引但都需要对应的值。

找到两个不同索引但都需要&#xff0c;对应的值。 df pd.DataFrame(np.random.randint(1, 10, [3,3]), columns list(ABC)) 通过 dict 制造key index_htable{} for _,row in idc.iterrows(): #按行循环 key str(row[u股票代码]) | str(row[u日期]) #根据不同 的索引…

45.0/HTML 简介(详细版)

目录 45.1 互联网简介 45.2 网页技术与分类 45.3 HTML 简介 45.3.1 什么是 HTML?(面试题) 45.3.2 HTML 文件结构 45.3.3 HTML 语法 45.3.4 实例演练步骤(面试题) 45.4 head 中的常用标签 45.4.1 title 标记 45.4.2 meta 标记 45.4.3 45.4.4 45.4.4(面试题)总结: 45…

【AIE】AIE微信合集

AIE微信合集 AIE(1) 对于Versal&#xff0c;我们从系统角度看&#xff0c;可将其分为3个Domain&#xff1a;AIE、PS和PL&#xff0c;如下图所示。如果要运行一个AIE的应用&#xff0c;绝大多数情况下&#xff0c;这3个Domain我们都会用到&#xff0c;使其协同工作。这里我们仅…

linux less命令(less指令)(查看开头、从开头查看、从起始查看、反向导航、反向查找)

文章目录 Linux Less 命令1. Less 命令简介2. 基础用法less filename<command> | less 3. 常用命令行选项4. 高级技巧和用法4.1 搜索内容4.2 标记和跳转4.3 查看多个文件 5. less命令使用文档6. 总结 Linux Less 命令 less 是一种在Linux环境中查看文件内容的工具&#…

《绝地求生》新手怎么玩 游戏基本介绍

随着电竞热潮的兴起&#xff0c;《绝地求生》已经成为了一款备受玩家热爱的游戏。这款游戏在全球范围内拥有庞大的玩家群体&#xff0c;它将你置身于一个荒无人烟的岛屿上&#xff0c;与其他99名玩家展开生死竞争。作为一个新手&#xff0c;下面闲游盒小盒子就为大家详细介绍一…

Ubuntu20.04创建并挂在zfs池

Ubuntu 下使用 ZFS [适用于中高级用户] 主磁盘上清洁安装带有ZFS的Ubuntu后&#xff0c;可以开始体验其特性。 所有ZFS配置过程都需要命令行。 我不知道有GUI工具。 创建一个 ZFS 池 本节仅适用于具有多个磁盘的系统。 如果只有一个磁盘&#xff0c;Ubuntu会在安装时自动创建…

写实3D游戏模型纹理贴图设置

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xff1a; …

Mybatis源码解析5:Mapper执行流程1

Mybatis源码解析5&#xff1a;Mapper执行流程1 1.项目结构2. 源码分析2.1 Mapper代理 MapperProxy#invoke2.2 创建MapperMethod2.2.1 方法名称解析器ParamNameResolve2.2.2 MapperMethod#execute 2.3 DefaultSqlSession2.4 CachingExecutor2.5 SimpleExecutor#doQuery获取连接对…

Nacos源码解读09——配置中心配置信息创建修改怎么处理的

存储配置 从整体上Nacos服务端的配置存储分为三层&#xff1a; 内存&#xff1a;Nacos每个节点都在内存里缓存了配置&#xff0c;但是只包含配置的md5&#xff08;缓存配置文件太多了&#xff09;&#xff0c;所以内存级别的配置只能用于比较配置是否发生了变更&#xff0c;只用…

进行生成简单数字图片

1.之前只能做一些图像预测,我有个大胆的想法,如果神经网络正向就是预测图片的类别,如果我只有一个类别那就可以进行生成图片,专业术语叫做gan对抗网络 2.训练代码 import torch import torch.nn as nn import torch.optim as optim import torchvision.transforms as transfo…