ARM32开发--PWM与通用定时器

news2024/12/23 3:25:22

知不足而奋进·望远山而前行


目录

文章目录

前言

学习目标

学习内容

PWM

pwm原理

需求

开发流程

初始化PWM

PWM占空比控制

main函数修改duty

输出通道

关心的内容

重要的关键词

周期

分频

占空比

总结


前言

在微控制器开发中,理解和掌握PWM(脉宽调制)技术以及与定时器的关系是至关重要的。PWM技术可以广泛应用于工业自动化、电机控制、LED调光等领域,通过改变信号的脉冲宽度来控制电路输出。本文将介绍PWM原理、开发流程,以及如何通过定时器实现PWM功能。通过学习本文,您将掌握通用定时器开发流程,理解周期、分频系数、周期计数、分频计数等概念,以及掌握分频计数、周期计数和占空比的计算策略。


学习目标

  1. 理解PWM和定时器的关系
  2. 掌握通用定时器开发流程
  3. 理解周期,分频系数,周期计数,分频计数。
  4. 掌握分频计数、周期计数和占空比的计算策略

学习内容

PWM

PWM全称是脉宽调制(Pulse Width Modulation),是一种通过改变信号的脉冲宽度来控制电路输出的技术。PWM技术在工业自动化、电机控制、LED调光等领域广泛应用。

PWM是一种将数字信号转换为模拟信号的技术,它通过改变信号的占空比来控制输出的电平。

在ARM32系列芯片中,PWM输出的频率和占空比可以由程序控制,因此可以用来控制各种电机、灯光和其他设备的亮度、速度等参。

在ARM32系列芯片中,PWM的调制是通过Timer来实现的。PWM与引脚相关,除了基本定时器以外,其他类型的Timer都可以作为PWM来进行使用。

pwm原理

CHxCV是输入捕获和输出比较寄存器

需求

PD14对应的LED4为例,我们做一个呼吸灯的效果。

我们采用TIMER3CH2进行实现:

开发流程

  1. 添加Timer依赖
  2. 初始化PWM
  3. PWM占空比控制
初始化PWM

#define	PRESCALER	10		    // [1, 65536]
#define	FREQ		1000		// 1000Hz

// 保证分母 (FREQ * PRESCALER) >= 2564
#define PERIOD 				SystemCoreClock / (FREQ * PRESCALER)

// TIMER3_CH2
static void Timer_config() {
    // 通用定时器

    // GPIO PD14 =================================================================
    rcu_periph_clock_enable(RCU_GPIOD);
    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_14);
    gpio_af_set(GPIOD, GPIO_AF_2, GPIO_PIN_14);

    // TIMER3C0 =================================================================
    // 初始化定时器配置
    rcu_periph_clock_enable(RCU_PERIPH);

    timer_deinit(TIMER_PERIPH);
    // 升级频率
    rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
    // 初始化参数
    timer_parameter_struct initpara;
    /* initialize TIMER init parameter struct */
    timer_struct_para_init(&initpara);
    /* 根据需要配置值 */
    initpara.prescaler = PRESCALER - 1;	// 分频系数 (可以实现更低的timer频率)
    // 1个周期的计数(period Max: 65535) Freq > 2564
    initpara.period		 = PERIOD - 1;
    /* initialize TIMER counter */
    timer_init(TIMER_PERIPH, &initpara);

    // TIMER通道输出配置
    timer_oc_parameter_struct ocpara;
    /* 初始化结构体参数 initialize TIMER channel output parameter struct */
    timer_channel_output_struct_para_init(&ocpara);
    /* 启用TM1 CH0的OP极(正极) */
    ocpara.outputstate  = (uint16_t)TIMER_CCX_ENABLE;
    /* 配置输出参数configure TIMER channel output function */
    timer_channel_output_config(TIMER_PERIPH, TIMER_CH, &ocpara);
    /* 配置通达输出比较模式 configure TIMER channel output compare mode */
    timer_channel_output_mode_config(TIMER_PERIPH, TIMER_CH, TIMER_OC_MODE_PWM0);
    /* 设置通道输出脉冲值 (修改占空比) configure TIMER channel output pulse value */
    timer_channel_output_pulse_value_config(TIMER_PERIPH, TIMER_CH, (PERIOD - 1) * 1.0f);

    /* enable a TIMER */
    timer_enable(TIMER_PERIPH);
}
PWM占空比控制
void PWM_update(float duty) { // 0 -> 100

    if(duty > 100) {
        duty = 100;
    } else if (duty < 0) {
        duty = 0;
    }
    // pulse / (PERIOD - 1) == duty / 100;
    uint32_t pulse = (PERIOD - 1) * duty / 100.0f;
    /* 设置通道输出脉冲值 (修改占空比) configure TIMER channel output pulse value */
    timer_channel_output_pulse_value_config(TIMER_PERIPH, TIMER_CH, pulse);

}
main函数修改duty
int main(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    systick_config();
    USART0_init();

    Timer_config();
    printf("Init Complete!\n");

    PWM_update(0);

    float duty = 0;
    int dir = 1;
    while(1) {

        // printf发送字符串
        // 0 -> (PERIOD - 1) -> 0 -> ....

        if(duty >= 100) {
            dir = -1;
        } else if(duty <= 0) {
            dir = 1;
        }

        duty += dir;

        PWM_update(duty);

        delay_1ms(10);
    }
}

