ARM32开发--PWM通道输出

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

文章目录

前言

内容

需求

通用定时器多通道

开发流程

多通道配置

占空比更新

完整代码

高级定时器通道输出

开发流程

通道配置

Break配置

完整代码

总结


前言

  1. 加强掌握PWM开发流程
  2. 理解定时器与通道的关系
  3. 掌握多通道配置策略
  4. 掌握定时器查询方式
  5. 掌握代码抽取优化策略

内容

需求

点亮4个灯,采用pwm的方式。

定时器

通道

引脚

AF

LED序号

T3

CH0

PD12

AF2

LED5

CH1

PD13

AF2

LED6

CH2

PD14

AF2

LED7

CH3

PD15

AF2

LED8

实现LED5, LED6, LED7, LED8呼吸灯效果

通用定时器多通道

点亮T3定时器下的多个通道的灯。

开发流程

  1. 添加Timer依赖
  2. 初始化PWM相关GPIO
  3. 初始化PWM,包含多通道配置
  4. PWM占空比控制

多通道配置

void timer_channel_config(uint32_t timer_periph, uint16_t channel) {/* TIMER 通道输出配置 */timer_oc_parameter_struct ocpara;/* initialize TIMER channel output parameter struct */timer_channel_output_struct_para_init(&ocpara);/* 启用P极输出 */ocpara.outputstate  = (uint16_t)TIMER_CCX_ENABLE;/* 配置输出参数 configure TIMER channel output function */timer_channel_output_config(timer_periph, channel, &ocpara);/* 配置通道输出输出比较模式 configure TIMER channel output compare mode */timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}

输出比较模式

  • TIMER_OC_MODE_PWM0: 高电平有效
  • TIMER_OC_MODE_PWM1:低电平有效

占空比更新

/*********************************************************** @brief 更新pwm占空比* @param timer_periph 定时器* @param channel 通道* @param duty  占空比[0, 100]* @return **********************************************************/
void PWM_update(uint32_t timer_periph, uint16_t channel, float duty) { // 0-100if(duty > 100) duty = 100;else if(duty < 0) duty = 0;//	pulse / PERIOD == duty / 100uint32_t pulse = PERIOD * duty / 100.0f - 1;// 计数值 65535timer_channel_output_pulse_value_config(timer_periph, channel, pulse);
}