输出通道

这里完整配置为多种:

void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara)
{
    /* initialize the channel output parameter struct member with the default value */
    ocpara->outputstate  = (uint16_t)TIMER_CCX_DISABLE;
    ocpara->outputnstate = TIMER_CCXN_DISABLE;
    ocpara->ocpolarity   = TIMER_OC_POLARITY_HIGH;
    ocpara->ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    ocpara->ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
}

我们具体的可以分为两类:

ocpara->outputstate  = (uint16_t)TIMER_CCX_DISABLE;
ocpara->ocpolarity   = TIMER_OC_POLARITY_HIGH;
ocpara->ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
ocpara->outputnstate = TIMER_CCXN_DISABLE;
ocpara->ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

特别观察API,带N的为反向,带P的为正向。赋值的结果常量也是需要注意是否带N。

P和N的配置主要出现在互补PWM中,如果当前的Timer不是高级定时器,那么就不具备互补的功能,那么我们一律认为他是P类型,也就是设置P才有用。

通过设置outputstate 的 ENABLE来控制输出通道的开启。

关心的内容

  • 哪个定时器
  • 哪个引脚输出pwm
  • 周期和分频系数

重要的关键词

周期

pwm中,一个周期就是一次高低电平的变化。

分频

将原来的活增加几倍时间干完。

占空比

1个周期内,高电平出现的比例。


总结

本文详细介绍了PWM技术以及与定时器的关系,通过示例代码演示了在ARM32系列芯片中如何实现PWM功能。首先,我们了解了PWM技术是如何将数字信号转换为模拟信号,并通过改变占空比来控制输出电平的。接着,我们学习了开发流程,包括如何初始化PWM以及如何控制PWM占空比。最后,我们通过具体的代码示例演示了如何在实际开发中应用PWM技术,实现呼吸灯效果。通过本文的学习,相信您已经掌握了有关PWM和定时器的基本知识和开发技巧,希望本文能够对您的学习和开发有所帮助。

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

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

相关文章

计算机网络:网络层 - IPv4地址

计算机网络&#xff1a;网络层 - IPv4地址 分类编址划分子网子网掩码 无分类编址 CIDRCIDR 地址块构造超网 在酒店中&#xff0c;每个房间都有门牌号码&#xff0c;服务员送餐时&#xff0c;就可以根据门牌号码来判断一份餐要送到那个房间。 在网络中也是如此&#xff0c;一份…

泵制造5G智能工厂工业物联数字孪生可视化,推进制造业数字化转型

泵制造5G智能工厂工业物联数字孪生可视化&#xff0c;推进制造业数字化转型。泵制造行业&#xff0c;作为工业领域的核心部分&#xff0c;更是急需通过技术创新实现生产流程的智能化和高效化。而5G智能工厂工业物联数字孪生可视化技术的出现&#xff0c;为泵制造业的数字化转型…

【全网最齐报错的解决方法!】运行mvn命令打包项目jar包报错?“Fatal error compiling: 无效的目标发行版: 19 ”, 让我来看看~

最近写实验&#xff0c;要打包项目&#xff0c;但是不管是在cmd运行“mvn clean package -Dmaven.test.skiptrue”命令&#xff0c;还是在idea上去操作&#xff0c;都出现了这样的一个错误&#xff1a; [EROR] Failed to exeoute goal org.apache.maven.plugins:maven-comnpile…

作业6.11

练习1&#xff1a;输入一个数&#xff0c;判断是否是完美数 完美数&#xff1a;正序和逆序的结果一致 练习2&#xff1a; * ** *** **** for(int i0;i<4;i){for(int y1;y<4-i;y){ printf(" ");}for(int j0;j<i;j){printf("*&quo…

zabbix-agent如何版本回退降低?

文章目录 1&#xff0c;查看zabbix-agent版本号2&#xff0c;查看zabbix-server的版本号3&#xff0c;卸载已有的zabbix-agent4&#xff0c;找到与zabbix-server匹配版本的zabbix-agent5&#xff0c;安装zabbix-agent 5.0.42版本6&#xff0c;查看已安装的zabbix-agent的版本号…

谁是最会写作文的AI“考生”?“阅卷老师”ChatGPT直呼惊艳!

文章推荐 粽叶飘香&#xff0c;端午安康&#xff01;AI视频送祝福啦~ AI日报&#xff5c;文生语音大模型国内外均有突破&#xff0c;Pika完成6亿新融资&#xff0c;视频大模型也不远了&#xff01; ⭐️搜索“可信AI进展“关注公众号&#xff0c;获取当日最新AI资讯 一年一…

Visual Studio 调试 Win32 出现 Task Manager / Explorer 无法打开,无法关机/重启

现象 Access is denied 无法关机 无法通过开始 -> 关机/重启 进行关机或者重启 无法打开新的应用 无法通过开始 -> 双击应用打开新的应用 已打开应用的使用不受影响 已经打开的应用可以正常操作 原因 杀毒软件&#xff1b;关掉杀毒软件就好了 问题查找过程 参考…

记一次华为2288H V5更换主板的辛酸

1、开机提示找不到设备&#xff0c;通过带外检查硬盘raid是否正常&#xff0c;如果正常就不是硬件问题&#xff0c;也不会是线没接好 2、网络不通&#xff0c;服务重启啥的都正常不会报错&#xff0c;就是ping不通网关&#xff0c;后来通过带外发现是网卡漂移了。 核对mac地址发…

项目:双人五子棋对战-对战模块(6)

完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com 当玩家进入到游戏房间后, 就要开始一局紧张而又刺激的五子棋对战了, 本文将就前端后端的落子与判断胜负的部分作详细讲解. 模块详细讲解 约定前后端交互的接口 首先是建立连接后, 服务器需要生成一些游戏的初始信息(可…

一五零、MAC 安装mysql可视化工具连接

mysql安装&#xff0c;按照网上教程一步步安装&#xff08;官网下载安装包->解压->完成安装&#xff09;&#xff0c;最后在「系统偏好设置」无法启动mysql。 原因&#xff1a;下载的版本是8.0最新版本&#xff0c;MAC上这种方法无法启动成功。 解决方法 换低版本的mys…

JDBC开发之四大核心API:DriverManager Connection Statement ResultSet

DriverManager 方法都是静态的 注册驱动 在Mysql5之后我们就不用注册驱动了 在jar包里已经写好了 读取文件 第二个方法 如果连接的是主机mysql并且端口是默认的3306 则可以简化书写 代码书写 import java.sql.Connection; import java.sql.DriverManager; import java.sql.S…

微软的这个按钮又双叒叕变了位置?有时候还不见了……

前言 小白最近打开Windows11系统的时间比较少&#xff0c;大部分时间都还是喜欢用MacBookPro码字。 之前小白写过一篇关于微软系统左下角的这个神奇按钮 Windows11更新之后&#xff0c;电脑左下角多出了一个奇怪的按钮&#xff08;点我跳转查看&#xff09; 没错&#xff0…

vivado HW_SIO_GT

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

webpack--压缩,代码的拆分,tree shinking

Terser 对代码进行压缩、丑化 const TerserPlugin require("terser-webpack-plugin");optimization: { minimize: true, //在开发环境下启用 CSS 优化minimizer: [new TerserPlugin({extractComments: false,terserOptions: {compress: {arguments: true,// 将函数…

CAPL如何发送一条SYN报文

在TCP协议中,发起连接的Client端首先会发送一条SYN报文,用来发起TCP连接请求。这条SYN报文的本质是TCP报文,只不过flags字段中SYN位置为1。 且SYN的序列号是随机的,所以可以用一个随机函数来生成随机数。而ack确认号是0。 TCP报文和UDP报文一样,需要设置源和目标端口号,…

最新小红薯引流无限曝光机,轻松高效精准曝光引流【引流软件+使用教程】

在现代数字营销的海洋中&#xff0c;精准引流已成为商家及创业者追求的圣杯。一种无需采集ID的新策略突破了传统营销的局限&#xff0c;提供了一条高效且安全的道路。这种方法旨在通过有针对性的关键词触达潜在的兴趣群体&#xff0c;实现品牌与用户之间的高效对接。 以关键词…

【CW32F030CxTx StartKit开发板】构建开发环境,测试LED和UART例程

目录 1、开发环境的构建 2、硬件连线 3. 例程测试 3.1 LED示例 3.2 UART printf示例 本文首发于21ic&#xff1a;https://bbs.21ic.com/forum.php?modviewthread&tid3382698&page1#pid14103102 感谢21ic和武汉芯源提供的测试机会。 此次测试的是CW32F030CxTx S…

新手grub 配置介绍

最近因为工作需要接触了grub&#xff0c;学到了一些相关知识&#xff0c;所以在这里写篇博客记录一下&#xff0c;有不对的部分欢迎指正。 目录 grub是什么&#xff1f; grub有哪些配置文件&#xff1f; 各配置文件区别 配置文件生成流程 配置文件有哪些内容&#xff1f;…

【Nature子刊】最争气国人友好“灌水刊”,中科院3区升2区,录用仅1个月,2天见刊!

本周投稿推荐 SSCI • 中科院2区&#xff0c;6.0-7.0&#xff08;录用友好&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&#xff09; SCI&EI • 4区生物医学类&#xff0c;0.5-1.0&#xff08;录用…

Android Studio | 小白如何运行别人的安卓项目

目录 Step1&#xff1a;正确地打开项目 Step2&#xff1a;AS 同步时报错 Step3&#xff1a;同步完成后启动 Step4&#xff1a;启动成功 说明&#xff1a;本文简称 Android Studio 为 AS Step1&#xff1a;正确地打开项目 重点&#xff1a;确认好项目的根目录是哪个目录&am…