完整代码

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "USART0.h"void USART0_on_recv(uint8_t* data, uint32_t len) {printf("g_rx_buffer: %s g_rx_cnt:%d \n", data, len);
}static void GPIO_config() {rcu_periph_clock_enable(RCU_GPIOC);gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_bit_reset(GPIOC, GPIO_PIN_6);
}void timer_gpio_config(uint32_t gpio_rcu, uint32_t gpio_port, uint32_t gpio_pin, uint32_t gpio_af) {rcu_periph_clock_enable(gpio_rcu);/* 设置gpio模式 */gpio_mode_set(gpio_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_pin);gpio_output_options_set(gpio_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gpio_pin);gpio_af_set(gpio_port, gpio_af, gpio_pin);
}void timer_init_config(rcu_periph_enum rcu_periph, uint32_t timer_periph,uint16_t t_prescaler, uint32_t t_period) {rcu_periph_clock_enable(rcu_periph);timer_deinit(timer_periph);/*初始化参数 */timer_parameter_struct initpara;/* initialize TIMER init parameter struct */timer_struct_para_init(&initpara);/* 根据需要配置值 分频系数 (可以实现更低的timer频率) */initpara.prescaler 	= t_prescaler - 1;/* 1个周期的计数(period Max: 65535) Freq > 3662  */initpara.period		= t_period - 1;/* initialize TIMER counter */timer_init(timer_periph, &initpara);/* enable a TIMER */timer_enable(timer_periph);}void timer_channel_config(uint32_t timer_periph, uint16_t channel) {/* TIMER 通道输出配置 */timer_oc_parameter_struct ocpara;/* initialize TIMER channel output parameter struct */timer_channel_output_struct_para_init(&ocpara);ocpara.outputstate  = (uint16_t)TIMER_CCX_ENABLE;/* 配置输出参数 configure TIMER channel output function */timer_channel_output_config(timer_periph, channel, &ocpara);/* 配置通道输出输出比较模式 configure TIMER channel output compare mode */timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}// TIMER CH
#define LED5 TIMER3, TIMER_CH_0
#define LED6 TIMER3, TIMER_CH_1
#define LED7 TIMER3, TIMER_CH_2
#define LED8 TIMER3, TIMER_CH_3// PWM
#define	PRESCALER		1
#define	FREQ			  10000
#define PERIOD			(SystemCoreClock / FREQ)// LED5 TM3CH0 PD12
// LED6 TM3CH1 PD13
// LED7 TM3CH2 PD14
// LED8 TM3CH3 PD15
static void Timer_config() {// 定时器// GPIO ----------------------------------------timer_gpio_config(RCU_GPIOD, GPIOD, GPIO_PIN_12, GPIO_AF_2);timer_gpio_config(RCU_GPIOD, GPIOD, GPIO_PIN_13, GPIO_AF_2);timer_gpio_config(RCU_GPIOD, GPIOD, GPIO_PIN_14, GPIO_AF_2);timer_gpio_config(RCU_GPIOD, GPIOD, GPIO_PIN_15, GPIO_AF_2);// TIMER----------------------------------------/* 升级频率*/rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);timer_init_config(RCU_TIMER3, TIMER3, PRESCALER, PERIOD); // 与通道无关// TIMER channel-------------------------------timer_channel_config(LED5);timer_channel_config(LED6);timer_channel_config(LED7);timer_channel_config(LED8);}/*********************************************************** @brief 更新pwm占空比* @param timer_periph 定时器* @param channel 通道* @param duty  占空比[0, 100]* @return **********************************************************/
void PWM_update(uint32_t timer_periph, uint16_t channel, float duty) { // 0-100if(duty > 100) duty = 100;else if(duty < 0) duty = 0;//	pulse / PERIOD == duty / 100uint32_t pulse = PERIOD * duty / 100.0f - 1;// 计数值 65535timer_channel_output_pulse_value_config(timer_periph, channel, pulse);
}int main(void)
{systick_config();USART0_init();// 拉低总开关
//  GPIO_config();Timer_config();printf("Init Complete!\n");float duty = 0;int8_t dir = 1;while(1) {PWM_update(LED5, duty);PWM_update(LED6, duty);PWM_update(LED7, duty);PWM_update(LED8, duty);if (duty >= 100) {dir = -1;} else if (duty <= 0) {dir = 1;}duty += dir;printf("duty: %.2f \n", duty);delay_1ms(10);}
}

高级定时器通道输出

高级定时器只有TIMER0和TIMER7支持。由于扩展板上的高级定时器没有对应的LED,我们可以使用跳线的方式,将TIMER0CH0对应的PE8引脚,短接到PD8(LED1)上,通过观察LED1的亮灭,了解是否正确输出。

开发流程

  1. 添加Timer依赖
  2. 初始化PWM,包含多通道配置
  3. Break配置
  4. PWM占空比控制

通道配置

void timer0_channel_config(uint32_t timer_periph, uint16_t channel) {/* TIMER 通道输出配置 */timer_oc_parameter_struct ocpara;/* initialize TIMER channel output parameter struct */timer_channel_output_struct_para_init(&ocpara);// 禁用 OP极
//  ocpara.outputstate  = TIMER_CCX_ENABLE;// 启用 ON极ocpara.outputnstate = TIMER_CCXN_ENABLE;/* 配置输出参数 configure TIMER channel output function */timer_channel_output_config(timer_periph, channel, &ocpara);/* 配置通道输出输出比较模式 configure TIMER channel output compare mode */timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}#define LED1 TIMER0, TIMER_CH_0timer0_channel_config(LED1);
  • 特别强调,这里的引脚分为P和N类型,不同引脚要配置不同的输出状态

Break配置

// break 只针对高级定时器TIMER0 & TIMER7,需要打开互补保护电路/* TIMER通道互补保护电路 */
timer_break_parameter_struct breakpara;
/* 初始化TIMER break参数结构体 */
timer_break_struct_para_init(&breakpara);
/* break输入的极性 HIGH */
breakpara.breakpolarity   = TIMER_BREAK_POLARITY_HIGH;
/* 输出自动的启用 */
breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;
/* bread输入的启用*/
breakpara.breakstate     = TIMER_BREAK_ENABLE;
/* 配置TIMER7 break */
timer_break_config(TIMER0, &breakpara);
/* 启用TIMER7 break */
timer_break_enable(TIMER0);
  • breakstate:break状态开启
  • ouputostate:输出状态,自动开启
  • breakpolarity:输出极性,高电平

完整代码

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "USART0.h"void USART0_on_recv(uint8_t* data, uint32_t len) {printf("g_rx_buffer: %s g_rx_cnt:%d \n", data, len);
}static void GPIO_config() {rcu_periph_clock_enable(RCU_GPIOC);gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_bit_reset(GPIOC, GPIO_PIN_6);
}void timer_gpio_config(uint32_t gpio_rcu, uint32_t gpio_port, uint32_t gpio_pin, uint32_t gpio_af) {rcu_periph_clock_enable(gpio_rcu);/* 设置gpio模式 */gpio_mode_set(gpio_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_pin);gpio_output_options_set(gpio_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gpio_pin);gpio_af_set(gpio_port, gpio_af, gpio_pin);
}void timer_init_config(rcu_periph_enum rcu_periph, uint32_t timer_periph,uint16_t t_prescaler, uint32_t t_period) {rcu_periph_clock_enable(rcu_periph);timer_deinit(timer_periph);/*初始化参数 */timer_parameter_struct initpara;/* initialize TIMER init parameter struct */timer_struct_para_init(&initpara);/* 根据需要配置值 分频系数 (可以实现更低的timer频率) */initpara.prescaler 	= t_prescaler - 1;/* 1个周期的计数(period Max: 65535) Freq > 3662  */initpara.period		= t_period - 1;/* initialize TIMER counter */timer_init(timer_periph, &initpara);/* enable a TIMER */timer_enable(timer_periph);}void timer0_channel_config(uint32_t timer_periph, uint16_t channel) {/* TIMER 通道输出配置 */timer_oc_parameter_struct ocpara;/* initialize TIMER channel output parameter struct */timer_channel_output_struct_para_init(&ocpara);// 禁用 OP极
//  ocpara.outputstate  = TIMER_CCX_ENABLE;// 启用用 OP极ocpara.outputnstate = TIMER_CCXN_ENABLE;/* 配置输出参数 configure TIMER channel output function */timer_channel_output_config(timer_periph, channel, &ocpara);/* 配置通道输出输出比较模式 configure TIMER channel output compare mode */timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}// TIMER CH
#define LED1 TIMER0, TIMER_CH_0// PWM
#define	PRESCALER		1
#define	FREQ			  10000
#define PERIOD			(SystemCoreClock / FREQ)// LED1 TM0CH0_ON PE8
static void Timer_config() {// 定时器// GPIO ----------------------------------------timer_gpio_config(RCU_GPIOE, GPIOE, GPIO_PIN_8,  GPIO_AF_1);// TIMER----------------------------------------/* 升级频率*/rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);timer_init_config(RCU_TIMER0, TIMER0, PRESCALER, PERIOD); // 与通道无关// TIMER channel-------------------------------timer0_channel_config(LED1);// Break --------------------------------------------------// break 只针对高级定时器TIMER0 & TIMER7,打开互补保护电路/* TIMER通道互补保护电路 */timer_break_parameter_struct breakpara;/* 初始化TIMER break参数结构体 */timer_break_struct_para_init(&breakpara);/* break输入的极性 HIGH */breakpara.breakpolarity   = TIMER_BREAK_POLARITY_HIGH;/* 输出自动的启用 */breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;/* bread输入的启用*/breakpara.breakstate     = TIMER_BREAK_ENABLE;/* 配置TIMER7 break */timer_break_config(TIMER0, &breakpara);/* 启用TIMER7 break */timer_break_enable(TIMER0);
}/*********************************************************** @brief 更新pwm占空比* @param timer_periph 定时器* @param channel 通道* @param duty  占空比[0, 100]* @return**********************************************************/
void PWM_update(uint32_t timer_periph, uint16_t channel, float duty) { // 0-100if(duty > 100) duty = 100;else if(duty < 0) duty = 0;//	pulse / PERIOD == duty / 100uint32_t pulse = PERIOD * duty / 100.0f - 1;// 计数值 65535timer_channel_output_pulse_value_config(timer_periph, channel, pulse);
}int main(void)
{systick_config();USART0_init();// 拉低总开关GPIO_config();Timer_config();printf("Init Complete!\n");float duty = 0;int8_t dir = 1;while(1) {PWM_update(LED1, duty);if (duty >= 100) {dir = -1;} else if (duty <= 0) {dir = 1;}duty += dir;printf("duty: %.2f \n", duty);delay_1ms(10);}
}

总结

高级定时器只有TIMER0和TIMER7支持。由于扩展板上的高级定时器没有对应的LED,我们可以使用跳线的方式,将TIMER0CH0对应的PE8引脚,短接到PD8(LED1)上,通过观察LED1的亮灭,了解是否正确输出。

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

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

相关文章

2024年,计算机相关专业还值得选择吗?

2024年计算机相关专业依然非常值得选择&#xff0c;根据现有信息&#xff0c;计算机科学与技术、软件工程、信息安全、人工智能等专业在就业市场上保持着高度的热度和良好的前景。 就业率高&#xff1a;计算机专业毕业生的就业率持续保持高位&#xff0c;特别是在软件开发、系…

文案策划无门槛?文案策划职位入门全攻略

对于刚毕业的大学生来说&#xff0c;文案策划可以说是门槛最低的工作&#xff0c;仅次于前台。 绝大部分文案在进入广告公司之前不知道文案是干什么工作&#xff0c;早期会写点高考作文都不让写的诗歌就能入行。 没有文案专业&#xff0c;没有文案科班&#xff0c;最接近的三…

2024年山西水处理技术设备展览会11月8日召开

2024中国&#xff08;山西&#xff09;国际水务科技博览会 暨水处理技术设备与泵管阀展览会 时间&#xff1a;2024年11月8-10日 地点&#xff1a;山西潇河国际会展中心 推动城镇水务工作高质量发展&#xff0c;围绕解决水生态、水安全、水体黑臭、内涝积水等人民群众最关…

vivado HW_SIO_GT

描述 Xilinx的可定制LogiCORE™IP集成误码率测试仪&#xff08;IBERT&#xff09;核心 FPGA是为评估和监控千兆收发器&#xff08;GTs&#xff09;而设计的。IBERT core支持系统内串行I/O验证和调试&#xff0c;使您能够进行测量和优化 您的设计中的高速串行I/O链路。参考综合误…

[2024-06]-[大模型]-[Ollama] 0-相关命令

常用的ollama命令[持续更新中] ollama更新&#xff1a; curl https://ollama.ai/install.sh |sh带着flash attention启动&#xff1a; OLLAMA_FLASH_ATTENTION1 ollama serve停止ollama服务&#xff1a; sudo systemctl stop ollama note&#xff1a;目前遇到sudo systemctl …

No module named _sqlite3解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

微服务Day7学习-数据聚合、同步、补全

文章目录 数据聚合聚合分类 自动补全DSL实现Bucket聚合DSL实现Metrics聚合RestAPI实现聚合多条件聚合对接前端接口拼音分词器自定义分词器自动补全查询实现酒店搜索框自动补全 数据同步数据同步思路分析利用mq实现mysql与elasticsearch数据同步 集群介绍搭建ES集群 数据聚合 聚…

Electron qt开发教程

模块安装打包 npm install -g electron-forge electron-forge init my-project --templatevue npm start //进入目录启动 //打包成一个目录到out目录下&#xff0c;注意这种打包一般用于调试&#xff0c;并不是用于分发 npm run package //打出真正的分发包&#xff0c;放在o…

HarmonyOS未来五年的市场展望

一、引言 随着科技的不断进步和消费者对于智能化设备需求的日益增长&#xff0c;操作系统作为连接硬件与软件的核心平台&#xff0c;其重要性愈发凸显。HarmonyOS&#xff08;鸿蒙系统&#xff09;&#xff0c;作为华为自主研发的分布式操作系统&#xff0c;自诞生以来便备受瞩…

华安保险:核心系统分布式升级,提升保费规模处理能力2-3倍 | OceanBase企业案例

在3月20日的2024 OceanBase数据库城市行的活动中&#xff0c;安保险信息科技部总经理王在平发表了以“保险行业核心业务系统分布式架构实践”为主题的演讲。本文为该演讲的精彩回顾。 早在2019年&#xff0c;华安保险便开始与OceanBase接触&#xff0c;并着手进行数据库的升级…

使用本地大模型调用代码,根本就是一场骗局!

通过大模型调用其他工具到底可不可行&#xff1f;ChatGPT 或许能轻松搞定一切&#xff0c;但同样的需求落在本地大模型上&#xff0c;恐怕就要打个问号了。 法国开发工程师 Emilien Lancelot 尝试了多款号称具备工具调用功能的 agent 框架&#xff0c;来看看本地大模型到底能不…

qt-C++笔记之命令行生成项目pro文件(极简编译qt项目代码)

qt-C笔记之命令行生成项目pro文件(极简编译qt项目代码) 文章目录 qt-C笔记之命令行生成项目pro文件(极简编译qt项目代码)步骤 1&#xff1a;生成项目文件步骤 2&#xff1a;生成 Makefile 文件步骤 3&#xff1a;编译程序详细解释注意事项项目结构main.cpp 文件生成项目文件生成…

服饰进口清关流程及注意事项 | 国际贸易数字化平台 | 箱讯科技

随着全球化进程的不断推进&#xff0c;我国消费者对国外品牌服饰的需求日益增长&#xff0c;衣服进口业务也随之蓬勃发展。作为一名从事进口衣服行业的专业人士&#xff0c;掌握清关流程及注意事项至关重要。本文将为您详细解析衣服进口清关流程&#xff0c;并提供一些实用建议…

SpringSecurity入门(二)

8、获取用户认证信息 三种策略模式&#xff0c;调整通过修改VM options // 如果没有设置自定义的策略&#xff0c;就采用MODE_THREADLOCAL模式 public static final String MODE_THREADLOCAL "MODE_THREADLOCAL"; // 采用InheritableThreadLocal&#xff0c;它是Th…

图形和插图软件Canvas X Pro 20 Build 914

Canvas X Pro是一款功能强大、用途广泛的Windows软件,旨在处理技术图形和可视化,该程序结合了创建矢量和光栅图形的工具,这使其成为需要创建高质量技术插图和演示文稿的工程师、设计师、科学家和其他专业人士的理想选择。 Canvas X Pro的主要功能之一是支持处理大型和复杂的…

tcp协议的延迟应答(介绍+原则),拥塞控制(拥塞窗口,网络出现拥塞时,滑动窗口的大小如何确定,慢启动,阈值)

目录 延迟应答 引入 介绍 原则 拥塞控制 引入 网络出现拥塞 引入 介绍 介绍 拥塞窗口 介绍 决定滑动窗口的大小 慢启动 介绍 为什么要有慢启动 阈值 算法 总结 延迟应答 引入 发送方一次发送更多的数据,发送效率就越高 因为要写入网卡硬件的io速度很慢,尽量…

笔记 | 软件工程06-2:软件设计-软件体系结构设计

1 软件体系结构的概念 1.1 软件体系结构的设计元素 1.2 不同的抽象层次 1.3 软件体系结构的不同视图 1.3.1 软件体系结构的逻辑视图&#xff1a;包图 1.3.2 软件体系结构的逻辑视图&#xff1a;构件图 1.3.3 软件体系结构的开发视图 1.3.4 软件体系结构的部署视图 1.3.4.1 描述…

02眼电识别眼动--软件V1.0

对应视频链接点击直达 01项目点击下载&#xff0c;可直接运行&#xff08;含数据库&#xff09; 02眼电识别眼动--软件V1.0 对应视频链接点击直达构思结语其他以下是废话 构思 对于软件&#xff0c;主要就是接收数据、处理数据、储存和显示数据。 这是主要页面&#xff0c;…

【第2章】Vue快速上手

文章目录 前言一、第一个Vue程序二、Open in Browser插件1.安装2. 使用3. 界面 总结 前言 这里我们来实现我们的第一个程序。 一、第一个Vue程序 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&quo…

java版UWB高精度实时定位系统源码springboot+vue

UWB人员定位系统&#xff0c;实现人员的自动识别、位置定位、区域报警等功能。该系统能高效记录人员信息&#xff0c;出入信息及位置信息&#xff0c;并能灵活的查询及管理历史轨迹&#xff0c;可极大提高信息安全度&#xff0c;有效弥补了视频监控的不足。使人员管理实现信息化…